blob: 38273dcbebad044d7fe9e7cc4e489eac88418b8b [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.
784 OwningExprResult RebuildDeclRefExpr(NamedDecl *ND, SourceLocation Loc) {
785 return getSema().BuildDeclarationNameExpr(Loc, ND,
786 /*FIXME:*/false,
787 /*SS=*/0,
788 /*FIXME:*/false);
789 }
Mike Stump11289f42009-09-09 15:08:12 +0000790
Douglas Gregora16548e2009-08-11 05:31:07 +0000791 /// \brief Build a new expression in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +0000792 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000793 /// By default, performs semantic analysis to build the new expression.
794 /// Subclasses may override this routine to provide different behavior.
795 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
796 SourceLocation RParen) {
797 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
798 }
799
Douglas Gregorad8a3362009-09-04 17:36:40 +0000800 /// \brief Build a new pseudo-destructor expression.
Mike Stump11289f42009-09-09 15:08:12 +0000801 ///
Douglas Gregorad8a3362009-09-04 17:36:40 +0000802 /// By default, performs semantic analysis to build the new expression.
803 /// Subclasses may override this routine to provide different behavior.
804 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
805 SourceLocation OperatorLoc,
806 bool isArrow,
807 SourceLocation DestroyedTypeLoc,
808 QualType DestroyedType,
809 NestedNameSpecifier *Qualifier,
810 SourceRange QualifierRange) {
811 CXXScopeSpec SS;
812 if (Qualifier) {
813 SS.setRange(QualifierRange);
814 SS.setScopeRep(Qualifier);
815 }
816
Mike Stump11289f42009-09-09 15:08:12 +0000817 DeclarationName Name
Douglas Gregorad8a3362009-09-04 17:36:40 +0000818 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
819 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump11289f42009-09-09 15:08:12 +0000820
821 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorad8a3362009-09-04 17:36:40 +0000822 OperatorLoc,
823 isArrow? tok::arrow : tok::period,
824 DestroyedTypeLoc,
825 Name,
826 Sema::DeclPtrTy::make((Decl *)0),
827 &SS);
Mike Stump11289f42009-09-09 15:08:12 +0000828 }
829
Douglas Gregora16548e2009-08-11 05:31:07 +0000830 /// \brief Build a new unary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000831 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000832 /// By default, performs semantic analysis to build the new expression.
833 /// Subclasses may override this routine to provide different behavior.
834 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
835 UnaryOperator::Opcode Opc,
836 ExprArg SubExpr) {
837 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
838 }
Mike Stump11289f42009-09-09 15:08:12 +0000839
Douglas Gregora16548e2009-08-11 05:31:07 +0000840 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump11289f42009-09-09 15:08:12 +0000841 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000842 /// By default, performs semantic analysis to build the new expression.
843 /// Subclasses may override this routine to provide different behavior.
844 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
845 bool isSizeOf, SourceRange R) {
846 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
847 }
848
Mike Stump11289f42009-09-09 15:08:12 +0000849 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000850 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000851 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000852 /// By default, performs semantic analysis to build the new expression.
853 /// Subclasses may override this routine to provide different behavior.
854 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
855 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000856 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000857 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
858 OpLoc, isSizeOf, R);
859 if (Result.isInvalid())
860 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000861
Douglas Gregora16548e2009-08-11 05:31:07 +0000862 SubExpr.release();
863 return move(Result);
864 }
Mike Stump11289f42009-09-09 15:08:12 +0000865
Douglas Gregora16548e2009-08-11 05:31:07 +0000866 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000867 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000868 /// By default, performs semantic analysis to build the new expression.
869 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000870 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000871 SourceLocation LBracketLoc,
872 ExprArg RHS,
873 SourceLocation RBracketLoc) {
874 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000875 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000876 RBracketLoc);
877 }
878
879 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000880 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000881 /// By default, performs semantic analysis to build the new expression.
882 /// Subclasses may override this routine to provide different behavior.
883 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
884 MultiExprArg Args,
885 SourceLocation *CommaLocs,
886 SourceLocation RParenLoc) {
887 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
888 move(Args), CommaLocs, RParenLoc);
889 }
890
891 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000892 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000893 /// By default, performs semantic analysis to build the new expression.
894 /// Subclasses may override this routine to provide different behavior.
895 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000896 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000897 NestedNameSpecifier *Qualifier,
898 SourceRange QualifierRange,
899 SourceLocation MemberLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000900 NamedDecl *Member) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000901 if (!Member->getDeclName()) {
902 // We have a reference to an unnamed field.
903 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000904
905 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000906 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
907 Member, MemberLoc,
908 cast<FieldDecl>(Member)->getType());
909 return getSema().Owned(ME);
910 }
Mike Stump11289f42009-09-09 15:08:12 +0000911
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000912 CXXScopeSpec SS;
913 if (Qualifier) {
914 SS.setRange(QualifierRange);
915 SS.setScopeRep(Qualifier);
916 }
917
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000918 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000919 isArrow? tok::arrow : tok::period,
920 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000921 Member->getDeclName(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000922 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
923 &SS);
Douglas Gregora16548e2009-08-11 05:31:07 +0000924 }
Mike Stump11289f42009-09-09 15:08:12 +0000925
Douglas Gregora16548e2009-08-11 05:31:07 +0000926 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000927 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000928 /// By default, performs semantic analysis to build the new expression.
929 /// Subclasses may override this routine to provide different behavior.
930 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
931 BinaryOperator::Opcode Opc,
932 ExprArg LHS, ExprArg RHS) {
933 OwningExprResult Result
Mike Stump11289f42009-09-09 15:08:12 +0000934 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +0000935 (Expr *)RHS.get());
936 if (Result.isInvalid())
937 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000938
Douglas Gregora16548e2009-08-11 05:31:07 +0000939 LHS.release();
940 RHS.release();
941 return move(Result);
942 }
943
944 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000945 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000946 /// By default, performs semantic analysis to build the new expression.
947 /// Subclasses may override this routine to provide different behavior.
948 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
949 SourceLocation QuestionLoc,
950 ExprArg LHS,
951 SourceLocation ColonLoc,
952 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +0000953 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +0000954 move(LHS), move(RHS));
955 }
956
957 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000958 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000959 /// By default, builds a new implicit cast without any semantic analysis.
960 /// Subclasses may override this routine to provide different behavior.
961 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
962 ExprArg SubExpr, bool isLvalue) {
963 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +0000964 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +0000965 (Expr *)SubExpr.release(),
966 isLvalue);
967 return getSema().Owned(ICE);
968 }
969
970 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000971 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000972 /// By default, performs semantic analysis to build the new expression.
973 /// Subclasses may override this routine to provide different behavior.
974 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
975 QualType ExplicitTy,
976 SourceLocation RParenLoc,
977 ExprArg SubExpr) {
978 return getSema().ActOnCastExpr(/*Scope=*/0,
979 LParenLoc,
980 ExplicitTy.getAsOpaquePtr(),
981 RParenLoc,
982 move(SubExpr));
983 }
Mike Stump11289f42009-09-09 15:08:12 +0000984
Douglas Gregora16548e2009-08-11 05:31:07 +0000985 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +0000986 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000987 /// By default, performs semantic analysis to build the new expression.
988 /// Subclasses may override this routine to provide different behavior.
989 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
990 QualType T,
991 SourceLocation RParenLoc,
992 ExprArg Init) {
993 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
994 RParenLoc, move(Init));
995 }
Mike Stump11289f42009-09-09 15:08:12 +0000996
Douglas Gregora16548e2009-08-11 05:31:07 +0000997 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000998 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000999 /// By default, performs semantic analysis to build the new expression.
1000 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001001 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001002 SourceLocation OpLoc,
1003 SourceLocation AccessorLoc,
1004 IdentifierInfo &Accessor) {
1005 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
1006 tok::period, AccessorLoc,
1007 Accessor,
1008 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1009 }
Mike Stump11289f42009-09-09 15:08:12 +00001010
Douglas Gregora16548e2009-08-11 05:31:07 +00001011 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001012 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001013 /// By default, performs semantic analysis to build the new expression.
1014 /// Subclasses may override this routine to provide different behavior.
1015 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1016 MultiExprArg Inits,
1017 SourceLocation RBraceLoc) {
1018 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1019 }
Mike Stump11289f42009-09-09 15:08:12 +00001020
Douglas Gregora16548e2009-08-11 05:31:07 +00001021 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001022 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001023 /// By default, performs semantic analysis to build the new expression.
1024 /// Subclasses may override this routine to provide different behavior.
1025 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1026 MultiExprArg ArrayExprs,
1027 SourceLocation EqualOrColonLoc,
1028 bool GNUSyntax,
1029 ExprArg Init) {
1030 OwningExprResult Result
1031 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1032 move(Init));
1033 if (Result.isInvalid())
1034 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001035
Douglas Gregora16548e2009-08-11 05:31:07 +00001036 ArrayExprs.release();
1037 return move(Result);
1038 }
Mike Stump11289f42009-09-09 15:08:12 +00001039
Douglas Gregora16548e2009-08-11 05:31:07 +00001040 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001041 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001042 /// By default, builds the implicit value initialization without performing
1043 /// any semantic analysis. Subclasses may override this routine to provide
1044 /// different behavior.
1045 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1046 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1047 }
Mike Stump11289f42009-09-09 15:08:12 +00001048
Douglas Gregora16548e2009-08-11 05:31:07 +00001049 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001050 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001051 /// By default, performs semantic analysis to build the new expression.
1052 /// Subclasses may override this routine to provide different behavior.
1053 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1054 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001055 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001056 RParenLoc);
1057 }
1058
1059 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001060 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001061 /// By default, performs semantic analysis to build the new expression.
1062 /// Subclasses may override this routine to provide different behavior.
1063 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1064 MultiExprArg SubExprs,
1065 SourceLocation RParenLoc) {
1066 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1067 }
Mike Stump11289f42009-09-09 15:08:12 +00001068
Douglas Gregora16548e2009-08-11 05:31:07 +00001069 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001070 ///
1071 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001072 /// rather than attempting to map the label statement itself.
1073 /// Subclasses may override this routine to provide different behavior.
1074 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1075 SourceLocation LabelLoc,
1076 LabelStmt *Label) {
1077 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1078 }
Mike Stump11289f42009-09-09 15:08:12 +00001079
Douglas Gregora16548e2009-08-11 05:31:07 +00001080 /// \brief Build a new GNU statement expression.
Mike Stump11289f42009-09-09 15:08:12 +00001081 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001082 /// By default, performs semantic analysis to build the new expression.
1083 /// Subclasses may override this routine to provide different behavior.
1084 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1085 StmtArg SubStmt,
1086 SourceLocation RParenLoc) {
1087 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1088 }
Mike Stump11289f42009-09-09 15:08:12 +00001089
Douglas Gregora16548e2009-08-11 05:31:07 +00001090 /// \brief Build a new __builtin_types_compatible_p expression.
1091 ///
1092 /// By default, performs semantic analysis to build the new expression.
1093 /// Subclasses may override this routine to provide different behavior.
1094 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1095 QualType T1, QualType T2,
1096 SourceLocation RParenLoc) {
1097 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1098 T1.getAsOpaquePtr(),
1099 T2.getAsOpaquePtr(),
1100 RParenLoc);
1101 }
Mike Stump11289f42009-09-09 15:08:12 +00001102
Douglas Gregora16548e2009-08-11 05:31:07 +00001103 /// \brief Build a new __builtin_choose_expr expression.
1104 ///
1105 /// By default, performs semantic analysis to build the new expression.
1106 /// Subclasses may override this routine to provide different behavior.
1107 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1108 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1109 SourceLocation RParenLoc) {
1110 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1111 move(Cond), move(LHS), move(RHS),
1112 RParenLoc);
1113 }
Mike Stump11289f42009-09-09 15:08:12 +00001114
Douglas Gregora16548e2009-08-11 05:31:07 +00001115 /// \brief Build a new overloaded operator call expression.
1116 ///
1117 /// By default, performs semantic analysis to build the new expression.
1118 /// The semantic analysis provides the behavior of template instantiation,
1119 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001120 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001121 /// argument-dependent lookup, etc. Subclasses may override this routine to
1122 /// provide different behavior.
1123 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1124 SourceLocation OpLoc,
1125 ExprArg Callee,
1126 ExprArg First,
1127 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001128
1129 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001130 /// reinterpret_cast.
1131 ///
1132 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001133 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001134 /// Subclasses may override this routine to provide different behavior.
1135 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1136 Stmt::StmtClass Class,
1137 SourceLocation LAngleLoc,
1138 QualType T,
1139 SourceLocation RAngleLoc,
1140 SourceLocation LParenLoc,
1141 ExprArg SubExpr,
1142 SourceLocation RParenLoc) {
1143 switch (Class) {
1144 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001145 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1146 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001147 move(SubExpr), RParenLoc);
1148
1149 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001150 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1151 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001152 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001153
Douglas Gregora16548e2009-08-11 05:31:07 +00001154 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001155 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1156 RAngleLoc, LParenLoc,
1157 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001158 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001159
Douglas Gregora16548e2009-08-11 05:31:07 +00001160 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001161 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1162 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001163 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001164
Douglas Gregora16548e2009-08-11 05:31:07 +00001165 default:
1166 assert(false && "Invalid C++ named cast");
1167 break;
1168 }
Mike Stump11289f42009-09-09 15:08:12 +00001169
Douglas Gregora16548e2009-08-11 05:31:07 +00001170 return getSema().ExprError();
1171 }
Mike Stump11289f42009-09-09 15:08:12 +00001172
Douglas Gregora16548e2009-08-11 05:31:07 +00001173 /// \brief Build a new C++ static_cast expression.
1174 ///
1175 /// By default, performs semantic analysis to build the new expression.
1176 /// Subclasses may override this routine to provide different behavior.
1177 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1178 SourceLocation LAngleLoc,
1179 QualType T,
1180 SourceLocation RAngleLoc,
1181 SourceLocation LParenLoc,
1182 ExprArg SubExpr,
1183 SourceLocation RParenLoc) {
1184 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001185 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001186 LParenLoc, move(SubExpr), RParenLoc);
1187 }
1188
1189 /// \brief Build a new C++ dynamic_cast expression.
1190 ///
1191 /// By default, performs semantic analysis to build the new expression.
1192 /// Subclasses may override this routine to provide different behavior.
1193 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1194 SourceLocation LAngleLoc,
1195 QualType T,
1196 SourceLocation RAngleLoc,
1197 SourceLocation LParenLoc,
1198 ExprArg SubExpr,
1199 SourceLocation RParenLoc) {
1200 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001201 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001202 LParenLoc, move(SubExpr), RParenLoc);
1203 }
1204
1205 /// \brief Build a new C++ reinterpret_cast expression.
1206 ///
1207 /// By default, performs semantic analysis to build the new expression.
1208 /// Subclasses may override this routine to provide different behavior.
1209 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1210 SourceLocation LAngleLoc,
1211 QualType T,
1212 SourceLocation RAngleLoc,
1213 SourceLocation LParenLoc,
1214 ExprArg SubExpr,
1215 SourceLocation RParenLoc) {
1216 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1217 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1218 LParenLoc, move(SubExpr), RParenLoc);
1219 }
1220
1221 /// \brief Build a new C++ const_cast expression.
1222 ///
1223 /// By default, performs semantic analysis to build the new expression.
1224 /// Subclasses may override this routine to provide different behavior.
1225 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1226 SourceLocation LAngleLoc,
1227 QualType T,
1228 SourceLocation RAngleLoc,
1229 SourceLocation LParenLoc,
1230 ExprArg SubExpr,
1231 SourceLocation RParenLoc) {
1232 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001233 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001234 LParenLoc, move(SubExpr), RParenLoc);
1235 }
Mike Stump11289f42009-09-09 15:08:12 +00001236
Douglas Gregora16548e2009-08-11 05:31:07 +00001237 /// \brief Build a new C++ functional-style cast expression.
1238 ///
1239 /// By default, performs semantic analysis to build the new expression.
1240 /// Subclasses may override this routine to provide different behavior.
1241 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1242 QualType T,
1243 SourceLocation LParenLoc,
1244 ExprArg SubExpr,
1245 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001246 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001247 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1248 T.getAsOpaquePtr(),
1249 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001250 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001251 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001252 RParenLoc);
1253 }
Mike Stump11289f42009-09-09 15:08:12 +00001254
Douglas Gregora16548e2009-08-11 05:31:07 +00001255 /// \brief Build a new C++ typeid(type) expression.
1256 ///
1257 /// By default, performs semantic analysis to build the new expression.
1258 /// Subclasses may override this routine to provide different behavior.
1259 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1260 SourceLocation LParenLoc,
1261 QualType T,
1262 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001263 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001264 T.getAsOpaquePtr(), RParenLoc);
1265 }
Mike Stump11289f42009-09-09 15:08:12 +00001266
Douglas Gregora16548e2009-08-11 05:31:07 +00001267 /// \brief Build a new C++ typeid(expr) expression.
1268 ///
1269 /// By default, performs semantic analysis to build the new expression.
1270 /// Subclasses may override this routine to provide different behavior.
1271 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1272 SourceLocation LParenLoc,
1273 ExprArg Operand,
1274 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001275 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001276 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1277 RParenLoc);
1278 if (Result.isInvalid())
1279 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001280
Douglas Gregora16548e2009-08-11 05:31:07 +00001281 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1282 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001283 }
1284
Douglas Gregora16548e2009-08-11 05:31:07 +00001285 /// \brief Build a new C++ "this" expression.
1286 ///
1287 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001288 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001289 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001290 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001291 QualType ThisType) {
1292 return getSema().Owned(
1293 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1294 }
1295
1296 /// \brief Build a new C++ throw expression.
1297 ///
1298 /// By default, performs semantic analysis to build the new expression.
1299 /// Subclasses may override this routine to provide different behavior.
1300 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1301 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1302 }
1303
1304 /// \brief Build a new C++ default-argument expression.
1305 ///
1306 /// By default, builds a new default-argument expression, which does not
1307 /// require any semantic analysis. Subclasses may override this routine to
1308 /// provide different behavior.
1309 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001310 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001311 }
1312
1313 /// \brief Build a new C++ zero-initialization expression.
1314 ///
1315 /// By default, performs semantic analysis to build the new expression.
1316 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001317 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001318 SourceLocation LParenLoc,
1319 QualType T,
1320 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001321 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1322 T.getAsOpaquePtr(), LParenLoc,
1323 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001324 0, RParenLoc);
1325 }
Mike Stump11289f42009-09-09 15:08:12 +00001326
Douglas Gregora16548e2009-08-11 05:31:07 +00001327 /// \brief Build a new C++ conditional declaration expression.
1328 ///
1329 /// By default, performs semantic analysis to build the new expression.
1330 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001331 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001332 SourceLocation EqLoc,
1333 VarDecl *Var) {
1334 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1335 EqLoc,
1336 Var));
1337 }
Mike Stump11289f42009-09-09 15:08:12 +00001338
Douglas Gregora16548e2009-08-11 05:31:07 +00001339 /// \brief Build a new C++ "new" expression.
1340 ///
1341 /// By default, performs semantic analysis to build the new expression.
1342 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001343 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001344 bool UseGlobal,
1345 SourceLocation PlacementLParen,
1346 MultiExprArg PlacementArgs,
1347 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001348 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001349 QualType AllocType,
1350 SourceLocation TypeLoc,
1351 SourceRange TypeRange,
1352 ExprArg ArraySize,
1353 SourceLocation ConstructorLParen,
1354 MultiExprArg ConstructorArgs,
1355 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001356 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001357 PlacementLParen,
1358 move(PlacementArgs),
1359 PlacementRParen,
1360 ParenTypeId,
1361 AllocType,
1362 TypeLoc,
1363 TypeRange,
1364 move(ArraySize),
1365 ConstructorLParen,
1366 move(ConstructorArgs),
1367 ConstructorRParen);
1368 }
Mike Stump11289f42009-09-09 15:08:12 +00001369
Douglas Gregora16548e2009-08-11 05:31:07 +00001370 /// \brief Build a new C++ "delete" expression.
1371 ///
1372 /// By default, performs semantic analysis to build the new expression.
1373 /// Subclasses may override this routine to provide different behavior.
1374 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1375 bool IsGlobalDelete,
1376 bool IsArrayForm,
1377 ExprArg Operand) {
1378 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1379 move(Operand));
1380 }
Mike Stump11289f42009-09-09 15:08:12 +00001381
Douglas Gregora16548e2009-08-11 05:31:07 +00001382 /// \brief Build a new unary type trait expression.
1383 ///
1384 /// By default, performs semantic analysis to build the new expression.
1385 /// Subclasses may override this routine to provide different behavior.
1386 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1387 SourceLocation StartLoc,
1388 SourceLocation LParenLoc,
1389 QualType T,
1390 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001391 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001392 T.getAsOpaquePtr(), RParenLoc);
1393 }
1394
1395 /// \brief Build a new qualified declaration reference expression.
1396 ///
1397 /// By default, performs semantic analysis to build the new expression.
1398 /// Subclasses may override this routine to provide different behavior.
1399 OwningExprResult RebuildQualifiedDeclRefExpr(NestedNameSpecifier *NNS,
1400 SourceRange QualifierRange,
1401 NamedDecl *ND,
1402 SourceLocation Location,
1403 bool IsAddressOfOperand) {
1404 CXXScopeSpec SS;
1405 SS.setRange(QualifierRange);
1406 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001407 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001408 Location,
1409 ND->getDeclName(),
1410 /*Trailing lparen=*/false,
1411 &SS,
1412 IsAddressOfOperand);
1413 }
1414
Mike Stump11289f42009-09-09 15:08:12 +00001415 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001416 /// expression.
1417 ///
1418 /// By default, performs semantic analysis to build the new expression.
1419 /// Subclasses may override this routine to provide different behavior.
1420 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1421 SourceRange QualifierRange,
1422 DeclarationName Name,
1423 SourceLocation Location,
1424 bool IsAddressOfOperand) {
1425 CXXScopeSpec SS;
1426 SS.setRange(QualifierRange);
1427 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001428 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001429 Location,
1430 Name,
1431 /*Trailing lparen=*/false,
1432 &SS,
1433 IsAddressOfOperand);
1434 }
1435
1436 /// \brief Build a new template-id expression.
1437 ///
1438 /// By default, performs semantic analysis to build the new expression.
1439 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001440 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1441 SourceRange QualifierRange,
1442 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001443 SourceLocation TemplateLoc,
1444 SourceLocation LAngleLoc,
1445 TemplateArgument *TemplateArgs,
1446 unsigned NumTemplateArgs,
1447 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001448 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1449 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001450 LAngleLoc,
1451 TemplateArgs, NumTemplateArgs,
1452 RAngleLoc);
1453 }
1454
1455 /// \brief Build a new object-construction expression.
1456 ///
1457 /// By default, performs semantic analysis to build the new expression.
1458 /// Subclasses may override this routine to provide different behavior.
1459 OwningExprResult RebuildCXXConstructExpr(QualType T,
1460 CXXConstructorDecl *Constructor,
1461 bool IsElidable,
1462 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001463 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1464 SourceLocation(),
1465 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001466 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001467 }
1468
1469 /// \brief Build a new object-construction expression.
1470 ///
1471 /// By default, performs semantic analysis to build the new expression.
1472 /// Subclasses may override this routine to provide different behavior.
1473 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1474 QualType T,
1475 SourceLocation LParenLoc,
1476 MultiExprArg Args,
1477 SourceLocation *Commas,
1478 SourceLocation RParenLoc) {
1479 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1480 T.getAsOpaquePtr(),
1481 LParenLoc,
1482 move(Args),
1483 Commas,
1484 RParenLoc);
1485 }
1486
1487 /// \brief Build a new object-construction expression.
1488 ///
1489 /// By default, performs semantic analysis to build the new expression.
1490 /// Subclasses may override this routine to provide different behavior.
1491 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1492 QualType T,
1493 SourceLocation LParenLoc,
1494 MultiExprArg Args,
1495 SourceLocation *Commas,
1496 SourceLocation RParenLoc) {
1497 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1498 /*FIXME*/LParenLoc),
1499 T.getAsOpaquePtr(),
1500 LParenLoc,
1501 move(Args),
1502 Commas,
1503 RParenLoc);
1504 }
Mike Stump11289f42009-09-09 15:08:12 +00001505
Douglas Gregora16548e2009-08-11 05:31:07 +00001506 /// \brief Build a new member reference expression.
1507 ///
1508 /// By default, performs semantic analysis to build the new expression.
1509 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001510 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001511 bool IsArrow,
1512 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001513 NestedNameSpecifier *Qualifier,
1514 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001515 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001516 SourceLocation MemberLoc,
1517 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001518 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001519 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001520
Douglas Gregora16548e2009-08-11 05:31:07 +00001521 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001522 SS.setRange(QualifierRange);
1523 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001524
Douglas Gregor308047d2009-09-09 00:23:06 +00001525 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001526 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001527 MemberLoc,
1528 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001529 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001530 &SS,
1531 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001532 }
1533
Douglas Gregor308047d2009-09-09 00:23:06 +00001534 /// \brief Build a new member reference expression with explicit template
1535 /// arguments.
1536 ///
1537 /// By default, performs semantic analysis to build the new expression.
1538 /// Subclasses may override this routine to provide different behavior.
1539 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1540 bool IsArrow,
1541 SourceLocation OperatorLoc,
1542 NestedNameSpecifier *Qualifier,
1543 SourceRange QualifierRange,
1544 TemplateName Template,
1545 SourceLocation TemplateNameLoc,
1546 NamedDecl *FirstQualifierInScope,
1547 SourceLocation LAngleLoc,
1548 const TemplateArgument *TemplateArgs,
1549 unsigned NumTemplateArgs,
1550 SourceLocation RAngleLoc) {
1551 OwningExprResult Base = move(BaseE);
1552 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001553
Douglas Gregor308047d2009-09-09 00:23:06 +00001554 CXXScopeSpec SS;
1555 SS.setRange(QualifierRange);
1556 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001557
Douglas Gregor308047d2009-09-09 00:23:06 +00001558 // FIXME: We're going to end up looking up the template based on its name,
1559 // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
1560 DeclarationName Name;
1561 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1562 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001563 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001564 = Template.getAsOverloadedFunctionDecl())
1565 Name = Ovl->getDeclName();
1566 else
1567 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump11289f42009-09-09 15:08:12 +00001568
1569 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001570 OperatorLoc, OpKind,
1571 TemplateNameLoc, Name, true,
1572 LAngleLoc, TemplateArgs,
1573 NumTemplateArgs, RAngleLoc,
1574 Sema::DeclPtrTy(), &SS);
1575 }
Mike Stump11289f42009-09-09 15:08:12 +00001576
Douglas Gregora16548e2009-08-11 05:31:07 +00001577 /// \brief Build a new Objective-C @encode expression.
1578 ///
1579 /// By default, performs semantic analysis to build the new expression.
1580 /// Subclasses may override this routine to provide different behavior.
1581 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1582 QualType T,
1583 SourceLocation RParenLoc) {
1584 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1585 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001586 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001587
1588 /// \brief Build a new Objective-C protocol expression.
1589 ///
1590 /// By default, performs semantic analysis to build the new expression.
1591 /// Subclasses may override this routine to provide different behavior.
1592 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1593 SourceLocation AtLoc,
1594 SourceLocation ProtoLoc,
1595 SourceLocation LParenLoc,
1596 SourceLocation RParenLoc) {
1597 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1598 Protocol->getIdentifier(),
1599 AtLoc,
1600 ProtoLoc,
1601 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001602 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001603 }
Mike Stump11289f42009-09-09 15:08:12 +00001604
Douglas Gregora16548e2009-08-11 05:31:07 +00001605 /// \brief Build a new shuffle vector expression.
1606 ///
1607 /// By default, performs semantic analysis to build the new expression.
1608 /// Subclasses may override this routine to provide different behavior.
1609 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1610 MultiExprArg SubExprs,
1611 SourceLocation RParenLoc) {
1612 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001613 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001614 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1615 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1616 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1617 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001618
Douglas Gregora16548e2009-08-11 05:31:07 +00001619 // Build a reference to the __builtin_shufflevector builtin
1620 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001621 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001622 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1623 BuiltinLoc, false, false);
1624 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001625
1626 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001627 unsigned NumSubExprs = SubExprs.size();
1628 Expr **Subs = (Expr **)SubExprs.release();
1629 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1630 Subs, NumSubExprs,
1631 Builtin->getResultType(),
1632 RParenLoc);
1633 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001634
Douglas Gregora16548e2009-08-11 05:31:07 +00001635 // Type-check the __builtin_shufflevector expression.
1636 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1637 if (Result.isInvalid())
1638 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001639
Douglas Gregora16548e2009-08-11 05:31:07 +00001640 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001641 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001642 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001643};
Douglas Gregora16548e2009-08-11 05:31:07 +00001644
Douglas Gregorebe10102009-08-20 07:17:43 +00001645template<typename Derived>
1646Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1647 if (!S)
1648 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001649
Douglas Gregorebe10102009-08-20 07:17:43 +00001650 switch (S->getStmtClass()) {
1651 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001652
Douglas Gregorebe10102009-08-20 07:17:43 +00001653 // Transform individual statement nodes
1654#define STMT(Node, Parent) \
1655 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1656#define EXPR(Node, Parent)
1657#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001658
Douglas Gregorebe10102009-08-20 07:17:43 +00001659 // Transform expressions by calling TransformExpr.
1660#define STMT(Node, Parent)
1661#define EXPR(Node, Parent) case Stmt::Node##Class:
1662#include "clang/AST/StmtNodes.def"
1663 {
1664 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1665 if (E.isInvalid())
1666 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001667
Douglas Gregorebe10102009-08-20 07:17:43 +00001668 return getSema().Owned(E.takeAs<Stmt>());
1669 }
Mike Stump11289f42009-09-09 15:08:12 +00001670 }
1671
Douglas Gregorebe10102009-08-20 07:17:43 +00001672 return SemaRef.Owned(S->Retain());
1673}
Mike Stump11289f42009-09-09 15:08:12 +00001674
1675
Douglas Gregore922c772009-08-04 22:27:00 +00001676template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001677Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1678 bool isAddressOfOperand) {
1679 if (!E)
1680 return SemaRef.Owned(E);
1681
1682 switch (E->getStmtClass()) {
1683 case Stmt::NoStmtClass: break;
1684#define STMT(Node, Parent) case Stmt::Node##Class: break;
1685#define EXPR(Node, Parent) \
1686 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1687#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001688 }
1689
Douglas Gregora16548e2009-08-11 05:31:07 +00001690 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001691}
1692
1693template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001694NestedNameSpecifier *
1695TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001696 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001697 QualType ObjectType,
1698 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001699 if (!NNS)
1700 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001701
Douglas Gregorebe10102009-08-20 07:17:43 +00001702 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001703 NestedNameSpecifier *Prefix = NNS->getPrefix();
1704 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001705 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001706 ObjectType,
1707 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001708 if (!Prefix)
1709 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001710
1711 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001712 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001713 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001714 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001715 }
Mike Stump11289f42009-09-09 15:08:12 +00001716
Douglas Gregor1135c352009-08-06 05:28:30 +00001717 switch (NNS->getKind()) {
1718 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001719 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001720 "Identifier nested-name-specifier with no prefix or object type");
1721 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1722 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001723 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001724
1725 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001726 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001727 ObjectType,
1728 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001729
Douglas Gregor1135c352009-08-06 05:28:30 +00001730 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001731 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001732 = cast_or_null<NamespaceDecl>(
1733 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001734 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001735 Prefix == NNS->getPrefix() &&
1736 NS == NNS->getAsNamespace())
1737 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001738
Douglas Gregor1135c352009-08-06 05:28:30 +00001739 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1740 }
Mike Stump11289f42009-09-09 15:08:12 +00001741
Douglas Gregor1135c352009-08-06 05:28:30 +00001742 case NestedNameSpecifier::Global:
1743 // There is no meaningful transformation that one could perform on the
1744 // global scope.
1745 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001746
Douglas Gregor1135c352009-08-06 05:28:30 +00001747 case NestedNameSpecifier::TypeSpecWithTemplate:
1748 case NestedNameSpecifier::TypeSpec: {
1749 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001750 if (T.isNull())
1751 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001752
Douglas Gregor1135c352009-08-06 05:28:30 +00001753 if (!getDerived().AlwaysRebuild() &&
1754 Prefix == NNS->getPrefix() &&
1755 T == QualType(NNS->getAsType(), 0))
1756 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001757
1758 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1759 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001760 T);
1761 }
1762 }
Mike Stump11289f42009-09-09 15:08:12 +00001763
Douglas Gregor1135c352009-08-06 05:28:30 +00001764 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001765 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001766}
1767
1768template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001769DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001770TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001771 SourceLocation Loc,
1772 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001773 if (!Name)
1774 return Name;
1775
1776 switch (Name.getNameKind()) {
1777 case DeclarationName::Identifier:
1778 case DeclarationName::ObjCZeroArgSelector:
1779 case DeclarationName::ObjCOneArgSelector:
1780 case DeclarationName::ObjCMultiArgSelector:
1781 case DeclarationName::CXXOperatorName:
1782 case DeclarationName::CXXUsingDirective:
1783 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001784
Douglas Gregorf816bd72009-09-03 22:13:48 +00001785 case DeclarationName::CXXConstructorName:
1786 case DeclarationName::CXXDestructorName:
1787 case DeclarationName::CXXConversionFunctionName: {
1788 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001789 QualType T;
1790 if (!ObjectType.isNull() &&
1791 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1792 TemplateSpecializationType *SpecType
1793 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1794 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1795 } else
1796 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001797 if (T.isNull())
1798 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001799
Douglas Gregorf816bd72009-09-03 22:13:48 +00001800 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001801 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001802 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001803 }
Mike Stump11289f42009-09-09 15:08:12 +00001804 }
1805
Douglas Gregorf816bd72009-09-03 22:13:48 +00001806 return DeclarationName();
1807}
1808
1809template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001810TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001811TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1812 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001813 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001814 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001815 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1816 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1817 if (!NNS)
1818 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001819
Douglas Gregor71dc5092009-08-06 06:41:21 +00001820 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001821 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001822 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1823 if (!TransTemplate)
1824 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001825
Douglas Gregor71dc5092009-08-06 06:41:21 +00001826 if (!getDerived().AlwaysRebuild() &&
1827 NNS == QTN->getQualifier() &&
1828 TransTemplate == Template)
1829 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001830
Douglas Gregor71dc5092009-08-06 06:41:21 +00001831 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1832 TransTemplate);
1833 }
Mike Stump11289f42009-09-09 15:08:12 +00001834
Douglas Gregor71dc5092009-08-06 06:41:21 +00001835 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1836 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001837 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001838 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1839 if (!TransOvl)
1840 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001841
Douglas Gregor71dc5092009-08-06 06:41:21 +00001842 if (!getDerived().AlwaysRebuild() &&
1843 NNS == QTN->getQualifier() &&
1844 TransOvl == Ovl)
1845 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001846
Douglas Gregor71dc5092009-08-06 06:41:21 +00001847 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1848 TransOvl);
1849 }
Mike Stump11289f42009-09-09 15:08:12 +00001850
Douglas Gregor71dc5092009-08-06 06:41:21 +00001851 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001852 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001853 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1854 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001855 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001856 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001857
Douglas Gregor71dc5092009-08-06 06:41:21 +00001858 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001859 NNS == DTN->getQualifier() &&
1860 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001861 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001862
Douglas Gregor308047d2009-09-09 00:23:06 +00001863 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001864 }
Mike Stump11289f42009-09-09 15:08:12 +00001865
Douglas Gregor71dc5092009-08-06 06:41:21 +00001866 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001867 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001868 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1869 if (!TransTemplate)
1870 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001871
Douglas Gregor71dc5092009-08-06 06:41:21 +00001872 if (!getDerived().AlwaysRebuild() &&
1873 TransTemplate == Template)
1874 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001875
Douglas Gregor71dc5092009-08-06 06:41:21 +00001876 return TemplateName(TransTemplate);
1877 }
Mike Stump11289f42009-09-09 15:08:12 +00001878
Douglas Gregor71dc5092009-08-06 06:41:21 +00001879 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1880 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001881 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001882 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1883 if (!TransOvl)
1884 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001885
Douglas Gregor71dc5092009-08-06 06:41:21 +00001886 if (!getDerived().AlwaysRebuild() &&
1887 TransOvl == Ovl)
1888 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001889
Douglas Gregor71dc5092009-08-06 06:41:21 +00001890 return TemplateName(TransOvl);
1891}
1892
1893template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001894TemplateArgument
Douglas Gregore922c772009-08-04 22:27:00 +00001895TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
1896 switch (Arg.getKind()) {
1897 case TemplateArgument::Null:
1898 case TemplateArgument::Integral:
1899 return Arg;
Mike Stump11289f42009-09-09 15:08:12 +00001900
Douglas Gregore922c772009-08-04 22:27:00 +00001901 case TemplateArgument::Type: {
1902 QualType T = getDerived().TransformType(Arg.getAsType());
1903 if (T.isNull())
1904 return TemplateArgument();
1905 return TemplateArgument(Arg.getLocation(), T);
1906 }
Mike Stump11289f42009-09-09 15:08:12 +00001907
Douglas Gregore922c772009-08-04 22:27:00 +00001908 case TemplateArgument::Declaration: {
1909 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
1910 if (!D)
1911 return TemplateArgument();
1912 return TemplateArgument(Arg.getLocation(), D);
1913 }
Mike Stump11289f42009-09-09 15:08:12 +00001914
Douglas Gregore922c772009-08-04 22:27:00 +00001915 case TemplateArgument::Expression: {
1916 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00001917 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00001918 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00001919
Douglas Gregore922c772009-08-04 22:27:00 +00001920 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
1921 if (E.isInvalid())
1922 return TemplateArgument();
1923 return TemplateArgument(E.takeAs<Expr>());
1924 }
Mike Stump11289f42009-09-09 15:08:12 +00001925
Douglas Gregore922c772009-08-04 22:27:00 +00001926 case TemplateArgument::Pack: {
1927 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1928 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00001929 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00001930 AEnd = Arg.pack_end();
1931 A != AEnd; ++A) {
1932 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
1933 if (TA.isNull())
1934 return TA;
Mike Stump11289f42009-09-09 15:08:12 +00001935
Douglas Gregore922c772009-08-04 22:27:00 +00001936 TransformedArgs.push_back(TA);
1937 }
1938 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00001939 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00001940 true);
1941 return Result;
1942 }
1943 }
Mike Stump11289f42009-09-09 15:08:12 +00001944
Douglas Gregore922c772009-08-04 22:27:00 +00001945 // Work around bogus GCC warning
1946 return TemplateArgument();
1947}
1948
Douglas Gregord6ff3322009-08-04 16:50:30 +00001949//===----------------------------------------------------------------------===//
1950// Type transformation
1951//===----------------------------------------------------------------------===//
1952
1953template<typename Derived>
1954QualType TreeTransform<Derived>::TransformType(QualType T) {
1955 if (getDerived().AlreadyTransformed(T))
1956 return T;
Mike Stump11289f42009-09-09 15:08:12 +00001957
John McCall550e0c22009-10-21 00:40:46 +00001958 // Temporary workaround. All of these transformations should
1959 // eventually turn into transformations on TypeLocs.
1960 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00001961 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00001962
1963 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00001964
John McCall550e0c22009-10-21 00:40:46 +00001965 if (!NewDI)
1966 return QualType();
1967
1968 return NewDI->getType();
1969}
1970
1971template<typename Derived>
1972DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
1973 if (getDerived().AlreadyTransformed(DI->getType()))
1974 return DI;
1975
1976 TypeLocBuilder TLB;
1977
1978 TypeLoc TL = DI->getTypeLoc();
1979 TLB.reserve(TL.getFullDataSize());
1980
1981 QualType Result = getDerived().TransformType(TLB, TL);
1982 if (Result.isNull())
1983 return 0;
1984
1985 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
1986}
1987
1988template<typename Derived>
1989QualType
1990TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
1991 switch (T.getTypeLocClass()) {
1992#define ABSTRACT_TYPELOC(CLASS, PARENT)
1993#define TYPELOC(CLASS, PARENT) \
1994 case TypeLoc::CLASS: \
1995 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
1996#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00001997 }
Mike Stump11289f42009-09-09 15:08:12 +00001998
John McCall550e0c22009-10-21 00:40:46 +00001999 llvm::llvm_unreachable("unhandled type loc!");
2000 return QualType();
2001}
2002
2003/// FIXME: By default, this routine adds type qualifiers only to types
2004/// that can have qualifiers, and silently suppresses those qualifiers
2005/// that are not permitted (e.g., qualifiers on reference or function
2006/// types). This is the right thing for template instantiation, but
2007/// probably not for other clients.
2008template<typename Derived>
2009QualType
2010TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2011 QualifiedTypeLoc T) {
2012 Qualifiers Quals = T.getType().getQualifiers();
2013
2014 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2015 if (Result.isNull())
2016 return QualType();
2017
2018 // Silently suppress qualifiers if the result type can't be qualified.
2019 // FIXME: this is the right thing for template instantiation, but
2020 // probably not for other clients.
2021 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002022 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002023
John McCall550e0c22009-10-21 00:40:46 +00002024 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2025
2026 TLB.push<QualifiedTypeLoc>(Result);
2027
2028 // No location information to preserve.
2029
2030 return Result;
2031}
2032
2033template <class TyLoc> static inline
2034QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2035 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2036 NewT.setNameLoc(T.getNameLoc());
2037 return T.getType();
2038}
2039
2040// Ugly metaprogramming macros because I couldn't be bothered to make
2041// the equivalent template version work.
2042#define TransformPointerLikeType(TypeClass) do { \
2043 QualType PointeeType \
2044 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2045 if (PointeeType.isNull()) \
2046 return QualType(); \
2047 \
2048 QualType Result = TL.getType(); \
2049 if (getDerived().AlwaysRebuild() || \
2050 PointeeType != TL.getPointeeLoc().getType()) { \
2051 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2052 if (Result.isNull()) \
2053 return QualType(); \
2054 } \
2055 \
2056 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2057 NewT.setSigilLoc(TL.getSigilLoc()); \
2058 \
2059 return Result; \
2060} while(0)
2061
2062// Reference collapsing forces us to transform reference types
2063// differently from the other pointer-like types.
2064#define TransformReferenceType(TypeClass) do { \
2065 QualType PointeeType \
2066 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2067 if (PointeeType.isNull()) \
2068 return QualType(); \
2069 \
2070 QualType Result = TL.getType(); \
2071 if (getDerived().AlwaysRebuild() || \
2072 PointeeType != TL.getPointeeLoc().getType()) { \
2073 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2074 if (Result.isNull()) \
2075 return QualType(); \
2076 } \
2077 \
2078 /* Workaround: rebuild doesn't always change the type */ \
2079 /* FIXME: avoid losing this location information. */ \
2080 if (Result == PointeeType) \
2081 return Result; \
2082 ReferenceTypeLoc NewTL; \
2083 if (isa<LValueReferenceType>(Result)) \
2084 NewTL = TLB.push<LValueReferenceTypeLoc>(Result); \
2085 else \
2086 NewTL = TLB.push<RValueReferenceTypeLoc>(Result); \
2087 NewTL.setSigilLoc(TL.getSigilLoc()); \
2088 return Result; \
2089} while (0)
2090
2091template<typename Derived>
2092QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2093 BuiltinTypeLoc T) {
2094 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002095}
Mike Stump11289f42009-09-09 15:08:12 +00002096
Douglas Gregord6ff3322009-08-04 16:50:30 +00002097template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002098QualType
John McCall550e0c22009-10-21 00:40:46 +00002099TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2100 FixedWidthIntTypeLoc T) {
2101 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002102}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002103
Douglas Gregord6ff3322009-08-04 16:50:30 +00002104template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002105QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2106 ComplexTypeLoc T) {
2107 // FIXME: recurse?
2108 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002109}
Mike Stump11289f42009-09-09 15:08:12 +00002110
Douglas Gregord6ff3322009-08-04 16:50:30 +00002111template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002112QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2113 PointerTypeLoc TL) {
2114 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002115}
Mike Stump11289f42009-09-09 15:08:12 +00002116
2117template<typename Derived>
2118QualType
John McCall550e0c22009-10-21 00:40:46 +00002119TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2120 BlockPointerTypeLoc TL) {
2121 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002122}
2123
Mike Stump11289f42009-09-09 15:08:12 +00002124template<typename Derived>
2125QualType
John McCall550e0c22009-10-21 00:40:46 +00002126TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2127 LValueReferenceTypeLoc TL) {
2128 TransformReferenceType(LValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002129}
2130
Mike Stump11289f42009-09-09 15:08:12 +00002131template<typename Derived>
2132QualType
John McCall550e0c22009-10-21 00:40:46 +00002133TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2134 RValueReferenceTypeLoc TL) {
2135 TransformReferenceType(RValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002136}
Mike Stump11289f42009-09-09 15:08:12 +00002137
Douglas Gregord6ff3322009-08-04 16:50:30 +00002138template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002139QualType
John McCall550e0c22009-10-21 00:40:46 +00002140TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2141 MemberPointerTypeLoc TL) {
2142 MemberPointerType *T = TL.getTypePtr();
2143
2144 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002145 if (PointeeType.isNull())
2146 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002147
John McCall550e0c22009-10-21 00:40:46 +00002148 // TODO: preserve source information for this.
2149 QualType ClassType
2150 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002151 if (ClassType.isNull())
2152 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002153
John McCall550e0c22009-10-21 00:40:46 +00002154 QualType Result = TL.getType();
2155 if (getDerived().AlwaysRebuild() ||
2156 PointeeType != T->getPointeeType() ||
2157 ClassType != QualType(T->getClass(), 0)) {
2158 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2159 if (Result.isNull())
2160 return QualType();
2161 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002162
John McCall550e0c22009-10-21 00:40:46 +00002163 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2164 NewTL.setSigilLoc(TL.getSigilLoc());
2165
2166 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002167}
2168
Mike Stump11289f42009-09-09 15:08:12 +00002169template<typename Derived>
2170QualType
John McCall550e0c22009-10-21 00:40:46 +00002171TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2172 ConstantArrayTypeLoc TL) {
2173 ConstantArrayType *T = TL.getTypePtr();
2174 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002175 if (ElementType.isNull())
2176 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002177
John McCall550e0c22009-10-21 00:40:46 +00002178 QualType Result = TL.getType();
2179 if (getDerived().AlwaysRebuild() ||
2180 ElementType != T->getElementType()) {
2181 Result = getDerived().RebuildConstantArrayType(ElementType,
2182 T->getSizeModifier(),
2183 T->getSize(),
2184 T->getIndexTypeCVRQualifiers());
2185 if (Result.isNull())
2186 return QualType();
2187 }
2188
2189 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2190 NewTL.setLBracketLoc(TL.getLBracketLoc());
2191 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002192
John McCall550e0c22009-10-21 00:40:46 +00002193 Expr *Size = TL.getSizeExpr();
2194 if (Size) {
2195 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2196 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2197 }
2198 NewTL.setSizeExpr(Size);
2199
2200 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002201}
Mike Stump11289f42009-09-09 15:08:12 +00002202
Douglas Gregord6ff3322009-08-04 16:50:30 +00002203template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002204QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002205 TypeLocBuilder &TLB,
2206 IncompleteArrayTypeLoc TL) {
2207 IncompleteArrayType *T = TL.getTypePtr();
2208 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002209 if (ElementType.isNull())
2210 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002211
John McCall550e0c22009-10-21 00:40:46 +00002212 QualType Result = TL.getType();
2213 if (getDerived().AlwaysRebuild() ||
2214 ElementType != T->getElementType()) {
2215 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002216 T->getSizeModifier(),
John McCall550e0c22009-10-21 00:40:46 +00002217 T->getIndexTypeCVRQualifiers());
2218 if (Result.isNull())
2219 return QualType();
2220 }
2221
2222 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2223 NewTL.setLBracketLoc(TL.getLBracketLoc());
2224 NewTL.setRBracketLoc(TL.getRBracketLoc());
2225 NewTL.setSizeExpr(0);
2226
2227 return Result;
2228}
2229
2230template<typename Derived>
2231QualType
2232TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2233 VariableArrayTypeLoc TL) {
2234 VariableArrayType *T = TL.getTypePtr();
2235 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2236 if (ElementType.isNull())
2237 return QualType();
2238
2239 // Array bounds are not potentially evaluated contexts
2240 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2241
2242 Sema::OwningExprResult SizeResult
2243 = getDerived().TransformExpr(T->getSizeExpr());
2244 if (SizeResult.isInvalid())
2245 return QualType();
2246
2247 Expr *Size = static_cast<Expr*>(SizeResult.get());
2248
2249 QualType Result = TL.getType();
2250 if (getDerived().AlwaysRebuild() ||
2251 ElementType != T->getElementType() ||
2252 Size != T->getSizeExpr()) {
2253 Result = getDerived().RebuildVariableArrayType(ElementType,
2254 T->getSizeModifier(),
2255 move(SizeResult),
2256 T->getIndexTypeCVRQualifiers(),
2257 T->getBracketsRange());
2258 if (Result.isNull())
2259 return QualType();
2260 }
2261 else SizeResult.take();
2262
2263 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2264 NewTL.setLBracketLoc(TL.getLBracketLoc());
2265 NewTL.setRBracketLoc(TL.getRBracketLoc());
2266 NewTL.setSizeExpr(Size);
2267
2268 return Result;
2269}
2270
2271template<typename Derived>
2272QualType
2273TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2274 DependentSizedArrayTypeLoc TL) {
2275 DependentSizedArrayType *T = TL.getTypePtr();
2276 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2277 if (ElementType.isNull())
2278 return QualType();
2279
2280 // Array bounds are not potentially evaluated contexts
2281 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2282
2283 Sema::OwningExprResult SizeResult
2284 = getDerived().TransformExpr(T->getSizeExpr());
2285 if (SizeResult.isInvalid())
2286 return QualType();
2287
2288 Expr *Size = static_cast<Expr*>(SizeResult.get());
2289
2290 QualType Result = TL.getType();
2291 if (getDerived().AlwaysRebuild() ||
2292 ElementType != T->getElementType() ||
2293 Size != T->getSizeExpr()) {
2294 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2295 T->getSizeModifier(),
2296 move(SizeResult),
2297 T->getIndexTypeCVRQualifiers(),
2298 T->getBracketsRange());
2299 if (Result.isNull())
2300 return QualType();
2301 }
2302 else SizeResult.take();
2303
2304 // We might have any sort of array type now, but fortunately they
2305 // all have the same location layout.
2306 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2307 NewTL.setLBracketLoc(TL.getLBracketLoc());
2308 NewTL.setRBracketLoc(TL.getRBracketLoc());
2309 NewTL.setSizeExpr(Size);
2310
2311 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002312}
Mike Stump11289f42009-09-09 15:08:12 +00002313
2314template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002315QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002316 TypeLocBuilder &TLB,
2317 DependentSizedExtVectorTypeLoc TL) {
2318 DependentSizedExtVectorType *T = TL.getTypePtr();
2319
2320 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002321 QualType ElementType = getDerived().TransformType(T->getElementType());
2322 if (ElementType.isNull())
2323 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002324
Douglas Gregore922c772009-08-04 22:27:00 +00002325 // Vector sizes are not potentially evaluated contexts
2326 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2327
Douglas Gregord6ff3322009-08-04 16:50:30 +00002328 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2329 if (Size.isInvalid())
2330 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002331
John McCall550e0c22009-10-21 00:40:46 +00002332 QualType Result = TL.getType();
2333 if (getDerived().AlwaysRebuild() ||
2334 ElementType != T->getElementType() &&
2335 Size.get() != T->getSizeExpr()) {
2336 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002337 move(Size),
2338 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002339 if (Result.isNull())
2340 return QualType();
2341 }
2342 else Size.take();
2343
2344 // Result might be dependent or not.
2345 if (isa<DependentSizedExtVectorType>(Result)) {
2346 DependentSizedExtVectorTypeLoc NewTL
2347 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2348 NewTL.setNameLoc(TL.getNameLoc());
2349 } else {
2350 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2351 NewTL.setNameLoc(TL.getNameLoc());
2352 }
2353
2354 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002355}
Mike Stump11289f42009-09-09 15:08:12 +00002356
2357template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002358QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2359 VectorTypeLoc TL) {
2360 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002361 QualType ElementType = getDerived().TransformType(T->getElementType());
2362 if (ElementType.isNull())
2363 return QualType();
2364
John McCall550e0c22009-10-21 00:40:46 +00002365 QualType Result = TL.getType();
2366 if (getDerived().AlwaysRebuild() ||
2367 ElementType != T->getElementType()) {
2368 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2369 if (Result.isNull())
2370 return QualType();
2371 }
2372
2373 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2374 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002375
John McCall550e0c22009-10-21 00:40:46 +00002376 return Result;
2377}
2378
2379template<typename Derived>
2380QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2381 ExtVectorTypeLoc TL) {
2382 VectorType *T = TL.getTypePtr();
2383 QualType ElementType = getDerived().TransformType(T->getElementType());
2384 if (ElementType.isNull())
2385 return QualType();
2386
2387 QualType Result = TL.getType();
2388 if (getDerived().AlwaysRebuild() ||
2389 ElementType != T->getElementType()) {
2390 Result = getDerived().RebuildExtVectorType(ElementType,
2391 T->getNumElements(),
2392 /*FIXME*/ SourceLocation());
2393 if (Result.isNull())
2394 return QualType();
2395 }
2396
2397 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2398 NewTL.setNameLoc(TL.getNameLoc());
2399
2400 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002401}
Mike Stump11289f42009-09-09 15:08:12 +00002402
2403template<typename Derived>
2404QualType
John McCall550e0c22009-10-21 00:40:46 +00002405TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2406 FunctionProtoTypeLoc TL) {
2407 FunctionProtoType *T = TL.getTypePtr();
2408 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002409 if (ResultType.isNull())
2410 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002411
John McCall550e0c22009-10-21 00:40:46 +00002412 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002413 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002414 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2415 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2416 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002417
John McCall550e0c22009-10-21 00:40:46 +00002418 QualType NewType;
2419 ParmVarDecl *NewParm;
2420
2421 if (OldParm) {
2422 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2423 assert(OldDI->getType() == T->getArgType(i));
2424
2425 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2426 if (!NewDI)
2427 return QualType();
2428
2429 if (NewDI == OldDI)
2430 NewParm = OldParm;
2431 else
2432 NewParm = ParmVarDecl::Create(SemaRef.Context,
2433 OldParm->getDeclContext(),
2434 OldParm->getLocation(),
2435 OldParm->getIdentifier(),
2436 NewDI->getType(),
2437 NewDI,
2438 OldParm->getStorageClass(),
2439 /* DefArg */ NULL);
2440 NewType = NewParm->getType();
2441
2442 // Deal with the possibility that we don't have a parameter
2443 // declaration for this parameter.
2444 } else {
2445 NewParm = 0;
2446
2447 QualType OldType = T->getArgType(i);
2448 NewType = getDerived().TransformType(OldType);
2449 if (NewType.isNull())
2450 return QualType();
2451 }
2452
2453 ParamTypes.push_back(NewType);
2454 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002455 }
Mike Stump11289f42009-09-09 15:08:12 +00002456
John McCall550e0c22009-10-21 00:40:46 +00002457 QualType Result = TL.getType();
2458 if (getDerived().AlwaysRebuild() ||
2459 ResultType != T->getResultType() ||
2460 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2461 Result = getDerived().RebuildFunctionProtoType(ResultType,
2462 ParamTypes.data(),
2463 ParamTypes.size(),
2464 T->isVariadic(),
2465 T->getTypeQuals());
2466 if (Result.isNull())
2467 return QualType();
2468 }
Mike Stump11289f42009-09-09 15:08:12 +00002469
John McCall550e0c22009-10-21 00:40:46 +00002470 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2471 NewTL.setLParenLoc(TL.getLParenLoc());
2472 NewTL.setRParenLoc(TL.getRParenLoc());
2473 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2474 NewTL.setArg(i, ParamDecls[i]);
2475
2476 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002477}
Mike Stump11289f42009-09-09 15:08:12 +00002478
Douglas Gregord6ff3322009-08-04 16:50:30 +00002479template<typename Derived>
2480QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002481 TypeLocBuilder &TLB,
2482 FunctionNoProtoTypeLoc TL) {
2483 FunctionNoProtoType *T = TL.getTypePtr();
2484 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2485 if (ResultType.isNull())
2486 return QualType();
2487
2488 QualType Result = TL.getType();
2489 if (getDerived().AlwaysRebuild() ||
2490 ResultType != T->getResultType())
2491 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2492
2493 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2494 NewTL.setLParenLoc(TL.getLParenLoc());
2495 NewTL.setRParenLoc(TL.getRParenLoc());
2496
2497 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002498}
Mike Stump11289f42009-09-09 15:08:12 +00002499
Douglas Gregord6ff3322009-08-04 16:50:30 +00002500template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002501QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2502 TypedefTypeLoc TL) {
2503 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002504 TypedefDecl *Typedef
2505 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2506 if (!Typedef)
2507 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002508
John McCall550e0c22009-10-21 00:40:46 +00002509 QualType Result = TL.getType();
2510 if (getDerived().AlwaysRebuild() ||
2511 Typedef != T->getDecl()) {
2512 Result = getDerived().RebuildTypedefType(Typedef);
2513 if (Result.isNull())
2514 return QualType();
2515 }
Mike Stump11289f42009-09-09 15:08:12 +00002516
John McCall550e0c22009-10-21 00:40:46 +00002517 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2518 NewTL.setNameLoc(TL.getNameLoc());
2519
2520 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002521}
Mike Stump11289f42009-09-09 15:08:12 +00002522
Douglas Gregord6ff3322009-08-04 16:50:30 +00002523template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002524QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2525 TypeOfExprTypeLoc TL) {
2526 TypeOfExprType *T = TL.getTypePtr();
2527
Douglas Gregore922c772009-08-04 22:27:00 +00002528 // typeof expressions are not potentially evaluated contexts
2529 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002530
Douglas Gregord6ff3322009-08-04 16:50:30 +00002531 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2532 if (E.isInvalid())
2533 return QualType();
2534
John McCall550e0c22009-10-21 00:40:46 +00002535 QualType Result = TL.getType();
2536 if (getDerived().AlwaysRebuild() ||
2537 E.get() != T->getUnderlyingExpr()) {
2538 Result = getDerived().RebuildTypeOfExprType(move(E));
2539 if (Result.isNull())
2540 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002541 }
John McCall550e0c22009-10-21 00:40:46 +00002542 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002543
John McCall550e0c22009-10-21 00:40:46 +00002544 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2545 NewTL.setNameLoc(TL.getNameLoc());
2546
2547 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002548}
Mike Stump11289f42009-09-09 15:08:12 +00002549
2550template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002551QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2552 TypeOfTypeLoc TL) {
2553 TypeOfType *T = TL.getTypePtr();
2554
2555 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002556 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2557 if (Underlying.isNull())
2558 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002559
John McCall550e0c22009-10-21 00:40:46 +00002560 QualType Result = TL.getType();
2561 if (getDerived().AlwaysRebuild() ||
2562 Underlying != T->getUnderlyingType()) {
2563 Result = getDerived().RebuildTypeOfType(Underlying);
2564 if (Result.isNull())
2565 return QualType();
2566 }
Mike Stump11289f42009-09-09 15:08:12 +00002567
John McCall550e0c22009-10-21 00:40:46 +00002568 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2569 NewTL.setNameLoc(TL.getNameLoc());
2570
2571 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002572}
Mike Stump11289f42009-09-09 15:08:12 +00002573
2574template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002575QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2576 DecltypeTypeLoc TL) {
2577 DecltypeType *T = TL.getTypePtr();
2578
Douglas Gregore922c772009-08-04 22:27:00 +00002579 // decltype expressions are not potentially evaluated contexts
2580 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002581
Douglas Gregord6ff3322009-08-04 16:50:30 +00002582 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2583 if (E.isInvalid())
2584 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002585
John McCall550e0c22009-10-21 00:40:46 +00002586 QualType Result = TL.getType();
2587 if (getDerived().AlwaysRebuild() ||
2588 E.get() != T->getUnderlyingExpr()) {
2589 Result = getDerived().RebuildDecltypeType(move(E));
2590 if (Result.isNull())
2591 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002592 }
John McCall550e0c22009-10-21 00:40:46 +00002593 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002594
John McCall550e0c22009-10-21 00:40:46 +00002595 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2596 NewTL.setNameLoc(TL.getNameLoc());
2597
2598 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002599}
2600
2601template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002602QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2603 RecordTypeLoc TL) {
2604 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002605 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002606 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002607 if (!Record)
2608 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002609
John McCall550e0c22009-10-21 00:40:46 +00002610 QualType Result = TL.getType();
2611 if (getDerived().AlwaysRebuild() ||
2612 Record != T->getDecl()) {
2613 Result = getDerived().RebuildRecordType(Record);
2614 if (Result.isNull())
2615 return QualType();
2616 }
Mike Stump11289f42009-09-09 15:08:12 +00002617
John McCall550e0c22009-10-21 00:40:46 +00002618 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2619 NewTL.setNameLoc(TL.getNameLoc());
2620
2621 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002622}
Mike Stump11289f42009-09-09 15:08:12 +00002623
2624template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002625QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2626 EnumTypeLoc TL) {
2627 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002628 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002629 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002630 if (!Enum)
2631 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002632
John McCall550e0c22009-10-21 00:40:46 +00002633 QualType Result = TL.getType();
2634 if (getDerived().AlwaysRebuild() ||
2635 Enum != T->getDecl()) {
2636 Result = getDerived().RebuildEnumType(Enum);
2637 if (Result.isNull())
2638 return QualType();
2639 }
Mike Stump11289f42009-09-09 15:08:12 +00002640
John McCall550e0c22009-10-21 00:40:46 +00002641 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2642 NewTL.setNameLoc(TL.getNameLoc());
2643
2644 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002645}
John McCallfcc33b02009-09-05 00:15:47 +00002646
2647template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002648QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2649 ElaboratedTypeLoc TL) {
2650 ElaboratedType *T = TL.getTypePtr();
2651
2652 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002653 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2654 if (Underlying.isNull())
2655 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002656
John McCall550e0c22009-10-21 00:40:46 +00002657 QualType Result = TL.getType();
2658 if (getDerived().AlwaysRebuild() ||
2659 Underlying != T->getUnderlyingType()) {
2660 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2661 if (Result.isNull())
2662 return QualType();
2663 }
Mike Stump11289f42009-09-09 15:08:12 +00002664
John McCall550e0c22009-10-21 00:40:46 +00002665 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2666 NewTL.setNameLoc(TL.getNameLoc());
2667
2668 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002669}
Mike Stump11289f42009-09-09 15:08:12 +00002670
2671
Douglas Gregord6ff3322009-08-04 16:50:30 +00002672template<typename Derived>
2673QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002674 TypeLocBuilder &TLB,
2675 TemplateTypeParmTypeLoc TL) {
2676 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002677}
2678
Mike Stump11289f42009-09-09 15:08:12 +00002679template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002680QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002681 TypeLocBuilder &TLB,
2682 SubstTemplateTypeParmTypeLoc TL) {
2683 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002684}
2685
2686template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002687inline QualType
2688TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002689 TypeLocBuilder &TLB,
2690 TemplateSpecializationTypeLoc TL) {
2691 // TODO: figure out how make this work with an ObjectType.
2692 QualType Result
2693 = TransformTemplateSpecializationType(TL.getTypePtr(), QualType());
2694 if (Result.isNull())
2695 return QualType();
2696
2697 TemplateSpecializationTypeLoc NewTL
2698 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2699 NewTL.setNameLoc(TL.getNameLoc());
2700
2701 return Result;
Douglas Gregorc59e5612009-10-19 22:04:39 +00002702}
2703
2704template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002705QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
Douglas Gregorc59e5612009-10-19 22:04:39 +00002706 const TemplateSpecializationType *T,
2707 QualType ObjectType) {
Mike Stump11289f42009-09-09 15:08:12 +00002708 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002709 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002710 if (Template.isNull())
2711 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002712
Douglas Gregord6ff3322009-08-04 16:50:30 +00002713 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2714 NewTemplateArgs.reserve(T->getNumArgs());
2715 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2716 Arg != ArgEnd; ++Arg) {
2717 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2718 if (NewArg.isNull())
2719 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002720
Douglas Gregord6ff3322009-08-04 16:50:30 +00002721 NewTemplateArgs.push_back(NewArg);
2722 }
Mike Stump11289f42009-09-09 15:08:12 +00002723
Douglas Gregord6ff3322009-08-04 16:50:30 +00002724 // FIXME: early abort if all of the template arguments and such are the
2725 // same.
Mike Stump11289f42009-09-09 15:08:12 +00002726
Douglas Gregord6ff3322009-08-04 16:50:30 +00002727 // FIXME: We're missing the locations of the template name, '<', and '>'.
2728 return getDerived().RebuildTemplateSpecializationType(Template,
2729 NewTemplateArgs.data(),
2730 NewTemplateArgs.size());
2731}
Mike Stump11289f42009-09-09 15:08:12 +00002732
2733template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002734QualType
2735TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2736 QualifiedNameTypeLoc TL) {
2737 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002738 NestedNameSpecifier *NNS
2739 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2740 SourceRange());
2741 if (!NNS)
2742 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002743
Douglas Gregord6ff3322009-08-04 16:50:30 +00002744 QualType Named = getDerived().TransformType(T->getNamedType());
2745 if (Named.isNull())
2746 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002747
John McCall550e0c22009-10-21 00:40:46 +00002748 QualType Result = TL.getType();
2749 if (getDerived().AlwaysRebuild() ||
2750 NNS != T->getQualifier() ||
2751 Named != T->getNamedType()) {
2752 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2753 if (Result.isNull())
2754 return QualType();
2755 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002756
John McCall550e0c22009-10-21 00:40:46 +00002757 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2758 NewTL.setNameLoc(TL.getNameLoc());
2759
2760 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002761}
Mike Stump11289f42009-09-09 15:08:12 +00002762
2763template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002764QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2765 TypenameTypeLoc TL) {
2766 TypenameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002767 NestedNameSpecifier *NNS
2768 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor15acfb92009-08-06 16:20:37 +00002769 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002770 if (!NNS)
2771 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002772
John McCall550e0c22009-10-21 00:40:46 +00002773 QualType Result;
2774
Douglas Gregord6ff3322009-08-04 16:50:30 +00002775 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002776 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002777 = getDerived().TransformType(QualType(TemplateId, 0));
2778 if (NewTemplateId.isNull())
2779 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002780
Douglas Gregord6ff3322009-08-04 16:50:30 +00002781 if (!getDerived().AlwaysRebuild() &&
2782 NNS == T->getQualifier() &&
2783 NewTemplateId == QualType(TemplateId, 0))
2784 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002785
John McCall550e0c22009-10-21 00:40:46 +00002786 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2787 } else {
2788 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002789 }
John McCall550e0c22009-10-21 00:40:46 +00002790 if (Result.isNull())
2791 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002792
John McCall550e0c22009-10-21 00:40:46 +00002793 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2794 NewTL.setNameLoc(TL.getNameLoc());
2795
2796 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002797}
Mike Stump11289f42009-09-09 15:08:12 +00002798
Douglas Gregord6ff3322009-08-04 16:50:30 +00002799template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002800QualType
2801TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2802 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002803 assert(false && "TransformObjCInterfaceType unimplemented");
2804 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002805}
Mike Stump11289f42009-09-09 15:08:12 +00002806
2807template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002808QualType
2809TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2810 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002811 assert(false && "TransformObjCObjectPointerType unimplemented");
2812 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002813}
2814
Douglas Gregord6ff3322009-08-04 16:50:30 +00002815//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002816// Statement transformation
2817//===----------------------------------------------------------------------===//
2818template<typename Derived>
2819Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002820TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2821 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002822}
2823
2824template<typename Derived>
2825Sema::OwningStmtResult
2826TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2827 return getDerived().TransformCompoundStmt(S, false);
2828}
2829
2830template<typename Derived>
2831Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002832TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002833 bool IsStmtExpr) {
2834 bool SubStmtChanged = false;
2835 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2836 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2837 B != BEnd; ++B) {
2838 OwningStmtResult Result = getDerived().TransformStmt(*B);
2839 if (Result.isInvalid())
2840 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002841
Douglas Gregorebe10102009-08-20 07:17:43 +00002842 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2843 Statements.push_back(Result.takeAs<Stmt>());
2844 }
Mike Stump11289f42009-09-09 15:08:12 +00002845
Douglas Gregorebe10102009-08-20 07:17:43 +00002846 if (!getDerived().AlwaysRebuild() &&
2847 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00002848 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002849
2850 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2851 move_arg(Statements),
2852 S->getRBracLoc(),
2853 IsStmtExpr);
2854}
Mike Stump11289f42009-09-09 15:08:12 +00002855
Douglas Gregorebe10102009-08-20 07:17:43 +00002856template<typename Derived>
2857Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002858TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002859 // The case value expressions are not potentially evaluated.
2860 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002861
Douglas Gregorebe10102009-08-20 07:17:43 +00002862 // Transform the left-hand case value.
2863 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2864 if (LHS.isInvalid())
2865 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002866
Douglas Gregorebe10102009-08-20 07:17:43 +00002867 // Transform the right-hand case value (for the GNU case-range extension).
2868 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2869 if (RHS.isInvalid())
2870 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002871
Douglas Gregorebe10102009-08-20 07:17:43 +00002872 // Build the case statement.
2873 // Case statements are always rebuilt so that they will attached to their
2874 // transformed switch statement.
2875 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2876 move(LHS),
2877 S->getEllipsisLoc(),
2878 move(RHS),
2879 S->getColonLoc());
2880 if (Case.isInvalid())
2881 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002882
Douglas Gregorebe10102009-08-20 07:17:43 +00002883 // Transform the statement following the case
2884 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2885 if (SubStmt.isInvalid())
2886 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002887
Douglas Gregorebe10102009-08-20 07:17:43 +00002888 // Attach the body to the case statement
2889 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2890}
2891
2892template<typename Derived>
2893Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002894TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002895 // Transform the statement following the default case
2896 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2897 if (SubStmt.isInvalid())
2898 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002899
Douglas Gregorebe10102009-08-20 07:17:43 +00002900 // Default statements are always rebuilt
2901 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2902 move(SubStmt));
2903}
Mike Stump11289f42009-09-09 15:08:12 +00002904
Douglas Gregorebe10102009-08-20 07:17:43 +00002905template<typename Derived>
2906Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002907TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002908 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2909 if (SubStmt.isInvalid())
2910 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002911
Douglas Gregorebe10102009-08-20 07:17:43 +00002912 // FIXME: Pass the real colon location in.
2913 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2914 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2915 move(SubStmt));
2916}
Mike Stump11289f42009-09-09 15:08:12 +00002917
Douglas Gregorebe10102009-08-20 07:17:43 +00002918template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002919Sema::OwningStmtResult
2920TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002921 // Transform the condition
2922 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2923 if (Cond.isInvalid())
2924 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002925
Douglas Gregorebe10102009-08-20 07:17:43 +00002926 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00002927
Douglas Gregorebe10102009-08-20 07:17:43 +00002928 // Transform the "then" branch.
2929 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2930 if (Then.isInvalid())
2931 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002932
Douglas Gregorebe10102009-08-20 07:17:43 +00002933 // Transform the "else" branch.
2934 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2935 if (Else.isInvalid())
2936 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002937
Douglas Gregorebe10102009-08-20 07:17:43 +00002938 if (!getDerived().AlwaysRebuild() &&
2939 FullCond->get() == S->getCond() &&
2940 Then.get() == S->getThen() &&
2941 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00002942 return SemaRef.Owned(S->Retain());
2943
Douglas Gregorebe10102009-08-20 07:17:43 +00002944 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00002945 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00002946}
2947
2948template<typename Derived>
2949Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002950TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002951 // Transform the condition.
2952 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2953 if (Cond.isInvalid())
2954 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002955
Douglas Gregorebe10102009-08-20 07:17:43 +00002956 // Rebuild the switch statement.
2957 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2958 if (Switch.isInvalid())
2959 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002960
Douglas Gregorebe10102009-08-20 07:17:43 +00002961 // Transform the body of the switch statement.
2962 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2963 if (Body.isInvalid())
2964 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002965
Douglas Gregorebe10102009-08-20 07:17:43 +00002966 // Complete the switch statement.
2967 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2968 move(Body));
2969}
Mike Stump11289f42009-09-09 15:08:12 +00002970
Douglas Gregorebe10102009-08-20 07:17:43 +00002971template<typename Derived>
2972Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002973TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002974 // Transform the condition
2975 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2976 if (Cond.isInvalid())
2977 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002978
Douglas Gregorebe10102009-08-20 07:17:43 +00002979 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00002980
Douglas Gregorebe10102009-08-20 07:17:43 +00002981 // Transform the body
2982 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2983 if (Body.isInvalid())
2984 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002985
Douglas Gregorebe10102009-08-20 07:17:43 +00002986 if (!getDerived().AlwaysRebuild() &&
2987 FullCond->get() == S->getCond() &&
2988 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00002989 return SemaRef.Owned(S->Retain());
2990
Douglas Gregorebe10102009-08-20 07:17:43 +00002991 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2992}
Mike Stump11289f42009-09-09 15:08:12 +00002993
Douglas Gregorebe10102009-08-20 07:17:43 +00002994template<typename Derived>
2995Sema::OwningStmtResult
2996TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2997 // Transform the condition
2998 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2999 if (Cond.isInvalid())
3000 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003001
Douglas Gregorebe10102009-08-20 07:17:43 +00003002 // Transform the body
3003 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3004 if (Body.isInvalid())
3005 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003006
Douglas Gregorebe10102009-08-20 07:17:43 +00003007 if (!getDerived().AlwaysRebuild() &&
3008 Cond.get() == S->getCond() &&
3009 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003010 return SemaRef.Owned(S->Retain());
3011
Douglas Gregorebe10102009-08-20 07:17:43 +00003012 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3013 /*FIXME:*/S->getWhileLoc(), move(Cond),
3014 S->getRParenLoc());
3015}
Mike Stump11289f42009-09-09 15:08:12 +00003016
Douglas Gregorebe10102009-08-20 07:17:43 +00003017template<typename Derived>
3018Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003019TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003020 // Transform the initialization statement
3021 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3022 if (Init.isInvalid())
3023 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003024
Douglas Gregorebe10102009-08-20 07:17:43 +00003025 // Transform the condition
3026 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3027 if (Cond.isInvalid())
3028 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003029
Douglas Gregorebe10102009-08-20 07:17:43 +00003030 // Transform the increment
3031 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3032 if (Inc.isInvalid())
3033 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003034
Douglas Gregorebe10102009-08-20 07:17:43 +00003035 // Transform the body
3036 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3037 if (Body.isInvalid())
3038 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003039
Douglas Gregorebe10102009-08-20 07:17:43 +00003040 if (!getDerived().AlwaysRebuild() &&
3041 Init.get() == S->getInit() &&
3042 Cond.get() == S->getCond() &&
3043 Inc.get() == S->getInc() &&
3044 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003045 return SemaRef.Owned(S->Retain());
3046
Douglas Gregorebe10102009-08-20 07:17:43 +00003047 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3048 move(Init), move(Cond), move(Inc),
3049 S->getRParenLoc(), move(Body));
3050}
3051
3052template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003053Sema::OwningStmtResult
3054TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003055 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003056 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003057 S->getLabel());
3058}
3059
3060template<typename Derived>
3061Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003062TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003063 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3064 if (Target.isInvalid())
3065 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003066
Douglas Gregorebe10102009-08-20 07:17:43 +00003067 if (!getDerived().AlwaysRebuild() &&
3068 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003069 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003070
3071 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3072 move(Target));
3073}
3074
3075template<typename Derived>
3076Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003077TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3078 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003079}
Mike Stump11289f42009-09-09 15:08:12 +00003080
Douglas Gregorebe10102009-08-20 07:17:43 +00003081template<typename Derived>
3082Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003083TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3084 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003085}
Mike Stump11289f42009-09-09 15:08:12 +00003086
Douglas Gregorebe10102009-08-20 07:17:43 +00003087template<typename Derived>
3088Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003089TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003090 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3091 if (Result.isInvalid())
3092 return SemaRef.StmtError();
3093
Mike Stump11289f42009-09-09 15:08:12 +00003094 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003095 // to tell whether the return type of the function has changed.
3096 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3097}
Mike Stump11289f42009-09-09 15:08:12 +00003098
Douglas Gregorebe10102009-08-20 07:17:43 +00003099template<typename Derived>
3100Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003101TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003102 bool DeclChanged = false;
3103 llvm::SmallVector<Decl *, 4> Decls;
3104 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3105 D != DEnd; ++D) {
3106 Decl *Transformed = getDerived().TransformDefinition(*D);
3107 if (!Transformed)
3108 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003109
Douglas Gregorebe10102009-08-20 07:17:43 +00003110 if (Transformed != *D)
3111 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003112
Douglas Gregorebe10102009-08-20 07:17:43 +00003113 Decls.push_back(Transformed);
3114 }
Mike Stump11289f42009-09-09 15:08:12 +00003115
Douglas Gregorebe10102009-08-20 07:17:43 +00003116 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003117 return SemaRef.Owned(S->Retain());
3118
3119 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003120 S->getStartLoc(), S->getEndLoc());
3121}
Mike Stump11289f42009-09-09 15:08:12 +00003122
Douglas Gregorebe10102009-08-20 07:17:43 +00003123template<typename Derived>
3124Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003125TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003126 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003127 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003128}
3129
3130template<typename Derived>
3131Sema::OwningStmtResult
3132TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3133 // FIXME: Implement!
3134 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003135 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003136}
3137
3138
3139template<typename Derived>
3140Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003141TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003142 // FIXME: Implement this
3143 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003144 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003145}
Mike Stump11289f42009-09-09 15:08:12 +00003146
Douglas Gregorebe10102009-08-20 07:17:43 +00003147template<typename Derived>
3148Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003149TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003150 // FIXME: Implement this
3151 assert(false && "Cannot transform an Objective-C @catch statement");
3152 return SemaRef.Owned(S->Retain());
3153}
Mike Stump11289f42009-09-09 15:08:12 +00003154
Douglas Gregorebe10102009-08-20 07:17:43 +00003155template<typename Derived>
3156Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003157TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003158 // FIXME: Implement this
3159 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003160 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003161}
Mike Stump11289f42009-09-09 15:08:12 +00003162
Douglas Gregorebe10102009-08-20 07:17:43 +00003163template<typename Derived>
3164Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003165TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003166 // FIXME: Implement this
3167 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003168 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003169}
Mike Stump11289f42009-09-09 15:08:12 +00003170
Douglas Gregorebe10102009-08-20 07:17:43 +00003171template<typename Derived>
3172Sema::OwningStmtResult
3173TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003174 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003175 // FIXME: Implement this
3176 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003177 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003178}
3179
3180template<typename Derived>
3181Sema::OwningStmtResult
3182TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003183 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003184 // FIXME: Implement this
3185 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003186 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003187}
3188
3189
3190template<typename Derived>
3191Sema::OwningStmtResult
3192TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3193 // Transform the exception declaration, if any.
3194 VarDecl *Var = 0;
3195 if (S->getExceptionDecl()) {
3196 VarDecl *ExceptionDecl = S->getExceptionDecl();
3197 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3198 ExceptionDecl->getDeclName());
3199
3200 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3201 if (T.isNull())
3202 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003203
Douglas Gregorebe10102009-08-20 07:17:43 +00003204 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3205 T,
3206 ExceptionDecl->getDeclaratorInfo(),
3207 ExceptionDecl->getIdentifier(),
3208 ExceptionDecl->getLocation(),
3209 /*FIXME: Inaccurate*/
3210 SourceRange(ExceptionDecl->getLocation()));
3211 if (!Var || Var->isInvalidDecl()) {
3212 if (Var)
3213 Var->Destroy(SemaRef.Context);
3214 return SemaRef.StmtError();
3215 }
3216 }
Mike Stump11289f42009-09-09 15:08:12 +00003217
Douglas Gregorebe10102009-08-20 07:17:43 +00003218 // Transform the actual exception handler.
3219 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3220 if (Handler.isInvalid()) {
3221 if (Var)
3222 Var->Destroy(SemaRef.Context);
3223 return SemaRef.StmtError();
3224 }
Mike Stump11289f42009-09-09 15:08:12 +00003225
Douglas Gregorebe10102009-08-20 07:17:43 +00003226 if (!getDerived().AlwaysRebuild() &&
3227 !Var &&
3228 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003229 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003230
3231 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3232 Var,
3233 move(Handler));
3234}
Mike Stump11289f42009-09-09 15:08:12 +00003235
Douglas Gregorebe10102009-08-20 07:17:43 +00003236template<typename Derived>
3237Sema::OwningStmtResult
3238TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3239 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003240 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003241 = getDerived().TransformCompoundStmt(S->getTryBlock());
3242 if (TryBlock.isInvalid())
3243 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003244
Douglas Gregorebe10102009-08-20 07:17:43 +00003245 // Transform the handlers.
3246 bool HandlerChanged = false;
3247 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3248 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003249 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003250 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3251 if (Handler.isInvalid())
3252 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003253
Douglas Gregorebe10102009-08-20 07:17:43 +00003254 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3255 Handlers.push_back(Handler.takeAs<Stmt>());
3256 }
Mike Stump11289f42009-09-09 15:08:12 +00003257
Douglas Gregorebe10102009-08-20 07:17:43 +00003258 if (!getDerived().AlwaysRebuild() &&
3259 TryBlock.get() == S->getTryBlock() &&
3260 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003261 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003262
3263 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003264 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003265}
Mike Stump11289f42009-09-09 15:08:12 +00003266
Douglas Gregorebe10102009-08-20 07:17:43 +00003267//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003268// Expression transformation
3269//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003270template<typename Derived>
3271Sema::OwningExprResult
3272TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
3273 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003274}
Mike Stump11289f42009-09-09 15:08:12 +00003275
3276template<typename Derived>
3277Sema::OwningExprResult
3278TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
3279 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003280 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3281 if (!ND)
3282 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003283
Douglas Gregora16548e2009-08-11 05:31:07 +00003284 if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003285 return SemaRef.Owned(E->Retain());
3286
Douglas Gregora16548e2009-08-11 05:31:07 +00003287 return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
3288}
Mike Stump11289f42009-09-09 15:08:12 +00003289
Douglas Gregora16548e2009-08-11 05:31:07 +00003290template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003291Sema::OwningExprResult
3292TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
3293 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003294}
Mike Stump11289f42009-09-09 15:08:12 +00003295
Douglas Gregora16548e2009-08-11 05:31:07 +00003296template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003297Sema::OwningExprResult
3298TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
3299 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003300}
Mike Stump11289f42009-09-09 15:08:12 +00003301
Douglas Gregora16548e2009-08-11 05:31:07 +00003302template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003303Sema::OwningExprResult
3304TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
3305 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003306}
Mike Stump11289f42009-09-09 15:08:12 +00003307
Douglas Gregora16548e2009-08-11 05:31:07 +00003308template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003309Sema::OwningExprResult
3310TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
3311 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003312}
Mike Stump11289f42009-09-09 15:08:12 +00003313
Douglas Gregora16548e2009-08-11 05:31:07 +00003314template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003315Sema::OwningExprResult
3316TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
3317 return SemaRef.Owned(E->Retain());
3318}
3319
3320template<typename Derived>
3321Sema::OwningExprResult
3322TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003323 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3324 if (SubExpr.isInvalid())
3325 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003326
Douglas Gregora16548e2009-08-11 05:31:07 +00003327 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003328 return SemaRef.Owned(E->Retain());
3329
3330 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003331 E->getRParen());
3332}
3333
Mike Stump11289f42009-09-09 15:08:12 +00003334template<typename Derived>
3335Sema::OwningExprResult
3336TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003337 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3338 if (SubExpr.isInvalid())
3339 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003340
Douglas Gregora16548e2009-08-11 05:31:07 +00003341 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003342 return SemaRef.Owned(E->Retain());
3343
Douglas Gregora16548e2009-08-11 05:31:07 +00003344 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3345 E->getOpcode(),
3346 move(SubExpr));
3347}
Mike Stump11289f42009-09-09 15:08:12 +00003348
Douglas Gregora16548e2009-08-11 05:31:07 +00003349template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003350Sema::OwningExprResult
3351TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003352 if (E->isArgumentType()) {
3353 QualType T = getDerived().TransformType(E->getArgumentType());
3354 if (T.isNull())
3355 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003356
Douglas Gregora16548e2009-08-11 05:31:07 +00003357 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3358 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003359
3360 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3361 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003362 E->getSourceRange());
3363 }
Mike Stump11289f42009-09-09 15:08:12 +00003364
Douglas Gregora16548e2009-08-11 05:31:07 +00003365 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003366 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003367 // C++0x [expr.sizeof]p1:
3368 // The operand is either an expression, which is an unevaluated operand
3369 // [...]
3370 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003371
Douglas Gregora16548e2009-08-11 05:31:07 +00003372 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3373 if (SubExpr.isInvalid())
3374 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003375
Douglas Gregora16548e2009-08-11 05:31:07 +00003376 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3377 return SemaRef.Owned(E->Retain());
3378 }
Mike Stump11289f42009-09-09 15:08:12 +00003379
Douglas Gregora16548e2009-08-11 05:31:07 +00003380 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3381 E->isSizeOf(),
3382 E->getSourceRange());
3383}
Mike Stump11289f42009-09-09 15:08:12 +00003384
Douglas Gregora16548e2009-08-11 05:31:07 +00003385template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003386Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003387TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3388 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3389 if (LHS.isInvalid())
3390 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003391
Douglas Gregora16548e2009-08-11 05:31:07 +00003392 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3393 if (RHS.isInvalid())
3394 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003395
3396
Douglas Gregora16548e2009-08-11 05:31:07 +00003397 if (!getDerived().AlwaysRebuild() &&
3398 LHS.get() == E->getLHS() &&
3399 RHS.get() == E->getRHS())
3400 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003401
Douglas Gregora16548e2009-08-11 05:31:07 +00003402 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3403 /*FIXME:*/E->getLHS()->getLocStart(),
3404 move(RHS),
3405 E->getRBracketLoc());
3406}
Mike Stump11289f42009-09-09 15:08:12 +00003407
3408template<typename Derived>
3409Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003410TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3411 // Transform the callee.
3412 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3413 if (Callee.isInvalid())
3414 return SemaRef.ExprError();
3415
3416 // Transform arguments.
3417 bool ArgChanged = false;
3418 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3419 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3420 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3421 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3422 if (Arg.isInvalid())
3423 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003424
Douglas Gregora16548e2009-08-11 05:31:07 +00003425 // FIXME: Wrong source location information for the ','.
3426 FakeCommaLocs.push_back(
3427 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003428
3429 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003430 Args.push_back(Arg.takeAs<Expr>());
3431 }
Mike Stump11289f42009-09-09 15:08:12 +00003432
Douglas Gregora16548e2009-08-11 05:31:07 +00003433 if (!getDerived().AlwaysRebuild() &&
3434 Callee.get() == E->getCallee() &&
3435 !ArgChanged)
3436 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003437
Douglas Gregora16548e2009-08-11 05:31:07 +00003438 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003439 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003440 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3441 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3442 move_arg(Args),
3443 FakeCommaLocs.data(),
3444 E->getRParenLoc());
3445}
Mike Stump11289f42009-09-09 15:08:12 +00003446
3447template<typename Derived>
3448Sema::OwningExprResult
3449TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003450 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3451 if (Base.isInvalid())
3452 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003453
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003454 NestedNameSpecifier *Qualifier = 0;
3455 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003456 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003457 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3458 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003459 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003460 return SemaRef.ExprError();
3461 }
Mike Stump11289f42009-09-09 15:08:12 +00003462
3463 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003464 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3465 if (!Member)
3466 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003467
Douglas Gregora16548e2009-08-11 05:31:07 +00003468 if (!getDerived().AlwaysRebuild() &&
3469 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003470 Qualifier == E->getQualifier() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00003471 Member == E->getMemberDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003472 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003473
3474 // FIXME: Bogus source location for the operator
3475 SourceLocation FakeOperatorLoc
3476 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3477
3478 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3479 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003480 Qualifier,
3481 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003482 E->getMemberLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003483 Member);
Douglas Gregora16548e2009-08-11 05:31:07 +00003484}
Mike Stump11289f42009-09-09 15:08:12 +00003485
Douglas Gregora16548e2009-08-11 05:31:07 +00003486template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003487Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003488TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3489 assert(false && "Cannot transform abstract class");
3490 return SemaRef.Owned(E->Retain());
3491}
3492
3493template<typename Derived>
3494Sema::OwningExprResult
3495TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003496 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3497 if (LHS.isInvalid())
3498 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003499
Douglas Gregora16548e2009-08-11 05:31:07 +00003500 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3501 if (RHS.isInvalid())
3502 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003503
Douglas Gregora16548e2009-08-11 05:31:07 +00003504 if (!getDerived().AlwaysRebuild() &&
3505 LHS.get() == E->getLHS() &&
3506 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003507 return SemaRef.Owned(E->Retain());
3508
Douglas Gregora16548e2009-08-11 05:31:07 +00003509 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3510 move(LHS), move(RHS));
3511}
3512
Mike Stump11289f42009-09-09 15:08:12 +00003513template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003514Sema::OwningExprResult
3515TreeTransform<Derived>::TransformCompoundAssignOperator(
3516 CompoundAssignOperator *E) {
3517 return getDerived().TransformBinaryOperator(E);
3518}
Mike Stump11289f42009-09-09 15:08:12 +00003519
Douglas Gregora16548e2009-08-11 05:31:07 +00003520template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003521Sema::OwningExprResult
3522TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003523 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3524 if (Cond.isInvalid())
3525 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003526
Douglas Gregora16548e2009-08-11 05:31:07 +00003527 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3528 if (LHS.isInvalid())
3529 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003530
Douglas Gregora16548e2009-08-11 05:31:07 +00003531 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3532 if (RHS.isInvalid())
3533 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003534
Douglas Gregora16548e2009-08-11 05:31:07 +00003535 if (!getDerived().AlwaysRebuild() &&
3536 Cond.get() == E->getCond() &&
3537 LHS.get() == E->getLHS() &&
3538 RHS.get() == E->getRHS())
3539 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003540
3541 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003542 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003543 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003544 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003545 move(RHS));
3546}
Mike Stump11289f42009-09-09 15:08:12 +00003547
3548template<typename Derived>
3549Sema::OwningExprResult
3550TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003551 QualType T = getDerived().TransformType(E->getType());
3552 if (T.isNull())
3553 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003554
Douglas Gregora16548e2009-08-11 05:31:07 +00003555 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3556 if (SubExpr.isInvalid())
3557 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003558
Douglas Gregora16548e2009-08-11 05:31:07 +00003559 if (!getDerived().AlwaysRebuild() &&
3560 T == E->getType() &&
3561 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003562 return SemaRef.Owned(E->Retain());
3563
Douglas Gregora16548e2009-08-11 05:31:07 +00003564 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003565 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003566 E->isLvalueCast());
3567}
Mike Stump11289f42009-09-09 15:08:12 +00003568
Douglas Gregora16548e2009-08-11 05:31:07 +00003569template<typename Derived>
3570Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003571TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3572 assert(false && "Cannot transform abstract class");
3573 return SemaRef.Owned(E->Retain());
3574}
3575
3576template<typename Derived>
3577Sema::OwningExprResult
3578TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003579 QualType T;
3580 {
3581 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003582 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003583 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3584 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003585
Douglas Gregora16548e2009-08-11 05:31:07 +00003586 T = getDerived().TransformType(E->getTypeAsWritten());
3587 if (T.isNull())
3588 return SemaRef.ExprError();
3589 }
Mike Stump11289f42009-09-09 15:08:12 +00003590
Douglas Gregora16548e2009-08-11 05:31:07 +00003591 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3592 if (SubExpr.isInvalid())
3593 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003594
Douglas Gregora16548e2009-08-11 05:31:07 +00003595 if (!getDerived().AlwaysRebuild() &&
3596 T == E->getTypeAsWritten() &&
3597 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003598 return SemaRef.Owned(E->Retain());
3599
Douglas Gregora16548e2009-08-11 05:31:07 +00003600 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3601 E->getRParenLoc(),
3602 move(SubExpr));
3603}
Mike Stump11289f42009-09-09 15:08:12 +00003604
Douglas Gregora16548e2009-08-11 05:31:07 +00003605template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003606Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003607TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3608 QualType T;
3609 {
3610 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003611 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003612 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3613 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003614
Douglas Gregora16548e2009-08-11 05:31:07 +00003615 T = getDerived().TransformType(E->getType());
3616 if (T.isNull())
3617 return SemaRef.ExprError();
3618 }
Mike Stump11289f42009-09-09 15:08:12 +00003619
Douglas Gregora16548e2009-08-11 05:31:07 +00003620 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3621 if (Init.isInvalid())
3622 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003623
Douglas Gregora16548e2009-08-11 05:31:07 +00003624 if (!getDerived().AlwaysRebuild() &&
3625 T == E->getType() &&
3626 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003627 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003628
3629 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3630 /*FIXME:*/E->getInitializer()->getLocEnd(),
3631 move(Init));
3632}
Mike Stump11289f42009-09-09 15:08:12 +00003633
Douglas Gregora16548e2009-08-11 05:31:07 +00003634template<typename Derived>
3635Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003636TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003637 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3638 if (Base.isInvalid())
3639 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003640
Douglas Gregora16548e2009-08-11 05:31:07 +00003641 if (!getDerived().AlwaysRebuild() &&
3642 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003643 return SemaRef.Owned(E->Retain());
3644
Douglas Gregora16548e2009-08-11 05:31:07 +00003645 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003646 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003647 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3648 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3649 E->getAccessorLoc(),
3650 E->getAccessor());
3651}
Mike Stump11289f42009-09-09 15:08:12 +00003652
Douglas Gregora16548e2009-08-11 05:31:07 +00003653template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003654Sema::OwningExprResult
3655TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003656 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003657
Douglas Gregora16548e2009-08-11 05:31:07 +00003658 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3659 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3660 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3661 if (Init.isInvalid())
3662 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003663
Douglas Gregora16548e2009-08-11 05:31:07 +00003664 InitChanged = InitChanged || Init.get() != E->getInit(I);
3665 Inits.push_back(Init.takeAs<Expr>());
3666 }
Mike Stump11289f42009-09-09 15:08:12 +00003667
Douglas Gregora16548e2009-08-11 05:31:07 +00003668 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003669 return SemaRef.Owned(E->Retain());
3670
Douglas Gregora16548e2009-08-11 05:31:07 +00003671 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3672 E->getRBraceLoc());
3673}
Mike Stump11289f42009-09-09 15:08:12 +00003674
Douglas Gregora16548e2009-08-11 05:31:07 +00003675template<typename Derived>
3676Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003677TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003678 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003679
Douglas Gregorebe10102009-08-20 07:17:43 +00003680 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003681 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3682 if (Init.isInvalid())
3683 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003684
Douglas Gregorebe10102009-08-20 07:17:43 +00003685 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003686 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3687 bool ExprChanged = false;
3688 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3689 DEnd = E->designators_end();
3690 D != DEnd; ++D) {
3691 if (D->isFieldDesignator()) {
3692 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3693 D->getDotLoc(),
3694 D->getFieldLoc()));
3695 continue;
3696 }
Mike Stump11289f42009-09-09 15:08:12 +00003697
Douglas Gregora16548e2009-08-11 05:31:07 +00003698 if (D->isArrayDesignator()) {
3699 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3700 if (Index.isInvalid())
3701 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003702
3703 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003704 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003705
Douglas Gregora16548e2009-08-11 05:31:07 +00003706 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3707 ArrayExprs.push_back(Index.release());
3708 continue;
3709 }
Mike Stump11289f42009-09-09 15:08:12 +00003710
Douglas Gregora16548e2009-08-11 05:31:07 +00003711 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003712 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003713 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3714 if (Start.isInvalid())
3715 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003716
Douglas Gregora16548e2009-08-11 05:31:07 +00003717 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3718 if (End.isInvalid())
3719 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003720
3721 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003722 End.get(),
3723 D->getLBracketLoc(),
3724 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003725
Douglas Gregora16548e2009-08-11 05:31:07 +00003726 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3727 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003728
Douglas Gregora16548e2009-08-11 05:31:07 +00003729 ArrayExprs.push_back(Start.release());
3730 ArrayExprs.push_back(End.release());
3731 }
Mike Stump11289f42009-09-09 15:08:12 +00003732
Douglas Gregora16548e2009-08-11 05:31:07 +00003733 if (!getDerived().AlwaysRebuild() &&
3734 Init.get() == E->getInit() &&
3735 !ExprChanged)
3736 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003737
Douglas Gregora16548e2009-08-11 05:31:07 +00003738 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3739 E->getEqualOrColonLoc(),
3740 E->usesGNUSyntax(), move(Init));
3741}
Mike Stump11289f42009-09-09 15:08:12 +00003742
Douglas Gregora16548e2009-08-11 05:31:07 +00003743template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003744Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003745TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003746 ImplicitValueInitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003747 QualType T = getDerived().TransformType(E->getType());
3748 if (T.isNull())
3749 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003750
Douglas Gregora16548e2009-08-11 05:31:07 +00003751 if (!getDerived().AlwaysRebuild() &&
3752 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003753 return SemaRef.Owned(E->Retain());
3754
Douglas Gregora16548e2009-08-11 05:31:07 +00003755 return getDerived().RebuildImplicitValueInitExpr(T);
3756}
Mike Stump11289f42009-09-09 15:08:12 +00003757
Douglas Gregora16548e2009-08-11 05:31:07 +00003758template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003759Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003760TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3761 // FIXME: Do we want the type as written?
3762 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003763
Douglas Gregora16548e2009-08-11 05:31:07 +00003764 {
3765 // FIXME: Source location isn't quite accurate.
3766 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3767 T = getDerived().TransformType(E->getType());
3768 if (T.isNull())
3769 return SemaRef.ExprError();
3770 }
Mike Stump11289f42009-09-09 15:08:12 +00003771
Douglas Gregora16548e2009-08-11 05:31:07 +00003772 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3773 if (SubExpr.isInvalid())
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() &&
3778 SubExpr.get() == E->getSubExpr())
3779 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003780
Douglas Gregora16548e2009-08-11 05:31:07 +00003781 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3782 T, E->getRParenLoc());
3783}
3784
3785template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003786Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003787TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3788 bool ArgumentChanged = false;
3789 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3790 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3791 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3792 if (Init.isInvalid())
3793 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003794
Douglas Gregora16548e2009-08-11 05:31:07 +00003795 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3796 Inits.push_back(Init.takeAs<Expr>());
3797 }
Mike Stump11289f42009-09-09 15:08:12 +00003798
Douglas Gregora16548e2009-08-11 05:31:07 +00003799 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3800 move_arg(Inits),
3801 E->getRParenLoc());
3802}
Mike Stump11289f42009-09-09 15:08:12 +00003803
Douglas Gregora16548e2009-08-11 05:31:07 +00003804/// \brief Transform an address-of-label expression.
3805///
3806/// By default, the transformation of an address-of-label expression always
3807/// rebuilds the expression, so that the label identifier can be resolved to
3808/// the corresponding label statement by semantic analysis.
3809template<typename Derived>
3810Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003811TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003812 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3813 E->getLabel());
3814}
Mike Stump11289f42009-09-09 15:08:12 +00003815
3816template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003817Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00003818 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00003819 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3820 if (SubStmt.isInvalid())
3821 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003822
Douglas Gregora16548e2009-08-11 05:31:07 +00003823 if (!getDerived().AlwaysRebuild() &&
3824 SubStmt.get() == E->getSubStmt())
3825 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003826
3827 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003828 move(SubStmt),
3829 E->getRParenLoc());
3830}
Mike Stump11289f42009-09-09 15:08:12 +00003831
Douglas Gregora16548e2009-08-11 05:31:07 +00003832template<typename Derived>
3833Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003834TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003835 QualType T1, T2;
3836 {
3837 // FIXME: Source location isn't quite accurate.
3838 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003839
Douglas Gregora16548e2009-08-11 05:31:07 +00003840 T1 = getDerived().TransformType(E->getArgType1());
3841 if (T1.isNull())
3842 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003843
Douglas Gregora16548e2009-08-11 05:31:07 +00003844 T2 = getDerived().TransformType(E->getArgType2());
3845 if (T2.isNull())
3846 return SemaRef.ExprError();
3847 }
3848
3849 if (!getDerived().AlwaysRebuild() &&
3850 T1 == E->getArgType1() &&
3851 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00003852 return SemaRef.Owned(E->Retain());
3853
Douglas Gregora16548e2009-08-11 05:31:07 +00003854 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3855 T1, T2, E->getRParenLoc());
3856}
Mike Stump11289f42009-09-09 15:08:12 +00003857
Douglas Gregora16548e2009-08-11 05:31:07 +00003858template<typename Derived>
3859Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003860TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003861 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3862 if (Cond.isInvalid())
3863 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003864
Douglas Gregora16548e2009-08-11 05:31:07 +00003865 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3866 if (LHS.isInvalid())
3867 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003868
Douglas Gregora16548e2009-08-11 05:31:07 +00003869 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3870 if (RHS.isInvalid())
3871 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003872
Douglas Gregora16548e2009-08-11 05:31:07 +00003873 if (!getDerived().AlwaysRebuild() &&
3874 Cond.get() == E->getCond() &&
3875 LHS.get() == E->getLHS() &&
3876 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003877 return SemaRef.Owned(E->Retain());
3878
Douglas Gregora16548e2009-08-11 05:31:07 +00003879 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3880 move(Cond), move(LHS), move(RHS),
3881 E->getRParenLoc());
3882}
Mike Stump11289f42009-09-09 15:08:12 +00003883
Douglas Gregora16548e2009-08-11 05:31:07 +00003884template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003885Sema::OwningExprResult
3886TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3887 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003888}
3889
3890template<typename Derived>
3891Sema::OwningExprResult
3892TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3893 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3894 if (Callee.isInvalid())
3895 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003896
Douglas Gregora16548e2009-08-11 05:31:07 +00003897 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3898 if (First.isInvalid())
3899 return SemaRef.ExprError();
3900
3901 OwningExprResult Second(SemaRef);
3902 if (E->getNumArgs() == 2) {
3903 Second = getDerived().TransformExpr(E->getArg(1));
3904 if (Second.isInvalid())
3905 return SemaRef.ExprError();
3906 }
Mike Stump11289f42009-09-09 15:08:12 +00003907
Douglas Gregora16548e2009-08-11 05:31:07 +00003908 if (!getDerived().AlwaysRebuild() &&
3909 Callee.get() == E->getCallee() &&
3910 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00003911 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3912 return SemaRef.Owned(E->Retain());
3913
Douglas Gregora16548e2009-08-11 05:31:07 +00003914 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3915 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003916 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00003917 move(First),
3918 move(Second));
3919}
Mike Stump11289f42009-09-09 15:08:12 +00003920
Douglas Gregora16548e2009-08-11 05:31:07 +00003921template<typename Derived>
3922Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003923TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003924 return getDerived().TransformCallExpr(E);
3925}
Mike Stump11289f42009-09-09 15:08:12 +00003926
Douglas Gregora16548e2009-08-11 05:31:07 +00003927template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003928Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003929TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3930 QualType ExplicitTy;
3931 {
3932 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003933 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003934 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3935 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003936
Douglas Gregora16548e2009-08-11 05:31:07 +00003937 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3938 if (ExplicitTy.isNull())
3939 return SemaRef.ExprError();
3940 }
Mike Stump11289f42009-09-09 15:08:12 +00003941
Douglas Gregora16548e2009-08-11 05:31:07 +00003942 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3943 if (SubExpr.isInvalid())
3944 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003945
Douglas Gregora16548e2009-08-11 05:31:07 +00003946 if (!getDerived().AlwaysRebuild() &&
3947 ExplicitTy == E->getTypeAsWritten() &&
3948 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003949 return SemaRef.Owned(E->Retain());
3950
Douglas Gregora16548e2009-08-11 05:31:07 +00003951 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00003952 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003953 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3954 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3955 SourceLocation FakeRParenLoc
3956 = SemaRef.PP.getLocForEndOfToken(
3957 E->getSubExpr()->getSourceRange().getEnd());
3958 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003959 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003960 FakeLAngleLoc,
3961 ExplicitTy,
3962 FakeRAngleLoc,
3963 FakeRAngleLoc,
3964 move(SubExpr),
3965 FakeRParenLoc);
3966}
Mike Stump11289f42009-09-09 15:08:12 +00003967
Douglas Gregora16548e2009-08-11 05:31:07 +00003968template<typename Derived>
3969Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003970TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003971 return getDerived().TransformCXXNamedCastExpr(E);
3972}
Mike Stump11289f42009-09-09 15:08:12 +00003973
3974template<typename Derived>
3975Sema::OwningExprResult
3976TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
3977 return getDerived().TransformCXXNamedCastExpr(E);
3978}
3979
Douglas Gregora16548e2009-08-11 05:31:07 +00003980template<typename Derived>
3981Sema::OwningExprResult
3982TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003983 CXXReinterpretCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003984 return getDerived().TransformCXXNamedCastExpr(E);
3985}
Mike Stump11289f42009-09-09 15:08:12 +00003986
Douglas Gregora16548e2009-08-11 05:31:07 +00003987template<typename Derived>
3988Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003989TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003990 return getDerived().TransformCXXNamedCastExpr(E);
3991}
Mike Stump11289f42009-09-09 15:08:12 +00003992
Douglas Gregora16548e2009-08-11 05:31:07 +00003993template<typename Derived>
3994Sema::OwningExprResult
3995TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003996 CXXFunctionalCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003997 QualType ExplicitTy;
3998 {
3999 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004000
Douglas Gregora16548e2009-08-11 05:31:07 +00004001 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4002 if (ExplicitTy.isNull())
4003 return SemaRef.ExprError();
4004 }
Mike Stump11289f42009-09-09 15:08:12 +00004005
Douglas Gregora16548e2009-08-11 05:31:07 +00004006 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4007 if (SubExpr.isInvalid())
4008 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004009
Douglas Gregora16548e2009-08-11 05:31:07 +00004010 if (!getDerived().AlwaysRebuild() &&
4011 ExplicitTy == E->getTypeAsWritten() &&
4012 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004013 return SemaRef.Owned(E->Retain());
4014
Douglas Gregora16548e2009-08-11 05:31:07 +00004015 // FIXME: The end of the type's source range is wrong
4016 return getDerived().RebuildCXXFunctionalCastExpr(
4017 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4018 ExplicitTy,
4019 /*FIXME:*/E->getSubExpr()->getLocStart(),
4020 move(SubExpr),
4021 E->getRParenLoc());
4022}
Mike Stump11289f42009-09-09 15:08:12 +00004023
Douglas Gregora16548e2009-08-11 05:31:07 +00004024template<typename Derived>
4025Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004026TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004027 if (E->isTypeOperand()) {
4028 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004029
Douglas Gregora16548e2009-08-11 05:31:07 +00004030 QualType T = getDerived().TransformType(E->getTypeOperand());
4031 if (T.isNull())
4032 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004033
Douglas Gregora16548e2009-08-11 05:31:07 +00004034 if (!getDerived().AlwaysRebuild() &&
4035 T == E->getTypeOperand())
4036 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004037
Douglas Gregora16548e2009-08-11 05:31:07 +00004038 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4039 /*FIXME:*/E->getLocStart(),
4040 T,
4041 E->getLocEnd());
4042 }
Mike Stump11289f42009-09-09 15:08:12 +00004043
Douglas Gregora16548e2009-08-11 05:31:07 +00004044 // We don't know whether the expression is potentially evaluated until
4045 // after we perform semantic analysis, so the expression is potentially
4046 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004047 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004048 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004049
Douglas Gregora16548e2009-08-11 05:31:07 +00004050 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4051 if (SubExpr.isInvalid())
4052 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004053
Douglas Gregora16548e2009-08-11 05:31:07 +00004054 if (!getDerived().AlwaysRebuild() &&
4055 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004056 return SemaRef.Owned(E->Retain());
4057
Douglas Gregora16548e2009-08-11 05:31:07 +00004058 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4059 /*FIXME:*/E->getLocStart(),
4060 move(SubExpr),
4061 E->getLocEnd());
4062}
4063
4064template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004065Sema::OwningExprResult
4066TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
4067 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004068}
Mike Stump11289f42009-09-09 15:08:12 +00004069
Douglas Gregora16548e2009-08-11 05:31:07 +00004070template<typename Derived>
4071Sema::OwningExprResult
4072TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004073 CXXNullPtrLiteralExpr *E) {
4074 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004075}
Mike Stump11289f42009-09-09 15:08:12 +00004076
Douglas Gregora16548e2009-08-11 05:31:07 +00004077template<typename Derived>
4078Sema::OwningExprResult
4079TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
4080 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004081
Douglas Gregora16548e2009-08-11 05:31:07 +00004082 QualType T = getDerived().TransformType(E->getType());
4083 if (T.isNull())
4084 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004085
Douglas Gregora16548e2009-08-11 05:31:07 +00004086 if (!getDerived().AlwaysRebuild() &&
4087 T == E->getType())
4088 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004089
Douglas Gregora16548e2009-08-11 05:31:07 +00004090 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4091}
Mike Stump11289f42009-09-09 15:08:12 +00004092
Douglas Gregora16548e2009-08-11 05:31:07 +00004093template<typename Derived>
4094Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004095TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004096 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4097 if (SubExpr.isInvalid())
4098 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004099
Douglas Gregora16548e2009-08-11 05:31:07 +00004100 if (!getDerived().AlwaysRebuild() &&
4101 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004102 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004103
4104 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4105}
Mike Stump11289f42009-09-09 15:08:12 +00004106
Douglas Gregora16548e2009-08-11 05:31:07 +00004107template<typename Derived>
4108Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004109TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
4110 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004111 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4112 if (!Param)
4113 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004114
Douglas Gregora16548e2009-08-11 05:31:07 +00004115 if (getDerived().AlwaysRebuild() &&
4116 Param == E->getParam())
4117 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004118
Douglas Gregora16548e2009-08-11 05:31:07 +00004119 return getDerived().RebuildCXXDefaultArgExpr(Param);
4120}
Mike Stump11289f42009-09-09 15:08:12 +00004121
Douglas Gregora16548e2009-08-11 05:31:07 +00004122template<typename Derived>
4123Sema::OwningExprResult
4124TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
4125 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4126
4127 QualType T = getDerived().TransformType(E->getType());
4128 if (T.isNull())
4129 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004130
Douglas Gregora16548e2009-08-11 05:31:07 +00004131 if (!getDerived().AlwaysRebuild() &&
4132 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004133 return SemaRef.Owned(E->Retain());
4134
4135 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004136 /*FIXME:*/E->getTypeBeginLoc(),
4137 T,
4138 E->getRParenLoc());
4139}
Mike Stump11289f42009-09-09 15:08:12 +00004140
Douglas Gregora16548e2009-08-11 05:31:07 +00004141template<typename Derived>
4142Sema::OwningExprResult
4143TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00004144 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004145 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004146 if (!Var)
4147 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004148
Douglas Gregora16548e2009-08-11 05:31:07 +00004149 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004150 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004151 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004152
4153 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004154 /*FIXME:*/E->getStartLoc(),
4155 Var);
4156}
Mike Stump11289f42009-09-09 15:08:12 +00004157
Douglas Gregora16548e2009-08-11 05:31:07 +00004158template<typename Derived>
4159Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004160TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004161 // Transform the type that we're allocating
4162 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4163 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4164 if (AllocType.isNull())
4165 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004166
Douglas Gregora16548e2009-08-11 05:31:07 +00004167 // Transform the size of the array we're allocating (if any).
4168 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4169 if (ArraySize.isInvalid())
4170 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004171
Douglas Gregora16548e2009-08-11 05:31:07 +00004172 // Transform the placement arguments (if any).
4173 bool ArgumentChanged = false;
4174 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4175 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4176 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4177 if (Arg.isInvalid())
4178 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004179
Douglas Gregora16548e2009-08-11 05:31:07 +00004180 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4181 PlacementArgs.push_back(Arg.take());
4182 }
Mike Stump11289f42009-09-09 15:08:12 +00004183
Douglas Gregorebe10102009-08-20 07:17:43 +00004184 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004185 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4186 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4187 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4188 if (Arg.isInvalid())
4189 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004190
Douglas Gregora16548e2009-08-11 05:31:07 +00004191 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4192 ConstructorArgs.push_back(Arg.take());
4193 }
Mike Stump11289f42009-09-09 15:08:12 +00004194
Douglas Gregora16548e2009-08-11 05:31:07 +00004195 if (!getDerived().AlwaysRebuild() &&
4196 AllocType == E->getAllocatedType() &&
4197 ArraySize.get() == E->getArraySize() &&
4198 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004199 return SemaRef.Owned(E->Retain());
4200
Douglas Gregora16548e2009-08-11 05:31:07 +00004201 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4202 E->isGlobalNew(),
4203 /*FIXME:*/E->getLocStart(),
4204 move_arg(PlacementArgs),
4205 /*FIXME:*/E->getLocStart(),
4206 E->isParenTypeId(),
4207 AllocType,
4208 /*FIXME:*/E->getLocStart(),
4209 /*FIXME:*/SourceRange(),
4210 move(ArraySize),
4211 /*FIXME:*/E->getLocStart(),
4212 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004213 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004214}
Mike Stump11289f42009-09-09 15:08:12 +00004215
Douglas Gregora16548e2009-08-11 05:31:07 +00004216template<typename Derived>
4217Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004218TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004219 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4220 if (Operand.isInvalid())
4221 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004222
Douglas Gregora16548e2009-08-11 05:31:07 +00004223 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004224 Operand.get() == E->getArgument())
4225 return SemaRef.Owned(E->Retain());
4226
Douglas Gregora16548e2009-08-11 05:31:07 +00004227 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4228 E->isGlobalDelete(),
4229 E->isArrayForm(),
4230 move(Operand));
4231}
Mike Stump11289f42009-09-09 15:08:12 +00004232
Douglas Gregora16548e2009-08-11 05:31:07 +00004233template<typename Derived>
4234Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004235TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
4236 CXXPseudoDestructorExpr *E) {
4237 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4238 if (Base.isInvalid())
4239 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004240
Douglas Gregorad8a3362009-09-04 17:36:40 +00004241 NestedNameSpecifier *Qualifier
4242 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4243 E->getQualifierRange());
4244 if (E->getQualifier() && !Qualifier)
4245 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004246
Douglas Gregorad8a3362009-09-04 17:36:40 +00004247 QualType DestroyedType;
4248 {
4249 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4250 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4251 if (DestroyedType.isNull())
4252 return SemaRef.ExprError();
4253 }
Mike Stump11289f42009-09-09 15:08:12 +00004254
Douglas Gregorad8a3362009-09-04 17:36:40 +00004255 if (!getDerived().AlwaysRebuild() &&
4256 Base.get() == E->getBase() &&
4257 Qualifier == E->getQualifier() &&
4258 DestroyedType == E->getDestroyedType())
4259 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004260
Douglas Gregorad8a3362009-09-04 17:36:40 +00004261 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4262 E->getOperatorLoc(),
4263 E->isArrow(),
4264 E->getDestroyedTypeLoc(),
4265 DestroyedType,
4266 Qualifier,
4267 E->getQualifierRange());
4268}
Mike Stump11289f42009-09-09 15:08:12 +00004269
Douglas Gregorad8a3362009-09-04 17:36:40 +00004270template<typename Derived>
4271Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004272TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004273 UnresolvedFunctionNameExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004274 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004275 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004276}
Mike Stump11289f42009-09-09 15:08:12 +00004277
Douglas Gregora16548e2009-08-11 05:31:07 +00004278template<typename Derived>
4279Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004280TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004281 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004282
Douglas Gregora16548e2009-08-11 05:31:07 +00004283 QualType T = getDerived().TransformType(E->getQueriedType());
4284 if (T.isNull())
4285 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004286
Douglas Gregora16548e2009-08-11 05:31:07 +00004287 if (!getDerived().AlwaysRebuild() &&
4288 T == E->getQueriedType())
4289 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004290
Douglas Gregora16548e2009-08-11 05:31:07 +00004291 // FIXME: Bad location information
4292 SourceLocation FakeLParenLoc
4293 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004294
4295 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004296 E->getLocStart(),
4297 /*FIXME:*/FakeLParenLoc,
4298 T,
4299 E->getLocEnd());
4300}
Mike Stump11289f42009-09-09 15:08:12 +00004301
Douglas Gregora16548e2009-08-11 05:31:07 +00004302template<typename Derived>
4303Sema::OwningExprResult
4304TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
4305 NestedNameSpecifier *NNS
4306 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4307 E->getQualifierRange());
4308 if (!NNS)
4309 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004310
4311 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00004312 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
4313 if (!ND)
4314 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004315
4316 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004317 NNS == E->getQualifier() &&
4318 ND == E->getDecl())
Mike Stump11289f42009-09-09 15:08:12 +00004319 return SemaRef.Owned(E->Retain());
4320
4321 return getDerived().RebuildQualifiedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004322 E->getQualifierRange(),
4323 ND,
4324 E->getLocation(),
4325 /*FIXME:*/false);
4326}
Mike Stump11289f42009-09-09 15:08:12 +00004327
Douglas Gregora16548e2009-08-11 05:31:07 +00004328template<typename Derived>
4329Sema::OwningExprResult
4330TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004331 UnresolvedDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004332 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004333 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4334 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004335 if (!NNS)
4336 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004337
4338 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004339 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4340 if (!Name)
4341 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004342
4343 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004344 NNS == E->getQualifier() &&
4345 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004346 return SemaRef.Owned(E->Retain());
4347
4348 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004349 E->getQualifierRange(),
4350 Name,
4351 E->getLocation(),
4352 /*FIXME:*/false);
4353}
4354
4355template<typename Derived>
4356Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004357TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
4358 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004359 = getDerived().TransformTemplateName(E->getTemplateName());
4360 if (Template.isNull())
4361 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004362
Douglas Gregord019ff62009-10-22 17:20:55 +00004363 NestedNameSpecifier *Qualifier = 0;
4364 if (E->getQualifier()) {
4365 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4366 E->getQualifierRange());
4367 if (!Qualifier)
4368 return SemaRef.ExprError();
4369 }
4370
Douglas Gregora16548e2009-08-11 05:31:07 +00004371 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4372 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00004373 TemplateArgument TransArg
Douglas Gregora16548e2009-08-11 05:31:07 +00004374 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4375 if (TransArg.isNull())
4376 return SemaRef.ExprError();
4377
4378 TransArgs.push_back(TransArg);
4379 }
4380
4381 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4382 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004383
4384 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004385 // actually refers to a type, in which case the caller is actually dealing
4386 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004387 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4388 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004389 E->getLAngleLoc(),
4390 TransArgs.data(),
4391 TransArgs.size(),
4392 E->getRAngleLoc());
4393}
4394
4395template<typename Derived>
4396Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004397TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004398 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4399
4400 QualType T = getDerived().TransformType(E->getType());
4401 if (T.isNull())
4402 return SemaRef.ExprError();
4403
4404 CXXConstructorDecl *Constructor
4405 = cast_or_null<CXXConstructorDecl>(
4406 getDerived().TransformDecl(E->getConstructor()));
4407 if (!Constructor)
4408 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004409
Douglas Gregora16548e2009-08-11 05:31:07 +00004410 bool ArgumentChanged = false;
4411 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004412 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004413 ArgEnd = E->arg_end();
4414 Arg != ArgEnd; ++Arg) {
4415 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4416 if (TransArg.isInvalid())
4417 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004418
Douglas Gregora16548e2009-08-11 05:31:07 +00004419 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4420 Args.push_back(TransArg.takeAs<Expr>());
4421 }
4422
4423 if (!getDerived().AlwaysRebuild() &&
4424 T == E->getType() &&
4425 Constructor == E->getConstructor() &&
4426 !ArgumentChanged)
4427 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004428
Douglas Gregora16548e2009-08-11 05:31:07 +00004429 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4430 move_arg(Args));
4431}
Mike Stump11289f42009-09-09 15:08:12 +00004432
Douglas Gregora16548e2009-08-11 05:31:07 +00004433/// \brief Transform a C++ temporary-binding expression.
4434///
Mike Stump11289f42009-09-09 15:08:12 +00004435/// The transformation of a temporary-binding expression always attempts to
4436/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004437/// subexpression itself did not change, because the temporary variable itself
4438/// must be unique.
4439template<typename Derived>
4440Sema::OwningExprResult
4441TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4442 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4443 if (SubExpr.isInvalid())
4444 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004445
Douglas Gregora16548e2009-08-11 05:31:07 +00004446 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4447}
Mike Stump11289f42009-09-09 15:08:12 +00004448
4449/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004450/// be destroyed after the expression is evaluated.
4451///
Mike Stump11289f42009-09-09 15:08:12 +00004452/// The transformation of a full expression always attempts to build a new
4453/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004454/// subexpression itself did not change, because it will need to capture the
4455/// the new temporary variables introduced in the subexpression.
4456template<typename Derived>
4457Sema::OwningExprResult
4458TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump11289f42009-09-09 15:08:12 +00004459 CXXExprWithTemporaries *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004460 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4461 if (SubExpr.isInvalid())
4462 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004463
Douglas Gregora16548e2009-08-11 05:31:07 +00004464 return SemaRef.Owned(
4465 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4466 E->shouldDestroyTemporaries()));
4467}
Mike Stump11289f42009-09-09 15:08:12 +00004468
Douglas Gregora16548e2009-08-11 05:31:07 +00004469template<typename Derived>
4470Sema::OwningExprResult
4471TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004472 CXXTemporaryObjectExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004473 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4474 QualType T = getDerived().TransformType(E->getType());
4475 if (T.isNull())
4476 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004477
Douglas Gregora16548e2009-08-11 05:31:07 +00004478 CXXConstructorDecl *Constructor
4479 = cast_or_null<CXXConstructorDecl>(
4480 getDerived().TransformDecl(E->getConstructor()));
4481 if (!Constructor)
4482 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004483
Douglas Gregora16548e2009-08-11 05:31:07 +00004484 bool ArgumentChanged = false;
4485 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4486 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004487 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004488 ArgEnd = E->arg_end();
4489 Arg != ArgEnd; ++Arg) {
4490 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4491 if (TransArg.isInvalid())
4492 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004493
Douglas Gregora16548e2009-08-11 05:31:07 +00004494 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4495 Args.push_back((Expr *)TransArg.release());
4496 }
Mike Stump11289f42009-09-09 15:08:12 +00004497
Douglas Gregora16548e2009-08-11 05:31:07 +00004498 if (!getDerived().AlwaysRebuild() &&
4499 T == E->getType() &&
4500 Constructor == E->getConstructor() &&
4501 !ArgumentChanged)
4502 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004503
Douglas Gregora16548e2009-08-11 05:31:07 +00004504 // FIXME: Bogus location information
4505 SourceLocation CommaLoc;
4506 if (Args.size() > 1) {
4507 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004508 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004509 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4510 }
4511 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4512 T,
4513 /*FIXME:*/E->getTypeBeginLoc(),
4514 move_arg(Args),
4515 &CommaLoc,
4516 E->getLocEnd());
4517}
Mike Stump11289f42009-09-09 15:08:12 +00004518
Douglas Gregora16548e2009-08-11 05:31:07 +00004519template<typename Derived>
4520Sema::OwningExprResult
4521TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004522 CXXUnresolvedConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004523 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4524 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4525 if (T.isNull())
4526 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004527
Douglas Gregora16548e2009-08-11 05:31:07 +00004528 bool ArgumentChanged = false;
4529 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4530 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4531 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4532 ArgEnd = E->arg_end();
4533 Arg != ArgEnd; ++Arg) {
4534 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4535 if (TransArg.isInvalid())
4536 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004537
Douglas Gregora16548e2009-08-11 05:31:07 +00004538 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4539 FakeCommaLocs.push_back(
4540 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4541 Args.push_back(TransArg.takeAs<Expr>());
4542 }
Mike Stump11289f42009-09-09 15:08:12 +00004543
Douglas Gregora16548e2009-08-11 05:31:07 +00004544 if (!getDerived().AlwaysRebuild() &&
4545 T == E->getTypeAsWritten() &&
4546 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004547 return SemaRef.Owned(E->Retain());
4548
Douglas Gregora16548e2009-08-11 05:31:07 +00004549 // FIXME: we're faking the locations of the commas
4550 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4551 T,
4552 E->getLParenLoc(),
4553 move_arg(Args),
4554 FakeCommaLocs.data(),
4555 E->getRParenLoc());
4556}
Mike Stump11289f42009-09-09 15:08:12 +00004557
Douglas Gregora16548e2009-08-11 05:31:07 +00004558template<typename Derived>
4559Sema::OwningExprResult
4560TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004561 CXXUnresolvedMemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004562 // Transform the base of the expression.
4563 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4564 if (Base.isInvalid())
4565 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004566
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004567 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004568 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004569 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004570 E->getOperatorLoc(),
4571 E->isArrow()? tok::arrow : tok::period,
4572 ObjectType);
4573 if (Base.isInvalid())
4574 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004575
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004576 // Transform the first part of the nested-name-specifier that qualifies
4577 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004578 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004579 = getDerived().TransformFirstQualifierInScope(
4580 E->getFirstQualifierFoundInScope(),
4581 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004582
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004583 NestedNameSpecifier *Qualifier = 0;
4584 if (E->getQualifier()) {
4585 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4586 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004587 QualType::getFromOpaquePtr(ObjectType),
4588 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004589 if (!Qualifier)
4590 return SemaRef.ExprError();
4591 }
Mike Stump11289f42009-09-09 15:08:12 +00004592
4593 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004594 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4595 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004596 if (!Name)
4597 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004598
Douglas Gregor308047d2009-09-09 00:23:06 +00004599 if (!E->hasExplicitTemplateArgumentList()) {
4600 // This is a reference to a member without an explicitly-specified
4601 // template argument list. Optimize for this common case.
4602 if (!getDerived().AlwaysRebuild() &&
4603 Base.get() == E->getBase() &&
4604 Qualifier == E->getQualifier() &&
4605 Name == E->getMember() &&
4606 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004607 return SemaRef.Owned(E->Retain());
4608
Douglas Gregor308047d2009-09-09 00:23:06 +00004609 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4610 E->isArrow(),
4611 E->getOperatorLoc(),
4612 Qualifier,
4613 E->getQualifierRange(),
4614 Name,
4615 E->getMemberLoc(),
4616 FirstQualifierInScope);
4617 }
4618
4619 // FIXME: This is an ugly hack, which forces the same template name to
4620 // be looked up multiple times. Yuck!
4621 // FIXME: This also won't work for, e.g., x->template operator+<int>
4622 TemplateName OrigTemplateName
4623 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump11289f42009-09-09 15:08:12 +00004624
4625 TemplateName Template
4626 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004627 QualType::getFromOpaquePtr(ObjectType));
4628 if (Template.isNull())
4629 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004630
Douglas Gregor308047d2009-09-09 00:23:06 +00004631 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4632 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00004633 TemplateArgument TransArg
Douglas Gregor308047d2009-09-09 00:23:06 +00004634 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4635 if (TransArg.isNull())
4636 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004637
Douglas Gregor308047d2009-09-09 00:23:06 +00004638 TransArgs.push_back(TransArg);
4639 }
Mike Stump11289f42009-09-09 15:08:12 +00004640
Douglas Gregora16548e2009-08-11 05:31:07 +00004641 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4642 E->isArrow(),
4643 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004644 Qualifier,
4645 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004646 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004647 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004648 FirstQualifierInScope,
4649 E->getLAngleLoc(),
4650 TransArgs.data(),
4651 TransArgs.size(),
4652 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004653}
4654
4655template<typename Derived>
4656Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004657TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4658 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004659}
4660
Mike Stump11289f42009-09-09 15:08:12 +00004661template<typename Derived>
4662Sema::OwningExprResult
4663TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004664 // FIXME: poor source location
4665 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4666 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4667 if (EncodedType.isNull())
4668 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004669
Douglas Gregora16548e2009-08-11 05:31:07 +00004670 if (!getDerived().AlwaysRebuild() &&
4671 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004672 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004673
4674 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4675 EncodedType,
4676 E->getRParenLoc());
4677}
Mike Stump11289f42009-09-09 15:08:12 +00004678
Douglas Gregora16548e2009-08-11 05:31:07 +00004679template<typename Derived>
4680Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004681TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004682 // FIXME: Implement this!
4683 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004684 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004685}
4686
Mike Stump11289f42009-09-09 15:08:12 +00004687template<typename Derived>
4688Sema::OwningExprResult
4689TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4690 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004691}
4692
Mike Stump11289f42009-09-09 15:08:12 +00004693template<typename Derived>
4694Sema::OwningExprResult
4695TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4696 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004697 = cast_or_null<ObjCProtocolDecl>(
4698 getDerived().TransformDecl(E->getProtocol()));
4699 if (!Protocol)
4700 return SemaRef.ExprError();
4701
4702 if (!getDerived().AlwaysRebuild() &&
4703 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004704 return SemaRef.Owned(E->Retain());
4705
Douglas Gregora16548e2009-08-11 05:31:07 +00004706 return getDerived().RebuildObjCProtocolExpr(Protocol,
4707 E->getAtLoc(),
4708 /*FIXME:*/E->getAtLoc(),
4709 /*FIXME:*/E->getAtLoc(),
4710 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004711
Douglas Gregora16548e2009-08-11 05:31:07 +00004712}
4713
Mike Stump11289f42009-09-09 15:08:12 +00004714template<typename Derived>
4715Sema::OwningExprResult
4716TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004717 // FIXME: Implement this!
4718 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004719 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004720}
4721
Mike Stump11289f42009-09-09 15:08:12 +00004722template<typename Derived>
4723Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004724TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4725 // FIXME: Implement this!
4726 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004727 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004728}
4729
Mike Stump11289f42009-09-09 15:08:12 +00004730template<typename Derived>
4731Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004732TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004733 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004734 // FIXME: Implement this!
4735 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004736 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004737}
4738
Mike Stump11289f42009-09-09 15:08:12 +00004739template<typename Derived>
4740Sema::OwningExprResult
4741TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004742 // FIXME: Implement this!
4743 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004744 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004745}
4746
Mike Stump11289f42009-09-09 15:08:12 +00004747template<typename Derived>
4748Sema::OwningExprResult
4749TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004750 // FIXME: Implement this!
4751 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004752 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004753}
4754
Mike Stump11289f42009-09-09 15:08:12 +00004755template<typename Derived>
4756Sema::OwningExprResult
4757TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004758 bool ArgumentChanged = false;
4759 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4760 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4761 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4762 if (SubExpr.isInvalid())
4763 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004764
Douglas Gregora16548e2009-08-11 05:31:07 +00004765 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4766 SubExprs.push_back(SubExpr.takeAs<Expr>());
4767 }
Mike Stump11289f42009-09-09 15:08:12 +00004768
Douglas Gregora16548e2009-08-11 05:31:07 +00004769 if (!getDerived().AlwaysRebuild() &&
4770 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004771 return SemaRef.Owned(E->Retain());
4772
Douglas Gregora16548e2009-08-11 05:31:07 +00004773 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4774 move_arg(SubExprs),
4775 E->getRParenLoc());
4776}
4777
Mike Stump11289f42009-09-09 15:08:12 +00004778template<typename Derived>
4779Sema::OwningExprResult
4780TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004781 // FIXME: Implement this!
4782 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004783 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004784}
4785
Mike Stump11289f42009-09-09 15:08:12 +00004786template<typename Derived>
4787Sema::OwningExprResult
4788TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004789 // FIXME: Implement this!
4790 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004791 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004792}
Mike Stump11289f42009-09-09 15:08:12 +00004793
Douglas Gregora16548e2009-08-11 05:31:07 +00004794//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00004795// Type reconstruction
4796//===----------------------------------------------------------------------===//
4797
Mike Stump11289f42009-09-09 15:08:12 +00004798template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004799QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004800 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004801 getDerived().getBaseLocation(),
4802 getDerived().getBaseEntity());
4803}
4804
Mike Stump11289f42009-09-09 15:08:12 +00004805template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004806QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004807 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004808 getDerived().getBaseLocation(),
4809 getDerived().getBaseEntity());
4810}
4811
Mike Stump11289f42009-09-09 15:08:12 +00004812template<typename Derived>
4813QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004814TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004815 return SemaRef.BuildReferenceType(ReferentType, true, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004816 getDerived().getBaseLocation(),
4817 getDerived().getBaseEntity());
4818}
4819
4820template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004821QualType
4822TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004823 return SemaRef.BuildReferenceType(ReferentType, false, Qualifiers(),
Mike Stump11289f42009-09-09 15:08:12 +00004824 getDerived().getBaseLocation(),
4825 getDerived().getBaseEntity());
4826}
4827
4828template<typename Derived>
4829QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004830 QualType ClassType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004831 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004832 getDerived().getBaseLocation(),
4833 getDerived().getBaseEntity());
4834}
4835
4836template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004837QualType
John McCall550e0c22009-10-21 00:40:46 +00004838TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType) {
4839 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
4840 getDerived().getBaseLocation(),
4841 getDerived().getBaseEntity());
4842}
4843
4844template<typename Derived>
4845QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004846TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4847 ArrayType::ArraySizeModifier SizeMod,
4848 const llvm::APInt *Size,
4849 Expr *SizeExpr,
4850 unsigned IndexTypeQuals,
4851 SourceRange BracketsRange) {
4852 if (SizeExpr || !Size)
4853 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4854 IndexTypeQuals, BracketsRange,
4855 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00004856
4857 QualType Types[] = {
4858 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4859 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4860 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00004861 };
4862 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4863 QualType SizeType;
4864 for (unsigned I = 0; I != NumTypes; ++I)
4865 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4866 SizeType = Types[I];
4867 break;
4868 }
Mike Stump11289f42009-09-09 15:08:12 +00004869
Douglas Gregord6ff3322009-08-04 16:50:30 +00004870 if (SizeType.isNull())
4871 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00004872
Douglas Gregord6ff3322009-08-04 16:50:30 +00004873 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004874 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004875 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00004876 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004877}
Mike Stump11289f42009-09-09 15:08:12 +00004878
Douglas Gregord6ff3322009-08-04 16:50:30 +00004879template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004880QualType
4881TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004882 ArrayType::ArraySizeModifier SizeMod,
4883 const llvm::APInt &Size,
4884 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004885 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004886 IndexTypeQuals, SourceRange());
4887}
4888
4889template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004890QualType
Mike Stump11289f42009-09-09 15:08:12 +00004891TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004892 ArrayType::ArraySizeModifier SizeMod,
4893 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004894 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004895 IndexTypeQuals, SourceRange());
4896}
Mike Stump11289f42009-09-09 15:08:12 +00004897
Douglas Gregord6ff3322009-08-04 16:50:30 +00004898template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004899QualType
4900TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004901 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00004902 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004903 unsigned IndexTypeQuals,
4904 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00004905 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004906 SizeExpr.takeAs<Expr>(),
4907 IndexTypeQuals, BracketsRange);
4908}
4909
4910template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004911QualType
4912TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004913 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00004914 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004915 unsigned IndexTypeQuals,
4916 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00004917 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004918 SizeExpr.takeAs<Expr>(),
4919 IndexTypeQuals, BracketsRange);
4920}
4921
4922template<typename Derived>
4923QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4924 unsigned NumElements) {
4925 // FIXME: semantic checking!
4926 return SemaRef.Context.getVectorType(ElementType, NumElements);
4927}
Mike Stump11289f42009-09-09 15:08:12 +00004928
Douglas Gregord6ff3322009-08-04 16:50:30 +00004929template<typename Derived>
4930QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4931 unsigned NumElements,
4932 SourceLocation AttributeLoc) {
4933 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4934 NumElements, true);
4935 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00004936 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004937 AttributeLoc);
4938 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4939 AttributeLoc);
4940}
Mike Stump11289f42009-09-09 15:08:12 +00004941
Douglas Gregord6ff3322009-08-04 16:50:30 +00004942template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004943QualType
4944TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00004945 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004946 SourceLocation AttributeLoc) {
4947 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4948}
Mike Stump11289f42009-09-09 15:08:12 +00004949
Douglas Gregord6ff3322009-08-04 16:50:30 +00004950template<typename Derived>
4951QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00004952 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004953 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00004954 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004955 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00004956 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004957 Quals,
4958 getDerived().getBaseLocation(),
4959 getDerived().getBaseEntity());
4960}
Mike Stump11289f42009-09-09 15:08:12 +00004961
Douglas Gregord6ff3322009-08-04 16:50:30 +00004962template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00004963QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
4964 return SemaRef.Context.getFunctionNoProtoType(T);
4965}
4966
4967template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00004968QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00004969 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4970}
4971
4972template<typename Derived>
4973QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4974 return SemaRef.Context.getTypeOfType(Underlying);
4975}
4976
4977template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00004978QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00004979 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4980}
4981
4982template<typename Derived>
4983QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4984 TemplateName Template,
4985 const TemplateArgument *Args,
4986 unsigned NumArgs) {
4987 // FIXME: Missing source locations for the template name, <, >.
4988 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
Mike Stump11289f42009-09-09 15:08:12 +00004989 SourceLocation(), Args, NumArgs,
4990 SourceLocation());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004991}
Mike Stump11289f42009-09-09 15:08:12 +00004992
Douglas Gregor1135c352009-08-06 05:28:30 +00004993template<typename Derived>
4994NestedNameSpecifier *
4995TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4996 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004997 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004998 QualType ObjectType,
4999 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00005000 CXXScopeSpec SS;
5001 // FIXME: The source location information is all wrong.
5002 SS.setRange(Range);
5003 SS.setScopeRep(Prefix);
5004 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005005 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005006 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005007 ObjectType,
5008 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005009 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005010}
5011
5012template<typename Derived>
5013NestedNameSpecifier *
5014TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5015 SourceRange Range,
5016 NamespaceDecl *NS) {
5017 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5018}
5019
5020template<typename Derived>
5021NestedNameSpecifier *
5022TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5023 SourceRange Range,
5024 bool TemplateKW,
5025 QualType T) {
5026 if (T->isDependentType() || T->isRecordType() ||
5027 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005028 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005029 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5030 T.getTypePtr());
5031 }
Mike Stump11289f42009-09-09 15:08:12 +00005032
Douglas Gregor1135c352009-08-06 05:28:30 +00005033 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5034 return 0;
5035}
Mike Stump11289f42009-09-09 15:08:12 +00005036
Douglas Gregor71dc5092009-08-06 06:41:21 +00005037template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005038TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005039TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5040 bool TemplateKW,
5041 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005042 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005043 Template);
5044}
5045
5046template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005047TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005048TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5049 bool TemplateKW,
5050 OverloadedFunctionDecl *Ovl) {
5051 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5052}
5053
5054template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005055TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005056TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005057 const IdentifierInfo &II,
5058 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005059 CXXScopeSpec SS;
5060 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005061 SS.setScopeRep(Qualifier);
Douglas Gregor308047d2009-09-09 00:23:06 +00005062 return getSema().ActOnDependentTemplateName(
5063 /*FIXME:*/getDerived().getBaseLocation(),
5064 II,
5065 /*FIXME:*/getDerived().getBaseLocation(),
5066 SS,
5067 ObjectType.getAsOpaquePtr())
5068 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005069}
Mike Stump11289f42009-09-09 15:08:12 +00005070
Douglas Gregora16548e2009-08-11 05:31:07 +00005071template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005072Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005073TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5074 SourceLocation OpLoc,
5075 ExprArg Callee,
5076 ExprArg First,
5077 ExprArg Second) {
5078 Expr *FirstExpr = (Expr *)First.get();
5079 Expr *SecondExpr = (Expr *)Second.get();
5080 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005081
Douglas Gregora16548e2009-08-11 05:31:07 +00005082 // Determine whether this should be a builtin operation.
5083 if (SecondExpr == 0 || isPostIncDec) {
5084 if (!FirstExpr->getType()->isOverloadableType()) {
5085 // The argument is not of overloadable type, so try to create a
5086 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005087 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005088 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005089
Douglas Gregora16548e2009-08-11 05:31:07 +00005090 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5091 }
5092 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005093 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005094 !SecondExpr->getType()->isOverloadableType()) {
5095 // Neither of the arguments is an overloadable type, so try to
5096 // create a built-in binary operation.
5097 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005098 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005099 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5100 if (Result.isInvalid())
5101 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005102
Douglas Gregora16548e2009-08-11 05:31:07 +00005103 First.release();
5104 Second.release();
5105 return move(Result);
5106 }
5107 }
Mike Stump11289f42009-09-09 15:08:12 +00005108
5109 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005110 // used during overload resolution.
5111 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005112
5113 DeclRefExpr *DRE
Douglas Gregor32e2c842009-09-01 16:58:52 +00005114 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Mike Stump11289f42009-09-09 15:08:12 +00005115
Douglas Gregora16548e2009-08-11 05:31:07 +00005116 // FIXME: Do we have to check
5117 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005118 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005119 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005120
Douglas Gregora16548e2009-08-11 05:31:07 +00005121 // Add any functions found via argument-dependent lookup.
5122 Expr *Args[2] = { FirstExpr, SecondExpr };
5123 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005124 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005125 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
5126 SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, 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