blob: ec5c6676f5d20cd192d122c3a2c0e8de31565353 [file] [log] [blame]
Douglas Gregor577f75a2009-08-04 16:50:30 +00001//===------- TreeTransform.h - Semantic Tree Transformation ---------------===/
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements a semantic tree transformation that takes a given
10// AST and rebuilds it, possibly transforming some nodes in the process.
11//
12//===----------------------------------------------------------------------===/
13#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_SEMA_TREETRANSFORM_H
15
16#include "Sema.h"
Douglas Gregordcee1a12009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregorc68afe22009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor657c1ac2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregor43959a92009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000025#include "clang/Parse/Ownership.h"
26#include "clang/Parse/Designator.h"
27#include "clang/Lex/Preprocessor.h"
Douglas Gregor577f75a2009-08-04 16:50:30 +000028#include <algorithm>
29
30namespace clang {
Mike Stump1eb44332009-09-09 15:08:12 +000031
Douglas Gregor577f75a2009-08-04 16:50:30 +000032/// \brief A semantic tree transformation that allows one to transform one
33/// abstract syntax tree into another.
34///
Mike Stump1eb44332009-09-09 15:08:12 +000035/// A new tree transformation is defined by creating a new subclass \c X of
36/// \c TreeTransform<X> and then overriding certain operations to provide
37/// behavior specific to that transformation. For example, template
Douglas Gregor577f75a2009-08-04 16:50:30 +000038/// instantiation is implemented as a tree transformation where the
39/// transformation of TemplateTypeParmType nodes involves substituting the
40/// template arguments for their corresponding template parameters; a similar
41/// transformation is performed for non-type template parameters and
42/// template template parameters.
43///
44/// This tree-transformation template uses static polymorphism to allow
Mike Stump1eb44332009-09-09 15:08:12 +000045/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregor577f75a2009-08-04 16:50:30 +000046/// override any of the transformation or rebuild operators by providing an
47/// operation with the same signature as the default implementation. The
48/// overridding function should not be virtual.
49///
50/// Semantic tree transformations are split into two stages, either of which
51/// can be replaced by a subclass. The "transform" step transforms an AST node
52/// or the parts of an AST node using the various transformation functions,
53/// then passes the pieces on to the "rebuild" step, which constructs a new AST
54/// node of the appropriate kind from the pieces. The default transformation
55/// routines recursively transform the operands to composite AST nodes (e.g.,
56/// the pointee type of a PointerType node) and, if any of those operand nodes
57/// were changed by the transformation, invokes the rebuild operation to create
58/// a new AST node.
59///
Mike Stump1eb44332009-09-09 15:08:12 +000060/// Subclasses can customize the transformation at various levels. The
Douglas Gregor670444e2009-08-04 22:27:00 +000061/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor577f75a2009-08-04 16:50:30 +000062/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
63/// TransformTemplateName(), or TransformTemplateArgument() with entirely
64/// new implementations.
65///
66/// For more fine-grained transformations, subclasses can replace any of the
67/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
Douglas Gregor43959a92009-08-20 07:17:43 +000068/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregor577f75a2009-08-04 16:50:30 +000069/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump1eb44332009-09-09 15:08:12 +000070/// to substitute template arguments for their corresponding template
Douglas Gregor577f75a2009-08-04 16:50:30 +000071/// parameters. Additionally, subclasses can override the \c RebuildXXX
72/// functions to control how AST nodes are rebuilt when their operands change.
73/// By default, \c TreeTransform will invoke semantic analysis to rebuild
74/// AST nodes. However, certain other tree transformations (e.g, cloning) may
75/// be able to use more efficient rebuild steps.
76///
77/// There are a handful of other functions that can be overridden, allowing one
Mike Stump1eb44332009-09-09 15:08:12 +000078/// to avoid traversing nodes that don't need any transformation
Douglas Gregor577f75a2009-08-04 16:50:30 +000079/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
80/// operands have not changed (\c AlwaysRebuild()), and customize the
81/// default locations and entity names used for type-checking
82/// (\c getBaseLocation(), \c getBaseEntity()).
Douglas Gregor577f75a2009-08-04 16:50:30 +000083template<typename Derived>
84class TreeTransform {
85protected:
86 Sema &SemaRef;
Mike Stump1eb44332009-09-09 15:08:12 +000087
88public:
Douglas Gregorb98b1992009-08-11 05:31:07 +000089 typedef Sema::OwningStmtResult OwningStmtResult;
90 typedef Sema::OwningExprResult OwningExprResult;
91 typedef Sema::StmtArg StmtArg;
92 typedef Sema::ExprArg ExprArg;
93 typedef Sema::MultiExprArg MultiExprArg;
Douglas Gregor43959a92009-08-20 07:17:43 +000094 typedef Sema::MultiStmtArg MultiStmtArg;
Mike Stump1eb44332009-09-09 15:08:12 +000095
Douglas Gregor577f75a2009-08-04 16:50:30 +000096 /// \brief Initializes a new tree transformer.
97 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump1eb44332009-09-09 15:08:12 +000098
Douglas Gregor577f75a2009-08-04 16:50:30 +000099 /// \brief Retrieves a reference to the derived class.
100 Derived &getDerived() { return static_cast<Derived&>(*this); }
101
102 /// \brief Retrieves a reference to the derived class.
Mike Stump1eb44332009-09-09 15:08:12 +0000103 const Derived &getDerived() const {
104 return static_cast<const Derived&>(*this);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000105 }
106
107 /// \brief Retrieves a reference to the semantic analysis object used for
108 /// this tree transform.
109 Sema &getSema() const { return SemaRef; }
Mike Stump1eb44332009-09-09 15:08:12 +0000110
Douglas Gregor577f75a2009-08-04 16:50:30 +0000111 /// \brief Whether the transformation should always rebuild AST nodes, even
112 /// if none of the children have changed.
113 ///
114 /// Subclasses may override this function to specify when the transformation
115 /// should rebuild all AST nodes.
116 bool AlwaysRebuild() { return false; }
Mike Stump1eb44332009-09-09 15:08:12 +0000117
Douglas Gregor577f75a2009-08-04 16:50:30 +0000118 /// \brief Returns the location of the entity being transformed, if that
119 /// information was not available elsewhere in the AST.
120 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000121 /// By default, returns no source-location information. Subclasses can
Douglas Gregor577f75a2009-08-04 16:50:30 +0000122 /// provide an alternative implementation that provides better location
123 /// information.
124 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump1eb44332009-09-09 15:08:12 +0000125
Douglas Gregor577f75a2009-08-04 16:50:30 +0000126 /// \brief Returns the name of the entity being transformed, if that
127 /// information was not available elsewhere in the AST.
128 ///
129 /// By default, returns an empty name. Subclasses can provide an alternative
130 /// implementation with a more precise name.
131 DeclarationName getBaseEntity() { return DeclarationName(); }
132
Douglas Gregorb98b1992009-08-11 05:31:07 +0000133 /// \brief Sets the "base" location and entity when that
134 /// information is known based on another transformation.
135 ///
136 /// By default, the source location and entity are ignored. Subclasses can
137 /// override this function to provide a customized implementation.
138 void setBase(SourceLocation Loc, DeclarationName Entity) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000139
Douglas Gregorb98b1992009-08-11 05:31:07 +0000140 /// \brief RAII object that temporarily sets the base location and entity
141 /// used for reporting diagnostics in types.
142 class TemporaryBase {
143 TreeTransform &Self;
144 SourceLocation OldLocation;
145 DeclarationName OldEntity;
Mike Stump1eb44332009-09-09 15:08:12 +0000146
Douglas Gregorb98b1992009-08-11 05:31:07 +0000147 public:
148 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump1eb44332009-09-09 15:08:12 +0000149 DeclarationName Entity) : Self(Self) {
Douglas Gregorb98b1992009-08-11 05:31:07 +0000150 OldLocation = Self.getDerived().getBaseLocation();
151 OldEntity = Self.getDerived().getBaseEntity();
152 Self.getDerived().setBase(Location, Entity);
153 }
Mike Stump1eb44332009-09-09 15:08:12 +0000154
Douglas Gregorb98b1992009-08-11 05:31:07 +0000155 ~TemporaryBase() {
156 Self.getDerived().setBase(OldLocation, OldEntity);
157 }
158 };
Mike Stump1eb44332009-09-09 15:08:12 +0000159
160 /// \brief Determine whether the given type \p T has already been
Douglas Gregor577f75a2009-08-04 16:50:30 +0000161 /// transformed.
162 ///
163 /// Subclasses can provide an alternative implementation of this routine
Mike Stump1eb44332009-09-09 15:08:12 +0000164 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregor577f75a2009-08-04 16:50:30 +0000165 /// not change. For example, template instantiation need not traverse
166 /// non-dependent types.
167 bool AlreadyTransformed(QualType T) {
168 return T.isNull();
169 }
170
171 /// \brief Transforms the given type into another type.
172 ///
173 /// By default, this routine transforms a type by delegating to the
Mike Stump1eb44332009-09-09 15:08:12 +0000174 /// appropriate TransformXXXType to build a new type, then applying
175 /// the qualifiers on \p T to the resulting type with AddTypeQualifiers.
176 /// Subclasses may override this function (to take over all type
Douglas Gregor577f75a2009-08-04 16:50:30 +0000177 /// transformations), some set of the TransformXXXType functions, or
178 /// the AddTypeQualifiers function to alter the transformation.
179 ///
180 /// \returns the transformed type.
181 QualType TransformType(QualType T);
Mike Stump1eb44332009-09-09 15:08:12 +0000182
Douglas Gregor577f75a2009-08-04 16:50:30 +0000183 /// \brief Transform the given type by adding the given set of qualifiers
184 /// and returning the result.
185 ///
186 /// FIXME: By default, this routine adds type qualifiers only to types that
187 /// can have qualifiers, and silently suppresses those qualifiers that are
188 /// not permitted (e.g., qualifiers on reference or function types). This
189 /// is the right thing for template instantiation, but probably not for
190 /// other clients.
John McCall0953e762009-09-24 19:53:00 +0000191 QualType AddTypeQualifiers(QualType T, Qualifiers Qs);
Mike Stump1eb44332009-09-09 15:08:12 +0000192
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000193 /// \brief Transform the given statement.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000194 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000195 /// By default, this routine transforms a statement by delegating to the
Douglas Gregor43959a92009-08-20 07:17:43 +0000196 /// appropriate TransformXXXStmt function to transform a specific kind of
197 /// statement or the TransformExpr() function to transform an expression.
198 /// Subclasses may override this function to transform statements using some
199 /// other mechanism.
200 ///
201 /// \returns the transformed statement.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000202 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump1eb44332009-09-09 15:08:12 +0000203
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000204 /// \brief Transform the given expression.
205 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000206 /// By default, this routine transforms an expression by delegating to the
207 /// appropriate TransformXXXExpr function to build a new expression.
208 /// Subclasses may override this function to transform expressions using some
209 /// other mechanism.
210 ///
211 /// \returns the transformed expression.
212 OwningExprResult TransformExpr(Expr *E) {
213 return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
214 }
215
216 /// \brief Transform the given expression.
217 ///
218 /// By default, this routine transforms an expression by delegating to the
219 /// appropriate TransformXXXExpr function to build a new expression.
220 /// Subclasses may override this function to transform expressions using some
221 /// other mechanism.
222 ///
223 /// \returns the transformed expression.
224 OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
Mike Stump1eb44332009-09-09 15:08:12 +0000225
Douglas Gregor577f75a2009-08-04 16:50:30 +0000226 /// \brief Transform the given declaration, which is referenced from a type
227 /// or expression.
228 ///
Douglas Gregordcee1a12009-08-06 05:28:30 +0000229 /// By default, acts as the identity function on declarations. Subclasses
230 /// may override this function to provide alternate behavior.
231 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregor43959a92009-08-20 07:17:43 +0000232
233 /// \brief Transform the definition of the given declaration.
234 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000235 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregor43959a92009-08-20 07:17:43 +0000236 /// Subclasses may override this function to provide alternate behavior.
237 Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
Mike Stump1eb44332009-09-09 15:08:12 +0000238
Douglas Gregor577f75a2009-08-04 16:50:30 +0000239 /// \brief Transform the given nested-name-specifier.
240 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000241 /// By default, transforms all of the types and declarations within the
Douglas Gregordcee1a12009-08-06 05:28:30 +0000242 /// nested-name-specifier. Subclasses may override this function to provide
243 /// alternate behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000244 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +0000245 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000246 QualType ObjectType = QualType(),
247 NamedDecl *FirstQualifierInScope = 0);
Mike Stump1eb44332009-09-09 15:08:12 +0000248
Douglas Gregor81499bb2009-09-03 22:13:48 +0000249 /// \brief Transform the given declaration name.
250 ///
251 /// By default, transforms the types of conversion function, constructor,
252 /// and destructor names and then (if needed) rebuilds the declaration name.
253 /// Identifiers and selectors are returned unmodified. Sublcasses may
254 /// override this function to provide alternate behavior.
255 DeclarationName TransformDeclarationName(DeclarationName Name,
256 SourceLocation Loc);
Mike Stump1eb44332009-09-09 15:08:12 +0000257
Douglas Gregor577f75a2009-08-04 16:50:30 +0000258 /// \brief Transform the given template name.
Mike Stump1eb44332009-09-09 15:08:12 +0000259 ///
Douglas Gregord1067e52009-08-06 06:41:21 +0000260 /// By default, transforms the template name by transforming the declarations
Mike Stump1eb44332009-09-09 15:08:12 +0000261 /// and nested-name-specifiers that occur within the template name.
Douglas Gregord1067e52009-08-06 06:41:21 +0000262 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000263 TemplateName TransformTemplateName(TemplateName Name,
264 QualType ObjectType = QualType());
Mike Stump1eb44332009-09-09 15:08:12 +0000265
Douglas Gregor577f75a2009-08-04 16:50:30 +0000266 /// \brief Transform the given template argument.
267 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000268 /// By default, this operation transforms the type, expression, or
269 /// declaration stored within the template argument and constructs a
Douglas Gregor670444e2009-08-04 22:27:00 +0000270 /// new template argument from the transformed result. Subclasses may
271 /// override this function to provide alternate behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000272 TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
Mike Stump1eb44332009-09-09 15:08:12 +0000273
Douglas Gregor577f75a2009-08-04 16:50:30 +0000274#define ABSTRACT_TYPE(CLASS, PARENT)
275#define TYPE(CLASS, PARENT) \
276 QualType Transform##CLASS##Type(const CLASS##Type *T);
Mike Stump1eb44332009-09-09 15:08:12 +0000277#include "clang/AST/TypeNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +0000278
Douglas Gregor43959a92009-08-20 07:17:43 +0000279 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump1eb44332009-09-09 15:08:12 +0000280
Douglas Gregor43959a92009-08-20 07:17:43 +0000281#define STMT(Node, Parent) \
282 OwningStmtResult Transform##Node(Node *S);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000283#define EXPR(Node, Parent) \
284 OwningExprResult Transform##Node(Node *E);
285#define ABSTRACT_EXPR(Node, Parent)
286#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +0000287
Douglas Gregor577f75a2009-08-04 16:50:30 +0000288 /// \brief Build a new pointer type given its pointee type.
289 ///
290 /// By default, performs semantic analysis when building the pointer type.
291 /// Subclasses may override this routine to provide different behavior.
292 QualType RebuildPointerType(QualType PointeeType);
293
294 /// \brief Build a new block pointer type given its pointee type.
295 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000296 /// By default, performs semantic analysis when building the block pointer
Douglas Gregor577f75a2009-08-04 16:50:30 +0000297 /// type. Subclasses may override this routine to provide different behavior.
298 QualType RebuildBlockPointerType(QualType PointeeType);
299
300 /// \brief Build a new lvalue reference type given the type it references.
301 ///
302 /// By default, performs semantic analysis when building the lvalue reference
303 /// type. Subclasses may override this routine to provide different behavior.
304 QualType RebuildLValueReferenceType(QualType ReferentType);
305
306 /// \brief Build a new rvalue reference type given the type it references.
307 ///
308 /// By default, performs semantic analysis when building the rvalue reference
309 /// type. Subclasses may override this routine to provide different behavior.
310 QualType RebuildRValueReferenceType(QualType ReferentType);
Mike Stump1eb44332009-09-09 15:08:12 +0000311
Douglas Gregor577f75a2009-08-04 16:50:30 +0000312 /// \brief Build a new member pointer type given the pointee type and the
313 /// class type it refers into.
314 ///
315 /// By default, performs semantic analysis when building the member pointer
316 /// type. Subclasses may override this routine to provide different behavior.
317 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
Mike Stump1eb44332009-09-09 15:08:12 +0000318
Douglas Gregor577f75a2009-08-04 16:50:30 +0000319 /// \brief Build a new array type given the element type, size
320 /// modifier, size of the array (if known), size expression, and index type
321 /// qualifiers.
322 ///
323 /// By default, performs semantic analysis when building the array type.
324 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000325 /// Also by default, all of the other Rebuild*Array
Douglas Gregor577f75a2009-08-04 16:50:30 +0000326 QualType RebuildArrayType(QualType ElementType,
327 ArrayType::ArraySizeModifier SizeMod,
328 const llvm::APInt *Size,
329 Expr *SizeExpr,
330 unsigned IndexTypeQuals,
331 SourceRange BracketsRange);
Mike Stump1eb44332009-09-09 15:08:12 +0000332
Douglas Gregor577f75a2009-08-04 16:50:30 +0000333 /// \brief Build a new constant array type given the element type, size
334 /// modifier, (known) size of the array, and index type qualifiers.
335 ///
336 /// By default, performs semantic analysis when building the array type.
337 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000338 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000339 ArrayType::ArraySizeModifier SizeMod,
340 const llvm::APInt &Size,
341 unsigned IndexTypeQuals);
342
343 /// \brief Build a new constant array type given the element type, size
Mike Stump1eb44332009-09-09 15:08:12 +0000344 /// modifier, (known) size of the array, size expression, and index type
Douglas Gregor577f75a2009-08-04 16:50:30 +0000345 /// qualifiers.
346 ///
347 /// By default, performs semantic analysis when building the array type.
348 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000349 QualType RebuildConstantArrayWithExprType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000350 ArrayType::ArraySizeModifier SizeMod,
351 const llvm::APInt &Size,
352 Expr *SizeExpr,
353 unsigned IndexTypeQuals,
354 SourceRange BracketsRange);
355
356 /// \brief Build a new constant array type given the element type, size
357 /// modifier, (known) size of the array, and index type qualifiers.
358 ///
359 /// By default, performs semantic analysis when building the array type.
360 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000361 QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000362 ArrayType::ArraySizeModifier SizeMod,
363 const llvm::APInt &Size,
364 unsigned IndexTypeQuals);
365
366 /// \brief Build a new incomplete array type given the element type, size
367 /// modifier, and index type qualifiers.
368 ///
369 /// By default, performs semantic analysis when building the array type.
370 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000371 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000372 ArrayType::ArraySizeModifier SizeMod,
373 unsigned IndexTypeQuals);
374
Mike Stump1eb44332009-09-09 15:08:12 +0000375 /// \brief Build a new variable-length array type given the element type,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000376 /// size modifier, size expression, and index type qualifiers.
377 ///
378 /// By default, performs semantic analysis when building the array type.
379 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000380 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000381 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000382 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000383 unsigned IndexTypeQuals,
384 SourceRange BracketsRange);
385
Mike Stump1eb44332009-09-09 15:08:12 +0000386 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000387 /// size modifier, size expression, and index type qualifiers.
388 ///
389 /// By default, performs semantic analysis when building the array type.
390 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000391 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000392 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000393 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000394 unsigned IndexTypeQuals,
395 SourceRange BracketsRange);
396
397 /// \brief Build a new vector type given the element type and
398 /// number of elements.
399 ///
400 /// By default, performs semantic analysis when building the vector type.
401 /// Subclasses may override this routine to provide different behavior.
402 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump1eb44332009-09-09 15:08:12 +0000403
Douglas Gregor577f75a2009-08-04 16:50:30 +0000404 /// \brief Build a new extended vector type given the element type and
405 /// number of elements.
406 ///
407 /// By default, performs semantic analysis when building the vector type.
408 /// Subclasses may override this routine to provide different behavior.
409 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
410 SourceLocation AttributeLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000411
412 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregor577f75a2009-08-04 16:50:30 +0000413 /// given the element type and number of elements.
414 ///
415 /// By default, performs semantic analysis when building the vector type.
416 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000417 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000418 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000419 SourceLocation AttributeLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000420
Douglas Gregor577f75a2009-08-04 16:50:30 +0000421 /// \brief Build a new function type.
422 ///
423 /// By default, performs semantic analysis when building the function type.
424 /// Subclasses may override this routine to provide different behavior.
425 QualType RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +0000426 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000427 unsigned NumParamTypes,
428 bool Variadic, unsigned Quals);
Mike Stump1eb44332009-09-09 15:08:12 +0000429
Douglas Gregor577f75a2009-08-04 16:50:30 +0000430 /// \brief Build a new typedef type.
431 QualType RebuildTypedefType(TypedefDecl *Typedef) {
432 return SemaRef.Context.getTypeDeclType(Typedef);
433 }
434
435 /// \brief Build a new class/struct/union type.
436 QualType RebuildRecordType(RecordDecl *Record) {
437 return SemaRef.Context.getTypeDeclType(Record);
438 }
439
440 /// \brief Build a new Enum type.
441 QualType RebuildEnumType(EnumDecl *Enum) {
442 return SemaRef.Context.getTypeDeclType(Enum);
443 }
John McCall7da24312009-09-05 00:15:47 +0000444
445 /// \brief Build a new elaborated type.
446 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
447 return SemaRef.Context.getElaboratedType(T, Tag);
448 }
Mike Stump1eb44332009-09-09 15:08:12 +0000449
450 /// \brief Build a new typeof(expr) type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000451 ///
452 /// By default, performs semantic analysis when building the typeof type.
453 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000454 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000455
Mike Stump1eb44332009-09-09 15:08:12 +0000456 /// \brief Build a new typeof(type) type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000457 ///
458 /// By default, builds a new TypeOfType with the given underlying type.
459 QualType RebuildTypeOfType(QualType Underlying);
460
Mike Stump1eb44332009-09-09 15:08:12 +0000461 /// \brief Build a new C++0x decltype type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000462 ///
463 /// By default, performs semantic analysis when building the decltype type.
464 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000465 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump1eb44332009-09-09 15:08:12 +0000466
Douglas Gregor577f75a2009-08-04 16:50:30 +0000467 /// \brief Build a new template specialization type.
468 ///
469 /// By default, performs semantic analysis when building the template
470 /// specialization type. Subclasses may override this routine to provide
471 /// different behavior.
472 QualType RebuildTemplateSpecializationType(TemplateName Template,
473 const TemplateArgument *Args,
474 unsigned NumArgs);
Mike Stump1eb44332009-09-09 15:08:12 +0000475
Douglas Gregor577f75a2009-08-04 16:50:30 +0000476 /// \brief Build a new qualified name type.
477 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000478 /// By default, builds a new QualifiedNameType type from the
479 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregor577f75a2009-08-04 16:50:30 +0000480 /// this routine to provide different behavior.
481 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
482 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump1eb44332009-09-09 15:08:12 +0000483 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000484
485 /// \brief Build a new typename type that refers to a template-id.
486 ///
487 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump1eb44332009-09-09 15:08:12 +0000488 /// and the given type. Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000489 /// different behavior.
490 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
491 if (NNS->isDependent())
Mike Stump1eb44332009-09-09 15:08:12 +0000492 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000493 cast<TemplateSpecializationType>(T));
Mike Stump1eb44332009-09-09 15:08:12 +0000494
Douglas Gregor577f75a2009-08-04 16:50:30 +0000495 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump1eb44332009-09-09 15:08:12 +0000496 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000497
498 /// \brief Build a new typename type that refers to an identifier.
499 ///
500 /// By default, performs semantic analysis when building the typename type
Mike Stump1eb44332009-09-09 15:08:12 +0000501 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000502 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000503 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000504 const IdentifierInfo *Id) {
505 return SemaRef.CheckTypenameType(NNS, *Id,
506 SourceRange(getDerived().getBaseLocation()));
Douglas Gregordcee1a12009-08-06 05:28:30 +0000507 }
Mike Stump1eb44332009-09-09 15:08:12 +0000508
Douglas Gregordcee1a12009-08-06 05:28:30 +0000509 /// \brief Build a new nested-name-specifier given the prefix and an
510 /// identifier that names the next step in the nested-name-specifier.
511 ///
512 /// By default, performs semantic analysis when building the new
513 /// nested-name-specifier. Subclasses may override this routine to provide
514 /// different behavior.
515 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
516 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +0000517 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000518 QualType ObjectType,
519 NamedDecl *FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000520
521 /// \brief Build a new nested-name-specifier given the prefix and the
522 /// namespace named in the next step in the nested-name-specifier.
523 ///
524 /// By default, performs semantic analysis when building the new
525 /// nested-name-specifier. Subclasses may override this routine to provide
526 /// different behavior.
527 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
528 SourceRange Range,
529 NamespaceDecl *NS);
530
531 /// \brief Build a new nested-name-specifier given the prefix and the
532 /// type named in the next step in the nested-name-specifier.
533 ///
534 /// By default, performs semantic analysis when building the new
535 /// nested-name-specifier. Subclasses may override this routine to provide
536 /// different behavior.
537 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
538 SourceRange Range,
539 bool TemplateKW,
540 QualType T);
Douglas Gregord1067e52009-08-06 06:41:21 +0000541
542 /// \brief Build a new template name given a nested name specifier, a flag
543 /// indicating whether the "template" keyword was provided, and the template
544 /// that the template name refers to.
545 ///
546 /// By default, builds the new template name directly. Subclasses may override
547 /// this routine to provide different behavior.
548 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
549 bool TemplateKW,
550 TemplateDecl *Template);
551
552 /// \brief Build a new template name given a nested name specifier, a flag
553 /// indicating whether the "template" keyword was provided, and a set of
554 /// overloaded function templates.
555 ///
556 /// By default, builds the new template name directly. Subclasses may override
557 /// this routine to provide different behavior.
558 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
559 bool TemplateKW,
560 OverloadedFunctionDecl *Ovl);
Mike Stump1eb44332009-09-09 15:08:12 +0000561
Douglas Gregord1067e52009-08-06 06:41:21 +0000562 /// \brief Build a new template name given a nested name specifier and the
563 /// name that is referred to as a template.
564 ///
565 /// By default, performs semantic analysis to determine whether the name can
566 /// be resolved to a specific template, then builds the appropriate kind of
567 /// template name. Subclasses may override this routine to provide different
568 /// behavior.
569 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000570 const IdentifierInfo &II,
571 QualType ObjectType);
Mike Stump1eb44332009-09-09 15:08:12 +0000572
573
Douglas Gregor43959a92009-08-20 07:17:43 +0000574 /// \brief Build a new compound statement.
575 ///
576 /// By default, performs semantic analysis to build the new statement.
577 /// Subclasses may override this routine to provide different behavior.
578 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
579 MultiStmtArg Statements,
580 SourceLocation RBraceLoc,
581 bool IsStmtExpr) {
582 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
583 IsStmtExpr);
584 }
585
586 /// \brief Build a new case statement.
587 ///
588 /// By default, performs semantic analysis to build the new statement.
589 /// Subclasses may override this routine to provide different behavior.
590 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
591 ExprArg LHS,
592 SourceLocation EllipsisLoc,
593 ExprArg RHS,
594 SourceLocation ColonLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000595 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregor43959a92009-08-20 07:17:43 +0000596 ColonLoc);
597 }
Mike Stump1eb44332009-09-09 15:08:12 +0000598
Douglas Gregor43959a92009-08-20 07:17:43 +0000599 /// \brief Attach the body to a new case statement.
600 ///
601 /// By default, performs semantic analysis to build the new statement.
602 /// Subclasses may override this routine to provide different behavior.
603 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
604 getSema().ActOnCaseStmtBody(S.get(), move(Body));
605 return move(S);
606 }
Mike Stump1eb44332009-09-09 15:08:12 +0000607
Douglas Gregor43959a92009-08-20 07:17:43 +0000608 /// \brief Build a new default statement.
609 ///
610 /// By default, performs semantic analysis to build the new statement.
611 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000612 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000613 SourceLocation ColonLoc,
614 StmtArg SubStmt) {
Mike Stump1eb44332009-09-09 15:08:12 +0000615 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregor43959a92009-08-20 07:17:43 +0000616 /*CurScope=*/0);
617 }
Mike Stump1eb44332009-09-09 15:08:12 +0000618
Douglas Gregor43959a92009-08-20 07:17:43 +0000619 /// \brief Build a new label statement.
620 ///
621 /// By default, performs semantic analysis to build the new statement.
622 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000623 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000624 IdentifierInfo *Id,
625 SourceLocation ColonLoc,
626 StmtArg SubStmt) {
627 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
628 }
Mike Stump1eb44332009-09-09 15:08:12 +0000629
Douglas Gregor43959a92009-08-20 07:17:43 +0000630 /// \brief Build a new "if" statement.
631 ///
632 /// By default, performs semantic analysis to build the new statement.
633 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000634 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
635 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000636 StmtArg Else) {
637 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
638 }
Mike Stump1eb44332009-09-09 15:08:12 +0000639
Douglas Gregor43959a92009-08-20 07:17:43 +0000640 /// \brief Start building a new switch statement.
641 ///
642 /// By default, performs semantic analysis to build the new statement.
643 /// Subclasses may override this routine to provide different behavior.
644 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
645 return getSema().ActOnStartOfSwitchStmt(move(Cond));
646 }
Mike Stump1eb44332009-09-09 15:08:12 +0000647
Douglas Gregor43959a92009-08-20 07:17:43 +0000648 /// \brief Attach the body to the switch statement.
649 ///
650 /// By default, performs semantic analysis to build the new statement.
651 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000652 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000653 StmtArg Switch, StmtArg Body) {
654 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
655 move(Body));
656 }
657
658 /// \brief Build a new while statement.
659 ///
660 /// By default, performs semantic analysis to build the new statement.
661 /// Subclasses may override this routine to provide different behavior.
662 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
663 Sema::FullExprArg Cond,
664 StmtArg Body) {
665 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
666 }
Mike Stump1eb44332009-09-09 15:08:12 +0000667
Douglas Gregor43959a92009-08-20 07:17:43 +0000668 /// \brief Build a new do-while statement.
669 ///
670 /// By default, performs semantic analysis to build the new statement.
671 /// Subclasses may override this routine to provide different behavior.
672 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
673 SourceLocation WhileLoc,
674 SourceLocation LParenLoc,
675 ExprArg Cond,
676 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000677 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000678 move(Cond), RParenLoc);
679 }
680
681 /// \brief Build a new for statement.
682 ///
683 /// By default, performs semantic analysis to build the new statement.
684 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000685 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000686 SourceLocation LParenLoc,
687 StmtArg Init, ExprArg Cond, ExprArg Inc,
688 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump1eb44332009-09-09 15:08:12 +0000689 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregor43959a92009-08-20 07:17:43 +0000690 move(Inc), RParenLoc, move(Body));
691 }
Mike Stump1eb44332009-09-09 15:08:12 +0000692
Douglas Gregor43959a92009-08-20 07:17:43 +0000693 /// \brief Build a new goto statement.
694 ///
695 /// By default, performs semantic analysis to build the new statement.
696 /// Subclasses may override this routine to provide different behavior.
697 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
698 SourceLocation LabelLoc,
699 LabelStmt *Label) {
700 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
701 }
702
703 /// \brief Build a new indirect goto statement.
704 ///
705 /// By default, performs semantic analysis to build the new statement.
706 /// Subclasses may override this routine to provide different behavior.
707 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
708 SourceLocation StarLoc,
709 ExprArg Target) {
710 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
711 }
Mike Stump1eb44332009-09-09 15:08:12 +0000712
Douglas Gregor43959a92009-08-20 07:17:43 +0000713 /// \brief Build a new return statement.
714 ///
715 /// By default, performs semantic analysis to build the new statement.
716 /// Subclasses may override this routine to provide different behavior.
717 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
718 ExprArg Result) {
Mike Stump1eb44332009-09-09 15:08:12 +0000719
Douglas Gregor43959a92009-08-20 07:17:43 +0000720 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
721 }
Mike Stump1eb44332009-09-09 15:08:12 +0000722
Douglas Gregor43959a92009-08-20 07:17:43 +0000723 /// \brief Build a new declaration statement.
724 ///
725 /// By default, performs semantic analysis to build the new statement.
726 /// Subclasses may override this routine to provide different behavior.
727 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump1eb44332009-09-09 15:08:12 +0000728 SourceLocation StartLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000729 SourceLocation EndLoc) {
730 return getSema().Owned(
731 new (getSema().Context) DeclStmt(
732 DeclGroupRef::Create(getSema().Context,
733 Decls, NumDecls),
734 StartLoc, EndLoc));
735 }
Mike Stump1eb44332009-09-09 15:08:12 +0000736
Douglas Gregor43959a92009-08-20 07:17:43 +0000737 /// \brief Build a new C++ exception declaration.
738 ///
739 /// By default, performs semantic analysis to build the new decaration.
740 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000741 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregor43959a92009-08-20 07:17:43 +0000742 DeclaratorInfo *Declarator,
743 IdentifierInfo *Name,
744 SourceLocation Loc,
745 SourceRange TypeRange) {
Mike Stump1eb44332009-09-09 15:08:12 +0000746 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000747 TypeRange);
748 }
749
750 /// \brief Build a new C++ catch statement.
751 ///
752 /// By default, performs semantic analysis to build the new statement.
753 /// Subclasses may override this routine to provide different behavior.
754 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
755 VarDecl *ExceptionDecl,
756 StmtArg Handler) {
757 return getSema().Owned(
Mike Stump1eb44332009-09-09 15:08:12 +0000758 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregor43959a92009-08-20 07:17:43 +0000759 Handler.takeAs<Stmt>()));
760 }
Mike Stump1eb44332009-09-09 15:08:12 +0000761
Douglas Gregor43959a92009-08-20 07:17:43 +0000762 /// \brief Build a new C++ try statement.
763 ///
764 /// By default, performs semantic analysis to build the new statement.
765 /// Subclasses may override this routine to provide different behavior.
766 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
767 StmtArg TryBlock,
768 MultiStmtArg Handlers) {
769 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
770 }
Mike Stump1eb44332009-09-09 15:08:12 +0000771
Douglas Gregorb98b1992009-08-11 05:31:07 +0000772 /// \brief Build a new expression that references a declaration.
773 ///
774 /// By default, performs semantic analysis to build the new expression.
775 /// Subclasses may override this routine to provide different behavior.
776 OwningExprResult RebuildDeclRefExpr(NamedDecl *ND, SourceLocation Loc) {
777 return getSema().BuildDeclarationNameExpr(Loc, ND,
778 /*FIXME:*/false,
779 /*SS=*/0,
780 /*FIXME:*/false);
781 }
Mike Stump1eb44332009-09-09 15:08:12 +0000782
Douglas Gregorb98b1992009-08-11 05:31:07 +0000783 /// \brief Build a new expression in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +0000784 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000785 /// By default, performs semantic analysis to build the new expression.
786 /// Subclasses may override this routine to provide different behavior.
787 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
788 SourceLocation RParen) {
789 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
790 }
791
Douglas Gregora71d8192009-09-04 17:36:40 +0000792 /// \brief Build a new pseudo-destructor expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000793 ///
Douglas Gregora71d8192009-09-04 17:36:40 +0000794 /// By default, performs semantic analysis to build the new expression.
795 /// Subclasses may override this routine to provide different behavior.
796 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
797 SourceLocation OperatorLoc,
798 bool isArrow,
799 SourceLocation DestroyedTypeLoc,
800 QualType DestroyedType,
801 NestedNameSpecifier *Qualifier,
802 SourceRange QualifierRange) {
803 CXXScopeSpec SS;
804 if (Qualifier) {
805 SS.setRange(QualifierRange);
806 SS.setScopeRep(Qualifier);
807 }
808
Mike Stump1eb44332009-09-09 15:08:12 +0000809 DeclarationName Name
Douglas Gregora71d8192009-09-04 17:36:40 +0000810 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
811 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump1eb44332009-09-09 15:08:12 +0000812
813 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregora71d8192009-09-04 17:36:40 +0000814 OperatorLoc,
815 isArrow? tok::arrow : tok::period,
816 DestroyedTypeLoc,
817 Name,
818 Sema::DeclPtrTy::make((Decl *)0),
819 &SS);
Mike Stump1eb44332009-09-09 15:08:12 +0000820 }
821
Douglas Gregorb98b1992009-08-11 05:31:07 +0000822 /// \brief Build a new unary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000823 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000824 /// By default, performs semantic analysis to build the new expression.
825 /// Subclasses may override this routine to provide different behavior.
826 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
827 UnaryOperator::Opcode Opc,
828 ExprArg SubExpr) {
829 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
830 }
Mike Stump1eb44332009-09-09 15:08:12 +0000831
Douglas Gregorb98b1992009-08-11 05:31:07 +0000832 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000833 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000834 /// By default, performs semantic analysis to build the new expression.
835 /// Subclasses may override this routine to provide different behavior.
836 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
837 bool isSizeOf, SourceRange R) {
838 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
839 }
840
Mike Stump1eb44332009-09-09 15:08:12 +0000841 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregorb98b1992009-08-11 05:31:07 +0000842 /// argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000843 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000844 /// By default, performs semantic analysis to build the new expression.
845 /// Subclasses may override this routine to provide different behavior.
846 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
847 bool isSizeOf, SourceRange R) {
Mike Stump1eb44332009-09-09 15:08:12 +0000848 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +0000849 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
850 OpLoc, isSizeOf, R);
851 if (Result.isInvalid())
852 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +0000853
Douglas Gregorb98b1992009-08-11 05:31:07 +0000854 SubExpr.release();
855 return move(Result);
856 }
Mike Stump1eb44332009-09-09 15:08:12 +0000857
Douglas Gregorb98b1992009-08-11 05:31:07 +0000858 /// \brief Build a new array subscript expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000859 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000860 /// By default, performs semantic analysis to build the new expression.
861 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000862 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000863 SourceLocation LBracketLoc,
864 ExprArg RHS,
865 SourceLocation RBracketLoc) {
866 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump1eb44332009-09-09 15:08:12 +0000867 LBracketLoc, move(RHS),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000868 RBracketLoc);
869 }
870
871 /// \brief Build a new call expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000872 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000873 /// By default, performs semantic analysis to build the new expression.
874 /// Subclasses may override this routine to provide different behavior.
875 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
876 MultiExprArg Args,
877 SourceLocation *CommaLocs,
878 SourceLocation RParenLoc) {
879 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
880 move(Args), CommaLocs, RParenLoc);
881 }
882
883 /// \brief Build a new member access expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000884 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000885 /// By default, performs semantic analysis to build the new expression.
886 /// Subclasses may override this routine to provide different behavior.
887 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump1eb44332009-09-09 15:08:12 +0000888 bool isArrow,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000889 NestedNameSpecifier *Qualifier,
890 SourceRange QualifierRange,
891 SourceLocation MemberLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000892 NamedDecl *Member) {
Anders Carlssond8b285f2009-09-01 04:26:58 +0000893 if (!Member->getDeclName()) {
894 // We have a reference to an unnamed field.
895 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump1eb44332009-09-09 15:08:12 +0000896
897 MemberExpr *ME =
Anders Carlssond8b285f2009-09-01 04:26:58 +0000898 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
899 Member, MemberLoc,
900 cast<FieldDecl>(Member)->getType());
901 return getSema().Owned(ME);
902 }
Mike Stump1eb44332009-09-09 15:08:12 +0000903
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000904 CXXScopeSpec SS;
905 if (Qualifier) {
906 SS.setRange(QualifierRange);
907 SS.setScopeRep(Qualifier);
908 }
909
Douglas Gregor017dde52009-08-31 20:00:26 +0000910 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000911 isArrow? tok::arrow : tok::period,
912 MemberLoc,
Douglas Gregor017dde52009-08-31 20:00:26 +0000913 Member->getDeclName(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000914 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
915 &SS);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000916 }
Mike Stump1eb44332009-09-09 15:08:12 +0000917
Douglas Gregorb98b1992009-08-11 05:31:07 +0000918 /// \brief Build a new binary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000919 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000920 /// By default, performs semantic analysis to build the new expression.
921 /// Subclasses may override this routine to provide different behavior.
922 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
923 BinaryOperator::Opcode Opc,
924 ExprArg LHS, ExprArg RHS) {
925 OwningExprResult Result
Mike Stump1eb44332009-09-09 15:08:12 +0000926 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000927 (Expr *)RHS.get());
928 if (Result.isInvalid())
929 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +0000930
Douglas Gregorb98b1992009-08-11 05:31:07 +0000931 LHS.release();
932 RHS.release();
933 return move(Result);
934 }
935
936 /// \brief Build a new conditional operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000937 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000938 /// By default, performs semantic analysis to build the new expression.
939 /// Subclasses may override this routine to provide different behavior.
940 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
941 SourceLocation QuestionLoc,
942 ExprArg LHS,
943 SourceLocation ColonLoc,
944 ExprArg RHS) {
Mike Stump1eb44332009-09-09 15:08:12 +0000945 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000946 move(LHS), move(RHS));
947 }
948
949 /// \brief Build a new implicit cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000950 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000951 /// By default, builds a new implicit cast without any semantic analysis.
952 /// Subclasses may override this routine to provide different behavior.
953 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
954 ExprArg SubExpr, bool isLvalue) {
955 ImplicitCastExpr *ICE
Mike Stump1eb44332009-09-09 15:08:12 +0000956 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000957 (Expr *)SubExpr.release(),
958 isLvalue);
959 return getSema().Owned(ICE);
960 }
961
962 /// \brief Build a new C-style cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000963 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000964 /// By default, performs semantic analysis to build the new expression.
965 /// Subclasses may override this routine to provide different behavior.
966 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
967 QualType ExplicitTy,
968 SourceLocation RParenLoc,
969 ExprArg SubExpr) {
970 return getSema().ActOnCastExpr(/*Scope=*/0,
971 LParenLoc,
972 ExplicitTy.getAsOpaquePtr(),
973 RParenLoc,
974 move(SubExpr));
975 }
Mike Stump1eb44332009-09-09 15:08:12 +0000976
Douglas Gregorb98b1992009-08-11 05:31:07 +0000977 /// \brief Build a new compound literal expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000978 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000979 /// By default, performs semantic analysis to build the new expression.
980 /// Subclasses may override this routine to provide different behavior.
981 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
982 QualType T,
983 SourceLocation RParenLoc,
984 ExprArg Init) {
985 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
986 RParenLoc, move(Init));
987 }
Mike Stump1eb44332009-09-09 15:08:12 +0000988
Douglas Gregorb98b1992009-08-11 05:31:07 +0000989 /// \brief Build a new extended vector element access expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000990 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000991 /// By default, performs semantic analysis to build the new expression.
992 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000993 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000994 SourceLocation OpLoc,
995 SourceLocation AccessorLoc,
996 IdentifierInfo &Accessor) {
997 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
998 tok::period, AccessorLoc,
999 Accessor,
1000 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1001 }
Mike Stump1eb44332009-09-09 15:08:12 +00001002
Douglas Gregorb98b1992009-08-11 05:31:07 +00001003 /// \brief Build a new initializer list expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001004 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001005 /// By default, performs semantic analysis to build the new expression.
1006 /// Subclasses may override this routine to provide different behavior.
1007 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1008 MultiExprArg Inits,
1009 SourceLocation RBraceLoc) {
1010 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1011 }
Mike Stump1eb44332009-09-09 15:08:12 +00001012
Douglas Gregorb98b1992009-08-11 05:31:07 +00001013 /// \brief Build a new designated initializer expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001014 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001015 /// By default, performs semantic analysis to build the new expression.
1016 /// Subclasses may override this routine to provide different behavior.
1017 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1018 MultiExprArg ArrayExprs,
1019 SourceLocation EqualOrColonLoc,
1020 bool GNUSyntax,
1021 ExprArg Init) {
1022 OwningExprResult Result
1023 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1024 move(Init));
1025 if (Result.isInvalid())
1026 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001027
Douglas Gregorb98b1992009-08-11 05:31:07 +00001028 ArrayExprs.release();
1029 return move(Result);
1030 }
Mike Stump1eb44332009-09-09 15:08:12 +00001031
Douglas Gregorb98b1992009-08-11 05:31:07 +00001032 /// \brief Build a new value-initialized expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001033 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001034 /// By default, builds the implicit value initialization without performing
1035 /// any semantic analysis. Subclasses may override this routine to provide
1036 /// different behavior.
1037 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1038 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1039 }
Mike Stump1eb44332009-09-09 15:08:12 +00001040
Douglas Gregorb98b1992009-08-11 05:31:07 +00001041 /// \brief Build a new \c va_arg expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001042 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001043 /// By default, performs semantic analysis to build the new expression.
1044 /// Subclasses may override this routine to provide different behavior.
1045 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1046 QualType T, SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001047 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001048 RParenLoc);
1049 }
1050
1051 /// \brief Build a new expression list in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +00001052 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001053 /// By default, performs semantic analysis to build the new expression.
1054 /// Subclasses may override this routine to provide different behavior.
1055 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1056 MultiExprArg SubExprs,
1057 SourceLocation RParenLoc) {
1058 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1059 }
Mike Stump1eb44332009-09-09 15:08:12 +00001060
Douglas Gregorb98b1992009-08-11 05:31:07 +00001061 /// \brief Build a new address-of-label expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001062 ///
1063 /// By default, performs semantic analysis, using the name of the label
Douglas Gregorb98b1992009-08-11 05:31:07 +00001064 /// rather than attempting to map the label statement itself.
1065 /// Subclasses may override this routine to provide different behavior.
1066 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1067 SourceLocation LabelLoc,
1068 LabelStmt *Label) {
1069 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1070 }
Mike Stump1eb44332009-09-09 15:08:12 +00001071
Douglas Gregorb98b1992009-08-11 05:31:07 +00001072 /// \brief Build a new GNU statement expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001073 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001074 /// By default, performs semantic analysis to build the new expression.
1075 /// Subclasses may override this routine to provide different behavior.
1076 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1077 StmtArg SubStmt,
1078 SourceLocation RParenLoc) {
1079 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1080 }
Mike Stump1eb44332009-09-09 15:08:12 +00001081
Douglas Gregorb98b1992009-08-11 05:31:07 +00001082 /// \brief Build a new __builtin_types_compatible_p expression.
1083 ///
1084 /// By default, performs semantic analysis to build the new expression.
1085 /// Subclasses may override this routine to provide different behavior.
1086 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1087 QualType T1, QualType T2,
1088 SourceLocation RParenLoc) {
1089 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1090 T1.getAsOpaquePtr(),
1091 T2.getAsOpaquePtr(),
1092 RParenLoc);
1093 }
Mike Stump1eb44332009-09-09 15:08:12 +00001094
Douglas Gregorb98b1992009-08-11 05:31:07 +00001095 /// \brief Build a new __builtin_choose_expr expression.
1096 ///
1097 /// By default, performs semantic analysis to build the new expression.
1098 /// Subclasses may override this routine to provide different behavior.
1099 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1100 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1101 SourceLocation RParenLoc) {
1102 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1103 move(Cond), move(LHS), move(RHS),
1104 RParenLoc);
1105 }
Mike Stump1eb44332009-09-09 15:08:12 +00001106
Douglas Gregorb98b1992009-08-11 05:31:07 +00001107 /// \brief Build a new overloaded operator call expression.
1108 ///
1109 /// By default, performs semantic analysis to build the new expression.
1110 /// The semantic analysis provides the behavior of template instantiation,
1111 /// copying with transformations that turn what looks like an overloaded
Mike Stump1eb44332009-09-09 15:08:12 +00001112 /// operator call into a use of a builtin operator, performing
Douglas Gregorb98b1992009-08-11 05:31:07 +00001113 /// argument-dependent lookup, etc. Subclasses may override this routine to
1114 /// provide different behavior.
1115 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1116 SourceLocation OpLoc,
1117 ExprArg Callee,
1118 ExprArg First,
1119 ExprArg Second);
Mike Stump1eb44332009-09-09 15:08:12 +00001120
1121 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregorb98b1992009-08-11 05:31:07 +00001122 /// reinterpret_cast.
1123 ///
1124 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump1eb44332009-09-09 15:08:12 +00001125 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregorb98b1992009-08-11 05:31:07 +00001126 /// Subclasses may override this routine to provide different behavior.
1127 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1128 Stmt::StmtClass Class,
1129 SourceLocation LAngleLoc,
1130 QualType T,
1131 SourceLocation RAngleLoc,
1132 SourceLocation LParenLoc,
1133 ExprArg SubExpr,
1134 SourceLocation RParenLoc) {
1135 switch (Class) {
1136 case Stmt::CXXStaticCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001137 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1138 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001139 move(SubExpr), RParenLoc);
1140
1141 case Stmt::CXXDynamicCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001142 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1143 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001144 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001145
Douglas Gregorb98b1992009-08-11 05:31:07 +00001146 case Stmt::CXXReinterpretCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001147 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1148 RAngleLoc, LParenLoc,
1149 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001150 RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001151
Douglas Gregorb98b1992009-08-11 05:31:07 +00001152 case Stmt::CXXConstCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001153 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1154 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001155 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001156
Douglas Gregorb98b1992009-08-11 05:31:07 +00001157 default:
1158 assert(false && "Invalid C++ named cast");
1159 break;
1160 }
Mike Stump1eb44332009-09-09 15:08:12 +00001161
Douglas Gregorb98b1992009-08-11 05:31:07 +00001162 return getSema().ExprError();
1163 }
Mike Stump1eb44332009-09-09 15:08:12 +00001164
Douglas Gregorb98b1992009-08-11 05:31:07 +00001165 /// \brief Build a new C++ static_cast expression.
1166 ///
1167 /// By default, performs semantic analysis to build the new expression.
1168 /// Subclasses may override this routine to provide different behavior.
1169 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1170 SourceLocation LAngleLoc,
1171 QualType T,
1172 SourceLocation RAngleLoc,
1173 SourceLocation LParenLoc,
1174 ExprArg SubExpr,
1175 SourceLocation RParenLoc) {
1176 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001177 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001178 LParenLoc, move(SubExpr), RParenLoc);
1179 }
1180
1181 /// \brief Build a new C++ dynamic_cast expression.
1182 ///
1183 /// By default, performs semantic analysis to build the new expression.
1184 /// Subclasses may override this routine to provide different behavior.
1185 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1186 SourceLocation LAngleLoc,
1187 QualType T,
1188 SourceLocation RAngleLoc,
1189 SourceLocation LParenLoc,
1190 ExprArg SubExpr,
1191 SourceLocation RParenLoc) {
1192 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001193 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001194 LParenLoc, move(SubExpr), RParenLoc);
1195 }
1196
1197 /// \brief Build a new C++ reinterpret_cast expression.
1198 ///
1199 /// By default, performs semantic analysis to build the new expression.
1200 /// Subclasses may override this routine to provide different behavior.
1201 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1202 SourceLocation LAngleLoc,
1203 QualType T,
1204 SourceLocation RAngleLoc,
1205 SourceLocation LParenLoc,
1206 ExprArg SubExpr,
1207 SourceLocation RParenLoc) {
1208 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1209 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1210 LParenLoc, move(SubExpr), RParenLoc);
1211 }
1212
1213 /// \brief Build a new C++ const_cast expression.
1214 ///
1215 /// By default, performs semantic analysis to build the new expression.
1216 /// Subclasses may override this routine to provide different behavior.
1217 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1218 SourceLocation LAngleLoc,
1219 QualType T,
1220 SourceLocation RAngleLoc,
1221 SourceLocation LParenLoc,
1222 ExprArg SubExpr,
1223 SourceLocation RParenLoc) {
1224 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001225 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001226 LParenLoc, move(SubExpr), RParenLoc);
1227 }
Mike Stump1eb44332009-09-09 15:08:12 +00001228
Douglas Gregorb98b1992009-08-11 05:31:07 +00001229 /// \brief Build a new C++ functional-style cast expression.
1230 ///
1231 /// By default, performs semantic analysis to build the new expression.
1232 /// Subclasses may override this routine to provide different behavior.
1233 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1234 QualType T,
1235 SourceLocation LParenLoc,
1236 ExprArg SubExpr,
1237 SourceLocation RParenLoc) {
Chris Lattner88650c32009-08-24 05:19:01 +00001238 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregorb98b1992009-08-11 05:31:07 +00001239 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1240 T.getAsOpaquePtr(),
1241 LParenLoc,
Chris Lattner88650c32009-08-24 05:19:01 +00001242 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump1eb44332009-09-09 15:08:12 +00001243 /*CommaLocs=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001244 RParenLoc);
1245 }
Mike Stump1eb44332009-09-09 15:08:12 +00001246
Douglas Gregorb98b1992009-08-11 05:31:07 +00001247 /// \brief Build a new C++ typeid(type) expression.
1248 ///
1249 /// By default, performs semantic analysis to build the new expression.
1250 /// Subclasses may override this routine to provide different behavior.
1251 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1252 SourceLocation LParenLoc,
1253 QualType T,
1254 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001255 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001256 T.getAsOpaquePtr(), RParenLoc);
1257 }
Mike Stump1eb44332009-09-09 15:08:12 +00001258
Douglas Gregorb98b1992009-08-11 05:31:07 +00001259 /// \brief Build a new C++ typeid(expr) expression.
1260 ///
1261 /// By default, performs semantic analysis to build the new expression.
1262 /// Subclasses may override this routine to provide different behavior.
1263 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1264 SourceLocation LParenLoc,
1265 ExprArg Operand,
1266 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001267 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00001268 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1269 RParenLoc);
1270 if (Result.isInvalid())
1271 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001272
Douglas Gregorb98b1992009-08-11 05:31:07 +00001273 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1274 return move(Result);
Mike Stump1eb44332009-09-09 15:08:12 +00001275 }
1276
Douglas Gregorb98b1992009-08-11 05:31:07 +00001277 /// \brief Build a new C++ "this" expression.
1278 ///
1279 /// By default, builds a new "this" expression without performing any
Mike Stump1eb44332009-09-09 15:08:12 +00001280 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregorb98b1992009-08-11 05:31:07 +00001281 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001282 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001283 QualType ThisType) {
1284 return getSema().Owned(
1285 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1286 }
1287
1288 /// \brief Build a new C++ throw expression.
1289 ///
1290 /// By default, performs semantic analysis to build the new expression.
1291 /// Subclasses may override this routine to provide different behavior.
1292 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1293 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1294 }
1295
1296 /// \brief Build a new C++ default-argument expression.
1297 ///
1298 /// By default, builds a new default-argument expression, which does not
1299 /// require any semantic analysis. Subclasses may override this routine to
1300 /// provide different behavior.
1301 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssonf1480ee2009-08-14 18:30:22 +00001302 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001303 }
1304
1305 /// \brief Build a new C++ zero-initialization expression.
1306 ///
1307 /// By default, performs semantic analysis to build the new expression.
1308 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001309 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001310 SourceLocation LParenLoc,
1311 QualType T,
1312 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001313 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1314 T.getAsOpaquePtr(), LParenLoc,
1315 MultiExprArg(getSema(), 0, 0),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001316 0, RParenLoc);
1317 }
Mike Stump1eb44332009-09-09 15:08:12 +00001318
Douglas Gregorb98b1992009-08-11 05:31:07 +00001319 /// \brief Build a new C++ conditional declaration expression.
1320 ///
1321 /// By default, performs semantic analysis to build the new expression.
1322 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001323 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001324 SourceLocation EqLoc,
1325 VarDecl *Var) {
1326 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1327 EqLoc,
1328 Var));
1329 }
Mike Stump1eb44332009-09-09 15:08:12 +00001330
Douglas Gregorb98b1992009-08-11 05:31:07 +00001331 /// \brief Build a new C++ "new" expression.
1332 ///
1333 /// By default, performs semantic analysis to build the new expression.
1334 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001335 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001336 bool UseGlobal,
1337 SourceLocation PlacementLParen,
1338 MultiExprArg PlacementArgs,
1339 SourceLocation PlacementRParen,
Mike Stump1eb44332009-09-09 15:08:12 +00001340 bool ParenTypeId,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001341 QualType AllocType,
1342 SourceLocation TypeLoc,
1343 SourceRange TypeRange,
1344 ExprArg ArraySize,
1345 SourceLocation ConstructorLParen,
1346 MultiExprArg ConstructorArgs,
1347 SourceLocation ConstructorRParen) {
Mike Stump1eb44332009-09-09 15:08:12 +00001348 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001349 PlacementLParen,
1350 move(PlacementArgs),
1351 PlacementRParen,
1352 ParenTypeId,
1353 AllocType,
1354 TypeLoc,
1355 TypeRange,
1356 move(ArraySize),
1357 ConstructorLParen,
1358 move(ConstructorArgs),
1359 ConstructorRParen);
1360 }
Mike Stump1eb44332009-09-09 15:08:12 +00001361
Douglas Gregorb98b1992009-08-11 05:31:07 +00001362 /// \brief Build a new C++ "delete" expression.
1363 ///
1364 /// By default, performs semantic analysis to build the new expression.
1365 /// Subclasses may override this routine to provide different behavior.
1366 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1367 bool IsGlobalDelete,
1368 bool IsArrayForm,
1369 ExprArg Operand) {
1370 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1371 move(Operand));
1372 }
Mike Stump1eb44332009-09-09 15:08:12 +00001373
Douglas Gregorb98b1992009-08-11 05:31:07 +00001374 /// \brief Build a new unary type trait expression.
1375 ///
1376 /// By default, performs semantic analysis to build the new expression.
1377 /// Subclasses may override this routine to provide different behavior.
1378 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1379 SourceLocation StartLoc,
1380 SourceLocation LParenLoc,
1381 QualType T,
1382 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001383 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001384 T.getAsOpaquePtr(), RParenLoc);
1385 }
1386
1387 /// \brief Build a new qualified declaration reference expression.
1388 ///
1389 /// By default, performs semantic analysis to build the new expression.
1390 /// Subclasses may override this routine to provide different behavior.
1391 OwningExprResult RebuildQualifiedDeclRefExpr(NestedNameSpecifier *NNS,
1392 SourceRange QualifierRange,
1393 NamedDecl *ND,
1394 SourceLocation Location,
1395 bool IsAddressOfOperand) {
1396 CXXScopeSpec SS;
1397 SS.setRange(QualifierRange);
1398 SS.setScopeRep(NNS);
Mike Stump1eb44332009-09-09 15:08:12 +00001399 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001400 Location,
1401 ND->getDeclName(),
1402 /*Trailing lparen=*/false,
1403 &SS,
1404 IsAddressOfOperand);
1405 }
1406
Mike Stump1eb44332009-09-09 15:08:12 +00001407 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregorb98b1992009-08-11 05:31:07 +00001408 /// expression.
1409 ///
1410 /// By default, performs semantic analysis to build the new expression.
1411 /// Subclasses may override this routine to provide different behavior.
1412 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1413 SourceRange QualifierRange,
1414 DeclarationName Name,
1415 SourceLocation Location,
1416 bool IsAddressOfOperand) {
1417 CXXScopeSpec SS;
1418 SS.setRange(QualifierRange);
1419 SS.setScopeRep(NNS);
Mike Stump1eb44332009-09-09 15:08:12 +00001420 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001421 Location,
1422 Name,
1423 /*Trailing lparen=*/false,
1424 &SS,
1425 IsAddressOfOperand);
1426 }
1427
1428 /// \brief Build a new template-id expression.
1429 ///
1430 /// By default, performs semantic analysis to build the new expression.
1431 /// Subclasses may override this routine to provide different behavior.
1432 OwningExprResult RebuildTemplateIdExpr(TemplateName Template,
1433 SourceLocation TemplateLoc,
1434 SourceLocation LAngleLoc,
1435 TemplateArgument *TemplateArgs,
1436 unsigned NumTemplateArgs,
1437 SourceLocation RAngleLoc) {
1438 return getSema().BuildTemplateIdExpr(Template, TemplateLoc,
1439 LAngleLoc,
1440 TemplateArgs, NumTemplateArgs,
1441 RAngleLoc);
1442 }
1443
1444 /// \brief Build a new object-construction expression.
1445 ///
1446 /// By default, performs semantic analysis to build the new expression.
1447 /// Subclasses may override this routine to provide different behavior.
1448 OwningExprResult RebuildCXXConstructExpr(QualType T,
1449 CXXConstructorDecl *Constructor,
1450 bool IsElidable,
1451 MultiExprArg Args) {
Anders Carlssonec8e5ea2009-09-05 07:40:38 +00001452 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1453 SourceLocation(),
1454 T, Constructor, IsElidable,
Anders Carlssonf47511a2009-09-07 22:23:31 +00001455 move(Args));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001456 }
1457
1458 /// \brief Build a new object-construction expression.
1459 ///
1460 /// By default, performs semantic analysis to build the new expression.
1461 /// Subclasses may override this routine to provide different behavior.
1462 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1463 QualType T,
1464 SourceLocation LParenLoc,
1465 MultiExprArg Args,
1466 SourceLocation *Commas,
1467 SourceLocation RParenLoc) {
1468 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1469 T.getAsOpaquePtr(),
1470 LParenLoc,
1471 move(Args),
1472 Commas,
1473 RParenLoc);
1474 }
1475
1476 /// \brief Build a new object-construction expression.
1477 ///
1478 /// By default, performs semantic analysis to build the new expression.
1479 /// Subclasses may override this routine to provide different behavior.
1480 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1481 QualType T,
1482 SourceLocation LParenLoc,
1483 MultiExprArg Args,
1484 SourceLocation *Commas,
1485 SourceLocation RParenLoc) {
1486 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1487 /*FIXME*/LParenLoc),
1488 T.getAsOpaquePtr(),
1489 LParenLoc,
1490 move(Args),
1491 Commas,
1492 RParenLoc);
1493 }
Mike Stump1eb44332009-09-09 15:08:12 +00001494
Douglas Gregorb98b1992009-08-11 05:31:07 +00001495 /// \brief Build a new member reference expression.
1496 ///
1497 /// By default, performs semantic analysis to build the new expression.
1498 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001499 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001500 bool IsArrow,
1501 SourceLocation OperatorLoc,
Douglas Gregora38c6872009-09-03 16:14:30 +00001502 NestedNameSpecifier *Qualifier,
1503 SourceRange QualifierRange,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001504 DeclarationName Name,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001505 SourceLocation MemberLoc,
1506 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001507 OwningExprResult Base = move(BaseE);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001508 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregora38c6872009-09-03 16:14:30 +00001509
Douglas Gregorb98b1992009-08-11 05:31:07 +00001510 CXXScopeSpec SS;
Douglas Gregora38c6872009-09-03 16:14:30 +00001511 SS.setRange(QualifierRange);
1512 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001513
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001514 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001515 move(Base), OperatorLoc, OpKind,
Douglas Gregor017dde52009-08-31 20:00:26 +00001516 MemberLoc,
1517 Name,
Douglas Gregora38c6872009-09-03 16:14:30 +00001518 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001519 &SS,
1520 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001521 }
1522
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001523 /// \brief Build a new member reference expression with explicit template
1524 /// arguments.
1525 ///
1526 /// By default, performs semantic analysis to build the new expression.
1527 /// Subclasses may override this routine to provide different behavior.
1528 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1529 bool IsArrow,
1530 SourceLocation OperatorLoc,
1531 NestedNameSpecifier *Qualifier,
1532 SourceRange QualifierRange,
1533 TemplateName Template,
1534 SourceLocation TemplateNameLoc,
1535 NamedDecl *FirstQualifierInScope,
1536 SourceLocation LAngleLoc,
1537 const TemplateArgument *TemplateArgs,
1538 unsigned NumTemplateArgs,
1539 SourceLocation RAngleLoc) {
1540 OwningExprResult Base = move(BaseE);
1541 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump1eb44332009-09-09 15:08:12 +00001542
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001543 CXXScopeSpec SS;
1544 SS.setRange(QualifierRange);
1545 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001546
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001547 // FIXME: We're going to end up looking up the template based on its name,
1548 // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
1549 DeclarationName Name;
1550 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1551 Name = ActualTemplate->getDeclName();
Mike Stump1eb44332009-09-09 15:08:12 +00001552 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001553 = Template.getAsOverloadedFunctionDecl())
1554 Name = Ovl->getDeclName();
1555 else
1556 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump1eb44332009-09-09 15:08:12 +00001557
1558 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001559 OperatorLoc, OpKind,
1560 TemplateNameLoc, Name, true,
1561 LAngleLoc, TemplateArgs,
1562 NumTemplateArgs, RAngleLoc,
1563 Sema::DeclPtrTy(), &SS);
1564 }
Mike Stump1eb44332009-09-09 15:08:12 +00001565
Douglas Gregorb98b1992009-08-11 05:31:07 +00001566 /// \brief Build a new Objective-C @encode expression.
1567 ///
1568 /// By default, performs semantic analysis to build the new expression.
1569 /// Subclasses may override this routine to provide different behavior.
1570 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1571 QualType T,
1572 SourceLocation RParenLoc) {
1573 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1574 RParenLoc));
Mike Stump1eb44332009-09-09 15:08:12 +00001575 }
Douglas Gregorb98b1992009-08-11 05:31:07 +00001576
1577 /// \brief Build a new Objective-C protocol 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 RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1582 SourceLocation AtLoc,
1583 SourceLocation ProtoLoc,
1584 SourceLocation LParenLoc,
1585 SourceLocation RParenLoc) {
1586 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1587 Protocol->getIdentifier(),
1588 AtLoc,
1589 ProtoLoc,
1590 LParenLoc,
Mike Stump1eb44332009-09-09 15:08:12 +00001591 RParenLoc));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001592 }
Mike Stump1eb44332009-09-09 15:08:12 +00001593
Douglas Gregorb98b1992009-08-11 05:31:07 +00001594 /// \brief Build a new shuffle vector expression.
1595 ///
1596 /// By default, performs semantic analysis to build the new expression.
1597 /// Subclasses may override this routine to provide different behavior.
1598 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1599 MultiExprArg SubExprs,
1600 SourceLocation RParenLoc) {
1601 // Find the declaration for __builtin_shufflevector
Mike Stump1eb44332009-09-09 15:08:12 +00001602 const IdentifierInfo &Name
Douglas Gregorb98b1992009-08-11 05:31:07 +00001603 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1604 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1605 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1606 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump1eb44332009-09-09 15:08:12 +00001607
Douglas Gregorb98b1992009-08-11 05:31:07 +00001608 // Build a reference to the __builtin_shufflevector builtin
1609 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump1eb44332009-09-09 15:08:12 +00001610 Expr *Callee
Douglas Gregorb98b1992009-08-11 05:31:07 +00001611 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1612 BuiltinLoc, false, false);
1613 SemaRef.UsualUnaryConversions(Callee);
Mike Stump1eb44332009-09-09 15:08:12 +00001614
1615 // Build the CallExpr
Douglas Gregorb98b1992009-08-11 05:31:07 +00001616 unsigned NumSubExprs = SubExprs.size();
1617 Expr **Subs = (Expr **)SubExprs.release();
1618 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1619 Subs, NumSubExprs,
1620 Builtin->getResultType(),
1621 RParenLoc);
1622 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump1eb44332009-09-09 15:08:12 +00001623
Douglas Gregorb98b1992009-08-11 05:31:07 +00001624 // Type-check the __builtin_shufflevector expression.
1625 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1626 if (Result.isInvalid())
1627 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001628
Douglas Gregorb98b1992009-08-11 05:31:07 +00001629 OwnedCall.release();
Mike Stump1eb44332009-09-09 15:08:12 +00001630 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001631 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00001632};
Douglas Gregorb98b1992009-08-11 05:31:07 +00001633
Douglas Gregor43959a92009-08-20 07:17:43 +00001634template<typename Derived>
1635Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1636 if (!S)
1637 return SemaRef.Owned(S);
Mike Stump1eb44332009-09-09 15:08:12 +00001638
Douglas Gregor43959a92009-08-20 07:17:43 +00001639 switch (S->getStmtClass()) {
1640 case Stmt::NoStmtClass: break;
Mike Stump1eb44332009-09-09 15:08:12 +00001641
Douglas Gregor43959a92009-08-20 07:17:43 +00001642 // Transform individual statement nodes
1643#define STMT(Node, Parent) \
1644 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1645#define EXPR(Node, Parent)
1646#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001647
Douglas Gregor43959a92009-08-20 07:17:43 +00001648 // Transform expressions by calling TransformExpr.
1649#define STMT(Node, Parent)
1650#define EXPR(Node, Parent) case Stmt::Node##Class:
1651#include "clang/AST/StmtNodes.def"
1652 {
1653 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1654 if (E.isInvalid())
1655 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00001656
Douglas Gregor43959a92009-08-20 07:17:43 +00001657 return getSema().Owned(E.takeAs<Stmt>());
1658 }
Mike Stump1eb44332009-09-09 15:08:12 +00001659 }
1660
Douglas Gregor43959a92009-08-20 07:17:43 +00001661 return SemaRef.Owned(S->Retain());
1662}
Mike Stump1eb44332009-09-09 15:08:12 +00001663
1664
Douglas Gregor670444e2009-08-04 22:27:00 +00001665template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00001666Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1667 bool isAddressOfOperand) {
1668 if (!E)
1669 return SemaRef.Owned(E);
1670
1671 switch (E->getStmtClass()) {
1672 case Stmt::NoStmtClass: break;
1673#define STMT(Node, Parent) case Stmt::Node##Class: break;
1674#define EXPR(Node, Parent) \
1675 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1676#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001677 }
1678
Douglas Gregorb98b1992009-08-11 05:31:07 +00001679 return SemaRef.Owned(E->Retain());
Douglas Gregor657c1ac2009-08-06 22:17:10 +00001680}
1681
1682template<typename Derived>
Douglas Gregordcee1a12009-08-06 05:28:30 +00001683NestedNameSpecifier *
1684TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +00001685 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001686 QualType ObjectType,
1687 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0979c802009-08-31 21:41:48 +00001688 if (!NNS)
1689 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001690
Douglas Gregor43959a92009-08-20 07:17:43 +00001691 // Transform the prefix of this nested name specifier.
Douglas Gregordcee1a12009-08-06 05:28:30 +00001692 NestedNameSpecifier *Prefix = NNS->getPrefix();
1693 if (Prefix) {
Mike Stump1eb44332009-09-09 15:08:12 +00001694 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001695 ObjectType,
1696 FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +00001697 if (!Prefix)
1698 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001699
1700 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregorc68afe22009-09-03 21:38:09 +00001701 // apply to the first element in the nested-name-specifier.
Douglas Gregora38c6872009-09-03 16:14:30 +00001702 ObjectType = QualType();
Douglas Gregorc68afe22009-09-03 21:38:09 +00001703 FirstQualifierInScope = 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001704 }
Mike Stump1eb44332009-09-09 15:08:12 +00001705
Douglas Gregordcee1a12009-08-06 05:28:30 +00001706 switch (NNS->getKind()) {
1707 case NestedNameSpecifier::Identifier:
Mike Stump1eb44332009-09-09 15:08:12 +00001708 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregora38c6872009-09-03 16:14:30 +00001709 "Identifier nested-name-specifier with no prefix or object type");
1710 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1711 ObjectType.isNull())
Douglas Gregordcee1a12009-08-06 05:28:30 +00001712 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001713
1714 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00001715 *NNS->getAsIdentifier(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001716 ObjectType,
1717 FirstQualifierInScope);
Mike Stump1eb44332009-09-09 15:08:12 +00001718
Douglas Gregordcee1a12009-08-06 05:28:30 +00001719 case NestedNameSpecifier::Namespace: {
Mike Stump1eb44332009-09-09 15:08:12 +00001720 NamespaceDecl *NS
Douglas Gregordcee1a12009-08-06 05:28:30 +00001721 = cast_or_null<NamespaceDecl>(
1722 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump1eb44332009-09-09 15:08:12 +00001723 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordcee1a12009-08-06 05:28:30 +00001724 Prefix == NNS->getPrefix() &&
1725 NS == NNS->getAsNamespace())
1726 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001727
Douglas Gregordcee1a12009-08-06 05:28:30 +00001728 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1729 }
Mike Stump1eb44332009-09-09 15:08:12 +00001730
Douglas Gregordcee1a12009-08-06 05:28:30 +00001731 case NestedNameSpecifier::Global:
1732 // There is no meaningful transformation that one could perform on the
1733 // global scope.
1734 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001735
Douglas Gregordcee1a12009-08-06 05:28:30 +00001736 case NestedNameSpecifier::TypeSpecWithTemplate:
1737 case NestedNameSpecifier::TypeSpec: {
1738 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregord1067e52009-08-06 06:41:21 +00001739 if (T.isNull())
1740 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001741
Douglas Gregordcee1a12009-08-06 05:28:30 +00001742 if (!getDerived().AlwaysRebuild() &&
1743 Prefix == NNS->getPrefix() &&
1744 T == QualType(NNS->getAsType(), 0))
1745 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001746
1747 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1748 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregordcee1a12009-08-06 05:28:30 +00001749 T);
1750 }
1751 }
Mike Stump1eb44332009-09-09 15:08:12 +00001752
Douglas Gregordcee1a12009-08-06 05:28:30 +00001753 // Required to silence a GCC warning
Mike Stump1eb44332009-09-09 15:08:12 +00001754 return 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001755}
1756
1757template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001758DeclarationName
Douglas Gregor81499bb2009-09-03 22:13:48 +00001759TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
1760 SourceLocation Loc) {
1761 if (!Name)
1762 return Name;
1763
1764 switch (Name.getNameKind()) {
1765 case DeclarationName::Identifier:
1766 case DeclarationName::ObjCZeroArgSelector:
1767 case DeclarationName::ObjCOneArgSelector:
1768 case DeclarationName::ObjCMultiArgSelector:
1769 case DeclarationName::CXXOperatorName:
1770 case DeclarationName::CXXUsingDirective:
1771 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001772
Douglas Gregor81499bb2009-09-03 22:13:48 +00001773 case DeclarationName::CXXConstructorName:
1774 case DeclarationName::CXXDestructorName:
1775 case DeclarationName::CXXConversionFunctionName: {
1776 TemporaryBase Rebase(*this, Loc, Name);
1777 QualType T = getDerived().TransformType(Name.getCXXNameType());
1778 if (T.isNull())
1779 return DeclarationName();
Mike Stump1eb44332009-09-09 15:08:12 +00001780
Douglas Gregor81499bb2009-09-03 22:13:48 +00001781 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump1eb44332009-09-09 15:08:12 +00001782 Name.getNameKind(),
Douglas Gregor81499bb2009-09-03 22:13:48 +00001783 SemaRef.Context.getCanonicalType(T));
Douglas Gregor81499bb2009-09-03 22:13:48 +00001784 }
Mike Stump1eb44332009-09-09 15:08:12 +00001785 }
1786
Douglas Gregor81499bb2009-09-03 22:13:48 +00001787 return DeclarationName();
1788}
1789
1790template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001791TemplateName
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001792TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1793 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00001794 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001795 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001796 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1797 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1798 if (!NNS)
1799 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001800
Douglas Gregord1067e52009-08-06 06:41:21 +00001801 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001802 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001803 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1804 if (!TransTemplate)
1805 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001806
Douglas Gregord1067e52009-08-06 06:41:21 +00001807 if (!getDerived().AlwaysRebuild() &&
1808 NNS == QTN->getQualifier() &&
1809 TransTemplate == Template)
1810 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001811
Douglas Gregord1067e52009-08-06 06:41:21 +00001812 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1813 TransTemplate);
1814 }
Mike Stump1eb44332009-09-09 15:08:12 +00001815
Douglas Gregord1067e52009-08-06 06:41:21 +00001816 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1817 assert(Ovl && "Not a template name or an overload set?");
Mike Stump1eb44332009-09-09 15:08:12 +00001818 OverloadedFunctionDecl *TransOvl
Douglas Gregord1067e52009-08-06 06:41:21 +00001819 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1820 if (!TransOvl)
1821 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001822
Douglas Gregord1067e52009-08-06 06:41:21 +00001823 if (!getDerived().AlwaysRebuild() &&
1824 NNS == QTN->getQualifier() &&
1825 TransOvl == Ovl)
1826 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001827
Douglas Gregord1067e52009-08-06 06:41:21 +00001828 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1829 TransOvl);
1830 }
Mike Stump1eb44332009-09-09 15:08:12 +00001831
Douglas Gregord1067e52009-08-06 06:41:21 +00001832 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001833 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001834 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1835 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001836 if (!NNS && DTN->getQualifier())
Douglas Gregord1067e52009-08-06 06:41:21 +00001837 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001838
Douglas Gregord1067e52009-08-06 06:41:21 +00001839 if (!getDerived().AlwaysRebuild() &&
1840 NNS == DTN->getQualifier())
1841 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001842
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001843 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregord1067e52009-08-06 06:41:21 +00001844 }
Mike Stump1eb44332009-09-09 15:08:12 +00001845
Douglas Gregord1067e52009-08-06 06:41:21 +00001846 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001847 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001848 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1849 if (!TransTemplate)
1850 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001851
Douglas Gregord1067e52009-08-06 06:41:21 +00001852 if (!getDerived().AlwaysRebuild() &&
1853 TransTemplate == Template)
1854 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001855
Douglas Gregord1067e52009-08-06 06:41:21 +00001856 return TemplateName(TransTemplate);
1857 }
Mike Stump1eb44332009-09-09 15:08:12 +00001858
Douglas Gregord1067e52009-08-06 06:41:21 +00001859 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1860 assert(Ovl && "Not a template name or an overload set?");
Mike Stump1eb44332009-09-09 15:08:12 +00001861 OverloadedFunctionDecl *TransOvl
Douglas Gregord1067e52009-08-06 06:41:21 +00001862 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1863 if (!TransOvl)
1864 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001865
Douglas Gregord1067e52009-08-06 06:41:21 +00001866 if (!getDerived().AlwaysRebuild() &&
1867 TransOvl == Ovl)
1868 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001869
Douglas Gregord1067e52009-08-06 06:41:21 +00001870 return TemplateName(TransOvl);
1871}
1872
1873template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001874TemplateArgument
Douglas Gregor670444e2009-08-04 22:27:00 +00001875TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
1876 switch (Arg.getKind()) {
1877 case TemplateArgument::Null:
1878 case TemplateArgument::Integral:
1879 return Arg;
Mike Stump1eb44332009-09-09 15:08:12 +00001880
Douglas Gregor670444e2009-08-04 22:27:00 +00001881 case TemplateArgument::Type: {
1882 QualType T = getDerived().TransformType(Arg.getAsType());
1883 if (T.isNull())
1884 return TemplateArgument();
1885 return TemplateArgument(Arg.getLocation(), T);
1886 }
Mike Stump1eb44332009-09-09 15:08:12 +00001887
Douglas Gregor670444e2009-08-04 22:27:00 +00001888 case TemplateArgument::Declaration: {
1889 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
1890 if (!D)
1891 return TemplateArgument();
1892 return TemplateArgument(Arg.getLocation(), D);
1893 }
Mike Stump1eb44332009-09-09 15:08:12 +00001894
Douglas Gregor670444e2009-08-04 22:27:00 +00001895 case TemplateArgument::Expression: {
1896 // Template argument expressions are not potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00001897 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregor670444e2009-08-04 22:27:00 +00001898 Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00001899
Douglas Gregor670444e2009-08-04 22:27:00 +00001900 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
1901 if (E.isInvalid())
1902 return TemplateArgument();
1903 return TemplateArgument(E.takeAs<Expr>());
1904 }
Mike Stump1eb44332009-09-09 15:08:12 +00001905
Douglas Gregor670444e2009-08-04 22:27:00 +00001906 case TemplateArgument::Pack: {
1907 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1908 TransformedArgs.reserve(Arg.pack_size());
Mike Stump1eb44332009-09-09 15:08:12 +00001909 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregor670444e2009-08-04 22:27:00 +00001910 AEnd = Arg.pack_end();
1911 A != AEnd; ++A) {
1912 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
1913 if (TA.isNull())
1914 return TA;
Mike Stump1eb44332009-09-09 15:08:12 +00001915
Douglas Gregor670444e2009-08-04 22:27:00 +00001916 TransformedArgs.push_back(TA);
1917 }
1918 TemplateArgument Result;
Mike Stump1eb44332009-09-09 15:08:12 +00001919 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregor670444e2009-08-04 22:27:00 +00001920 true);
1921 return Result;
1922 }
1923 }
Mike Stump1eb44332009-09-09 15:08:12 +00001924
Douglas Gregor670444e2009-08-04 22:27:00 +00001925 // Work around bogus GCC warning
1926 return TemplateArgument();
1927}
1928
Douglas Gregor577f75a2009-08-04 16:50:30 +00001929//===----------------------------------------------------------------------===//
1930// Type transformation
1931//===----------------------------------------------------------------------===//
1932
1933template<typename Derived>
1934QualType TreeTransform<Derived>::TransformType(QualType T) {
1935 if (getDerived().AlreadyTransformed(T))
1936 return T;
Mike Stump1eb44332009-09-09 15:08:12 +00001937
John McCall0953e762009-09-24 19:53:00 +00001938 QualifierCollector Qs;
1939 const Type *Ty = Qs.strip(T);
1940
Douglas Gregor577f75a2009-08-04 16:50:30 +00001941 QualType Result;
John McCall0953e762009-09-24 19:53:00 +00001942 switch (Ty->getTypeClass()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001943#define ABSTRACT_TYPE(CLASS, PARENT)
Douglas Gregor577f75a2009-08-04 16:50:30 +00001944#define TYPE(CLASS, PARENT) \
1945 case Type::CLASS: \
1946 Result = getDerived().Transform##CLASS##Type( \
John McCall0953e762009-09-24 19:53:00 +00001947 static_cast<const CLASS##Type*>(Ty)); \
Douglas Gregor577f75a2009-08-04 16:50:30 +00001948 break;
Mike Stump1eb44332009-09-09 15:08:12 +00001949#include "clang/AST/TypeNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +00001950 }
Mike Stump1eb44332009-09-09 15:08:12 +00001951
Douglas Gregor577f75a2009-08-04 16:50:30 +00001952 if (Result.isNull() || T == Result)
1953 return Result;
Mike Stump1eb44332009-09-09 15:08:12 +00001954
John McCall0953e762009-09-24 19:53:00 +00001955 return getDerived().AddTypeQualifiers(Result, Qs);
Douglas Gregor577f75a2009-08-04 16:50:30 +00001956}
Mike Stump1eb44332009-09-09 15:08:12 +00001957
Douglas Gregor577f75a2009-08-04 16:50:30 +00001958template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001959QualType
John McCall0953e762009-09-24 19:53:00 +00001960TreeTransform<Derived>::AddTypeQualifiers(QualType T, Qualifiers Quals) {
1961 if (!Quals.empty() && !T->isFunctionType() && !T->isReferenceType())
1962 return SemaRef.Context.getQualifiedType(T, Quals);
Mike Stump1eb44332009-09-09 15:08:12 +00001963
Douglas Gregor577f75a2009-08-04 16:50:30 +00001964 return T;
1965}
Argyrios Kyrtzidis1bb8a452009-08-19 01:28:17 +00001966
Douglas Gregor577f75a2009-08-04 16:50:30 +00001967template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001968QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00001969 // Nothing to do
Mike Stump1eb44332009-09-09 15:08:12 +00001970 return QualType(T, 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +00001971}
Mike Stump1eb44332009-09-09 15:08:12 +00001972
Douglas Gregor577f75a2009-08-04 16:50:30 +00001973template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001974QualType TreeTransform<Derived>::TransformFixedWidthIntType(
1975 const FixedWidthIntType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00001976 // FIXME: Implement
Mike Stump1eb44332009-09-09 15:08:12 +00001977 return QualType(T, 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +00001978}
Mike Stump1eb44332009-09-09 15:08:12 +00001979
1980template<typename Derived>
1981QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
1982 // FIXME: Implement
1983 return QualType(T, 0);
1984}
1985
1986template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00001987QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
1988 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1989 if (PointeeType.isNull())
1990 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00001991
Douglas Gregor577f75a2009-08-04 16:50:30 +00001992 if (!getDerived().AlwaysRebuild() &&
1993 PointeeType == T->getPointeeType())
1994 return QualType(T, 0);
1995
1996 return getDerived().RebuildPointerType(PointeeType);
1997}
Mike Stump1eb44332009-09-09 15:08:12 +00001998
1999template<typename Derived>
2000QualType
2001TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002002 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2003 if (PointeeType.isNull())
2004 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002005
Douglas Gregor577f75a2009-08-04 16:50:30 +00002006 if (!getDerived().AlwaysRebuild() &&
2007 PointeeType == T->getPointeeType())
2008 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002009
Douglas Gregor577f75a2009-08-04 16:50:30 +00002010 return getDerived().RebuildBlockPointerType(PointeeType);
2011}
2012
Mike Stump1eb44332009-09-09 15:08:12 +00002013template<typename Derived>
2014QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00002015TreeTransform<Derived>::TransformLValueReferenceType(
Mike Stump1eb44332009-09-09 15:08:12 +00002016 const LValueReferenceType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002017 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2018 if (PointeeType.isNull())
2019 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002020
Douglas Gregor577f75a2009-08-04 16:50:30 +00002021 if (!getDerived().AlwaysRebuild() &&
2022 PointeeType == T->getPointeeType())
2023 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002024
Douglas Gregor577f75a2009-08-04 16:50:30 +00002025 return getDerived().RebuildLValueReferenceType(PointeeType);
2026}
2027
Mike Stump1eb44332009-09-09 15:08:12 +00002028template<typename Derived>
2029QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00002030TreeTransform<Derived>::TransformRValueReferenceType(
Mike Stump1eb44332009-09-09 15:08:12 +00002031 const RValueReferenceType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002032 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2033 if (PointeeType.isNull())
2034 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002035
Douglas Gregor577f75a2009-08-04 16:50:30 +00002036 if (!getDerived().AlwaysRebuild() &&
2037 PointeeType == T->getPointeeType())
2038 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002039
Douglas Gregor577f75a2009-08-04 16:50:30 +00002040 return getDerived().RebuildRValueReferenceType(PointeeType);
2041}
Mike Stump1eb44332009-09-09 15:08:12 +00002042
Douglas Gregor577f75a2009-08-04 16:50:30 +00002043template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002044QualType
2045TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002046 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2047 if (PointeeType.isNull())
2048 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002049
Douglas Gregor577f75a2009-08-04 16:50:30 +00002050 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
2051 if (ClassType.isNull())
2052 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002053
Douglas Gregor577f75a2009-08-04 16:50:30 +00002054 if (!getDerived().AlwaysRebuild() &&
2055 PointeeType == T->getPointeeType() &&
2056 ClassType == QualType(T->getClass(), 0))
2057 return QualType(T, 0);
2058
2059 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2060}
2061
Mike Stump1eb44332009-09-09 15:08:12 +00002062template<typename Derived>
2063QualType
2064TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002065 QualType ElementType = getDerived().TransformType(T->getElementType());
2066 if (ElementType.isNull())
2067 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002068
Douglas Gregor577f75a2009-08-04 16:50:30 +00002069 if (!getDerived().AlwaysRebuild() &&
2070 ElementType == T->getElementType())
2071 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002072
2073 return getDerived().RebuildConstantArrayType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002074 T->getSizeModifier(),
2075 T->getSize(),
John McCall0953e762009-09-24 19:53:00 +00002076 T->getIndexTypeCVRQualifiers());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002077}
Mike Stump1eb44332009-09-09 15:08:12 +00002078
Douglas Gregor577f75a2009-08-04 16:50:30 +00002079template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002080QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00002081TreeTransform<Derived>::TransformConstantArrayWithExprType(
Mike Stump1eb44332009-09-09 15:08:12 +00002082 const ConstantArrayWithExprType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002083 QualType ElementType = getDerived().TransformType(T->getElementType());
2084 if (ElementType.isNull())
2085 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002086
Douglas Gregor670444e2009-08-04 22:27:00 +00002087 // Array bounds are not potentially evaluated contexts
2088 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002089
Douglas Gregor670444e2009-08-04 22:27:00 +00002090 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2091 if (Size.isInvalid())
2092 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002093
Douglas Gregor577f75a2009-08-04 16:50:30 +00002094 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor670444e2009-08-04 22:27:00 +00002095 ElementType == T->getElementType() &&
2096 Size.get() == T->getSizeExpr())
Douglas Gregor577f75a2009-08-04 16:50:30 +00002097 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002098
2099 return getDerived().RebuildConstantArrayWithExprType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002100 T->getSizeModifier(),
2101 T->getSize(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002102 Size.takeAs<Expr>(),
John McCall0953e762009-09-24 19:53:00 +00002103 T->getIndexTypeCVRQualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00002104 T->getBracketsRange());
2105}
Mike Stump1eb44332009-09-09 15:08:12 +00002106
2107template<typename Derived>
2108QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00002109TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
Mike Stump1eb44332009-09-09 15:08:12 +00002110 const ConstantArrayWithoutExprType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002111 QualType ElementType = getDerived().TransformType(T->getElementType());
2112 if (ElementType.isNull())
2113 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002114
Douglas Gregor577f75a2009-08-04 16:50:30 +00002115 if (!getDerived().AlwaysRebuild() &&
2116 ElementType == T->getElementType())
2117 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002118
2119 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002120 T->getSizeModifier(),
2121 T->getSize(),
John McCall0953e762009-09-24 19:53:00 +00002122 T->getIndexTypeCVRQualifiers());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002123}
2124
Mike Stump1eb44332009-09-09 15:08:12 +00002125template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002126QualType TreeTransform<Derived>::TransformIncompleteArrayType(
Mike Stump1eb44332009-09-09 15:08:12 +00002127 const IncompleteArrayType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002128 QualType ElementType = getDerived().TransformType(T->getElementType());
2129 if (ElementType.isNull())
2130 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002131
Douglas Gregor577f75a2009-08-04 16:50:30 +00002132 if (!getDerived().AlwaysRebuild() &&
2133 ElementType == T->getElementType())
2134 return QualType(T, 0);
2135
2136 return getDerived().RebuildIncompleteArrayType(ElementType,
2137 T->getSizeModifier(),
John McCall0953e762009-09-24 19:53:00 +00002138 T->getIndexTypeCVRQualifiers());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002139}
Mike Stump1eb44332009-09-09 15:08:12 +00002140
Douglas Gregor577f75a2009-08-04 16:50:30 +00002141template<typename Derived>
2142QualType TreeTransform<Derived>::TransformVariableArrayType(
Mike Stump1eb44332009-09-09 15:08:12 +00002143 const VariableArrayType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002144 QualType ElementType = getDerived().TransformType(T->getElementType());
2145 if (ElementType.isNull())
2146 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002147
Douglas Gregor670444e2009-08-04 22:27:00 +00002148 // Array bounds are not potentially evaluated contexts
2149 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2150
Douglas Gregor577f75a2009-08-04 16:50:30 +00002151 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2152 if (Size.isInvalid())
2153 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002154
Douglas Gregor577f75a2009-08-04 16:50:30 +00002155 if (!getDerived().AlwaysRebuild() &&
2156 ElementType == T->getElementType() &&
2157 Size.get() == T->getSizeExpr()) {
2158 Size.take();
2159 return QualType(T, 0);
2160 }
Mike Stump1eb44332009-09-09 15:08:12 +00002161
2162 return getDerived().RebuildVariableArrayType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002163 T->getSizeModifier(),
2164 move(Size),
John McCall0953e762009-09-24 19:53:00 +00002165 T->getIndexTypeCVRQualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00002166 T->getBracketsRange());
2167}
Mike Stump1eb44332009-09-09 15:08:12 +00002168
2169template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002170QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
Mike Stump1eb44332009-09-09 15:08:12 +00002171 const DependentSizedArrayType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002172 QualType ElementType = getDerived().TransformType(T->getElementType());
2173 if (ElementType.isNull())
2174 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002175
Douglas Gregor670444e2009-08-04 22:27:00 +00002176 // Array bounds are not potentially evaluated contexts
2177 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002178
Douglas Gregor577f75a2009-08-04 16:50:30 +00002179 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2180 if (Size.isInvalid())
2181 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002182
Douglas Gregor577f75a2009-08-04 16:50:30 +00002183 if (!getDerived().AlwaysRebuild() &&
2184 ElementType == T->getElementType() &&
2185 Size.get() == T->getSizeExpr()) {
2186 Size.take();
2187 return QualType(T, 0);
2188 }
Mike Stump1eb44332009-09-09 15:08:12 +00002189
2190 return getDerived().RebuildDependentSizedArrayType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002191 T->getSizeModifier(),
2192 move(Size),
John McCall0953e762009-09-24 19:53:00 +00002193 T->getIndexTypeCVRQualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00002194 T->getBracketsRange());
2195}
Mike Stump1eb44332009-09-09 15:08:12 +00002196
2197template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002198QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
Mike Stump1eb44332009-09-09 15:08:12 +00002199 const DependentSizedExtVectorType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002200 QualType ElementType = getDerived().TransformType(T->getElementType());
2201 if (ElementType.isNull())
2202 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002203
Douglas Gregor670444e2009-08-04 22:27:00 +00002204 // Vector sizes are not potentially evaluated contexts
2205 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2206
Douglas Gregor577f75a2009-08-04 16:50:30 +00002207 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2208 if (Size.isInvalid())
2209 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002210
Douglas Gregor577f75a2009-08-04 16:50:30 +00002211 if (!getDerived().AlwaysRebuild() &&
2212 ElementType == T->getElementType() &&
2213 Size.get() == T->getSizeExpr()) {
2214 Size.take();
2215 return QualType(T, 0);
2216 }
Mike Stump1eb44332009-09-09 15:08:12 +00002217
2218 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002219 move(Size),
2220 T->getAttributeLoc());
2221}
Mike Stump1eb44332009-09-09 15:08:12 +00002222
2223template<typename Derived>
2224QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002225 QualType ElementType = getDerived().TransformType(T->getElementType());
2226 if (ElementType.isNull())
2227 return QualType();
2228
2229 if (!getDerived().AlwaysRebuild() &&
2230 ElementType == T->getElementType())
2231 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002232
Douglas Gregor577f75a2009-08-04 16:50:30 +00002233 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
2234}
Mike Stump1eb44332009-09-09 15:08:12 +00002235
2236template<typename Derived>
2237QualType
2238TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002239 QualType ElementType = getDerived().TransformType(T->getElementType());
2240 if (ElementType.isNull())
2241 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002242
Douglas Gregor577f75a2009-08-04 16:50:30 +00002243 if (!getDerived().AlwaysRebuild() &&
2244 ElementType == T->getElementType())
2245 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002246
Douglas Gregor577f75a2009-08-04 16:50:30 +00002247 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
2248 /*FIXME*/SourceLocation());
2249}
2250
Mike Stump1eb44332009-09-09 15:08:12 +00002251template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002252QualType TreeTransform<Derived>::TransformFunctionProtoType(
Mike Stump1eb44332009-09-09 15:08:12 +00002253 const FunctionProtoType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002254 QualType ResultType = getDerived().TransformType(T->getResultType());
2255 if (ResultType.isNull())
2256 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002257
Douglas Gregor577f75a2009-08-04 16:50:30 +00002258 llvm::SmallVector<QualType, 4> ParamTypes;
2259 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
Mike Stump1eb44332009-09-09 15:08:12 +00002260 ParamEnd = T->arg_type_end();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002261 Param != ParamEnd; ++Param) {
2262 QualType P = getDerived().TransformType(*Param);
2263 if (P.isNull())
2264 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002265
Douglas Gregor577f75a2009-08-04 16:50:30 +00002266 ParamTypes.push_back(P);
2267 }
Mike Stump1eb44332009-09-09 15:08:12 +00002268
Douglas Gregor577f75a2009-08-04 16:50:30 +00002269 if (!getDerived().AlwaysRebuild() &&
2270 ResultType == T->getResultType() &&
2271 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
2272 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002273
2274 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00002275 ParamTypes.size(), T->isVariadic(),
2276 T->getTypeQuals());
2277}
Mike Stump1eb44332009-09-09 15:08:12 +00002278
Douglas Gregor577f75a2009-08-04 16:50:30 +00002279template<typename Derived>
2280QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
Mike Stump1eb44332009-09-09 15:08:12 +00002281 const FunctionNoProtoType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002282 // FIXME: Implement
Mike Stump1eb44332009-09-09 15:08:12 +00002283 return QualType(T, 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002284}
Mike Stump1eb44332009-09-09 15:08:12 +00002285
Douglas Gregor577f75a2009-08-04 16:50:30 +00002286template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002287QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002288 TypedefDecl *Typedef
2289 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2290 if (!Typedef)
2291 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002292
Douglas Gregor577f75a2009-08-04 16:50:30 +00002293 if (!getDerived().AlwaysRebuild() &&
2294 Typedef == T->getDecl())
2295 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002296
Douglas Gregor577f75a2009-08-04 16:50:30 +00002297 return getDerived().RebuildTypedefType(Typedef);
2298}
Mike Stump1eb44332009-09-09 15:08:12 +00002299
Douglas Gregor577f75a2009-08-04 16:50:30 +00002300template<typename Derived>
2301QualType TreeTransform<Derived>::TransformTypeOfExprType(
Mike Stump1eb44332009-09-09 15:08:12 +00002302 const TypeOfExprType *T) {
Douglas Gregor670444e2009-08-04 22:27:00 +00002303 // typeof expressions are not potentially evaluated contexts
2304 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002305
Douglas Gregor577f75a2009-08-04 16:50:30 +00002306 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2307 if (E.isInvalid())
2308 return QualType();
2309
2310 if (!getDerived().AlwaysRebuild() &&
2311 E.get() == T->getUnderlyingExpr()) {
2312 E.take();
2313 return QualType(T, 0);
2314 }
Mike Stump1eb44332009-09-09 15:08:12 +00002315
Douglas Gregor577f75a2009-08-04 16:50:30 +00002316 return getDerived().RebuildTypeOfExprType(move(E));
2317}
Mike Stump1eb44332009-09-09 15:08:12 +00002318
2319template<typename Derived>
2320QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002321 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2322 if (Underlying.isNull())
2323 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002324
Douglas Gregor577f75a2009-08-04 16:50:30 +00002325 if (!getDerived().AlwaysRebuild() &&
2326 Underlying == T->getUnderlyingType())
2327 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002328
Douglas Gregor577f75a2009-08-04 16:50:30 +00002329 return getDerived().RebuildTypeOfType(Underlying);
2330}
Mike Stump1eb44332009-09-09 15:08:12 +00002331
2332template<typename Derived>
2333QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor670444e2009-08-04 22:27:00 +00002334 // decltype expressions are not potentially evaluated contexts
2335 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002336
Douglas Gregor577f75a2009-08-04 16:50:30 +00002337 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2338 if (E.isInvalid())
2339 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002340
Douglas Gregor577f75a2009-08-04 16:50:30 +00002341 if (!getDerived().AlwaysRebuild() &&
2342 E.get() == T->getUnderlyingExpr()) {
2343 E.take();
2344 return QualType(T, 0);
2345 }
Mike Stump1eb44332009-09-09 15:08:12 +00002346
Douglas Gregor577f75a2009-08-04 16:50:30 +00002347 return getDerived().RebuildDecltypeType(move(E));
2348}
2349
2350template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002351QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002352 RecordDecl *Record
2353 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
2354 if (!Record)
2355 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002356
Douglas Gregor577f75a2009-08-04 16:50:30 +00002357 if (!getDerived().AlwaysRebuild() &&
2358 Record == T->getDecl())
2359 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002360
Douglas Gregor577f75a2009-08-04 16:50:30 +00002361 return getDerived().RebuildRecordType(Record);
2362}
Mike Stump1eb44332009-09-09 15:08:12 +00002363
2364template<typename Derived>
2365QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002366 EnumDecl *Enum
2367 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
2368 if (!Enum)
2369 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002370
Douglas Gregor577f75a2009-08-04 16:50:30 +00002371 if (!getDerived().AlwaysRebuild() &&
2372 Enum == T->getDecl())
2373 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002374
Douglas Gregor577f75a2009-08-04 16:50:30 +00002375 return getDerived().RebuildEnumType(Enum);
2376}
John McCall7da24312009-09-05 00:15:47 +00002377
2378template <typename Derived>
2379QualType TreeTransform<Derived>::TransformElaboratedType(
2380 const ElaboratedType *T) {
2381 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2382 if (Underlying.isNull())
2383 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002384
John McCall7da24312009-09-05 00:15:47 +00002385 if (!getDerived().AlwaysRebuild() &&
2386 Underlying == T->getUnderlyingType())
2387 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002388
John McCall7da24312009-09-05 00:15:47 +00002389 return getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2390}
Mike Stump1eb44332009-09-09 15:08:12 +00002391
2392
Douglas Gregor577f75a2009-08-04 16:50:30 +00002393template<typename Derived>
2394QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
Mike Stump1eb44332009-09-09 15:08:12 +00002395 const TemplateTypeParmType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002396 // Nothing to do
Mike Stump1eb44332009-09-09 15:08:12 +00002397 return QualType(T, 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002398}
2399
Mike Stump1eb44332009-09-09 15:08:12 +00002400template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002401QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
Mike Stump1eb44332009-09-09 15:08:12 +00002402 const TemplateSpecializationType *T) {
2403 TemplateName Template
Douglas Gregor577f75a2009-08-04 16:50:30 +00002404 = getDerived().TransformTemplateName(T->getTemplateName());
2405 if (Template.isNull())
2406 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002407
Douglas Gregor577f75a2009-08-04 16:50:30 +00002408 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2409 NewTemplateArgs.reserve(T->getNumArgs());
2410 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2411 Arg != ArgEnd; ++Arg) {
2412 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2413 if (NewArg.isNull())
2414 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002415
Douglas Gregor577f75a2009-08-04 16:50:30 +00002416 NewTemplateArgs.push_back(NewArg);
2417 }
Mike Stump1eb44332009-09-09 15:08:12 +00002418
Douglas Gregor577f75a2009-08-04 16:50:30 +00002419 // FIXME: early abort if all of the template arguments and such are the
2420 // same.
Mike Stump1eb44332009-09-09 15:08:12 +00002421
Douglas Gregor577f75a2009-08-04 16:50:30 +00002422 // FIXME: We're missing the locations of the template name, '<', and '>'.
2423 return getDerived().RebuildTemplateSpecializationType(Template,
2424 NewTemplateArgs.data(),
2425 NewTemplateArgs.size());
2426}
Mike Stump1eb44332009-09-09 15:08:12 +00002427
2428template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002429QualType TreeTransform<Derived>::TransformQualifiedNameType(
2430 const QualifiedNameType *T) {
2431 NestedNameSpecifier *NNS
2432 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2433 SourceRange());
2434 if (!NNS)
2435 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002436
Douglas Gregor577f75a2009-08-04 16:50:30 +00002437 QualType Named = getDerived().TransformType(T->getNamedType());
2438 if (Named.isNull())
2439 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002440
Douglas Gregor577f75a2009-08-04 16:50:30 +00002441 if (!getDerived().AlwaysRebuild() &&
2442 NNS == T->getQualifier() &&
2443 Named == T->getNamedType())
2444 return QualType(T, 0);
2445
2446 return getDerived().RebuildQualifiedNameType(NNS, Named);
2447}
Mike Stump1eb44332009-09-09 15:08:12 +00002448
2449template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002450QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
2451 NestedNameSpecifier *NNS
2452 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor4a959d82009-08-06 16:20:37 +00002453 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002454 if (!NNS)
2455 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002456
Douglas Gregor577f75a2009-08-04 16:50:30 +00002457 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002458 QualType NewTemplateId
Douglas Gregor577f75a2009-08-04 16:50:30 +00002459 = getDerived().TransformType(QualType(TemplateId, 0));
2460 if (NewTemplateId.isNull())
2461 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002462
Douglas Gregor577f75a2009-08-04 16:50:30 +00002463 if (!getDerived().AlwaysRebuild() &&
2464 NNS == T->getQualifier() &&
2465 NewTemplateId == QualType(TemplateId, 0))
2466 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002467
Douglas Gregor577f75a2009-08-04 16:50:30 +00002468 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
2469 }
2470
2471 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
2472}
Mike Stump1eb44332009-09-09 15:08:12 +00002473
Douglas Gregor577f75a2009-08-04 16:50:30 +00002474template<typename Derived>
2475QualType TreeTransform<Derived>::TransformObjCInterfaceType(
Mike Stump1eb44332009-09-09 15:08:12 +00002476 const ObjCInterfaceType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002477 // FIXME: Implement
Mike Stump1eb44332009-09-09 15:08:12 +00002478 return QualType(T, 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002479}
Mike Stump1eb44332009-09-09 15:08:12 +00002480
2481template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002482QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
Mike Stump1eb44332009-09-09 15:08:12 +00002483 const ObjCObjectPointerType *T) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00002484 // FIXME: Implement
Mike Stump1eb44332009-09-09 15:08:12 +00002485 return QualType(T, 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002486}
2487
Argyrios Kyrtzidis24fab412009-09-29 19:42:55 +00002488template<typename Derived>
2489QualType TreeTransform<Derived>::TransformObjCProtocolListType(
2490 const ObjCProtocolListType *T) {
2491 assert(false && "Should not see ObjCProtocolList types");
2492 return QualType(T, 0);
2493}
2494
Douglas Gregor577f75a2009-08-04 16:50:30 +00002495//===----------------------------------------------------------------------===//
Douglas Gregor43959a92009-08-20 07:17:43 +00002496// Statement transformation
2497//===----------------------------------------------------------------------===//
2498template<typename Derived>
2499Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002500TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2501 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002502}
2503
2504template<typename Derived>
2505Sema::OwningStmtResult
2506TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2507 return getDerived().TransformCompoundStmt(S, false);
2508}
2509
2510template<typename Derived>
2511Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002512TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregor43959a92009-08-20 07:17:43 +00002513 bool IsStmtExpr) {
2514 bool SubStmtChanged = false;
2515 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2516 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2517 B != BEnd; ++B) {
2518 OwningStmtResult Result = getDerived().TransformStmt(*B);
2519 if (Result.isInvalid())
2520 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002521
Douglas Gregor43959a92009-08-20 07:17:43 +00002522 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2523 Statements.push_back(Result.takeAs<Stmt>());
2524 }
Mike Stump1eb44332009-09-09 15:08:12 +00002525
Douglas Gregor43959a92009-08-20 07:17:43 +00002526 if (!getDerived().AlwaysRebuild() &&
2527 !SubStmtChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00002528 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002529
2530 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2531 move_arg(Statements),
2532 S->getRBracLoc(),
2533 IsStmtExpr);
2534}
Mike Stump1eb44332009-09-09 15:08:12 +00002535
Douglas Gregor43959a92009-08-20 07:17:43 +00002536template<typename Derived>
2537Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002538TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002539 // The case value expressions are not potentially evaluated.
2540 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002541
Douglas Gregor43959a92009-08-20 07:17:43 +00002542 // Transform the left-hand case value.
2543 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2544 if (LHS.isInvalid())
2545 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002546
Douglas Gregor43959a92009-08-20 07:17:43 +00002547 // Transform the right-hand case value (for the GNU case-range extension).
2548 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2549 if (RHS.isInvalid())
2550 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002551
Douglas Gregor43959a92009-08-20 07:17:43 +00002552 // Build the case statement.
2553 // Case statements are always rebuilt so that they will attached to their
2554 // transformed switch statement.
2555 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2556 move(LHS),
2557 S->getEllipsisLoc(),
2558 move(RHS),
2559 S->getColonLoc());
2560 if (Case.isInvalid())
2561 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002562
Douglas Gregor43959a92009-08-20 07:17:43 +00002563 // Transform the statement following the case
2564 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2565 if (SubStmt.isInvalid())
2566 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002567
Douglas Gregor43959a92009-08-20 07:17:43 +00002568 // Attach the body to the case statement
2569 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2570}
2571
2572template<typename Derived>
2573Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002574TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002575 // Transform the statement following the default case
2576 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2577 if (SubStmt.isInvalid())
2578 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002579
Douglas Gregor43959a92009-08-20 07:17:43 +00002580 // Default statements are always rebuilt
2581 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2582 move(SubStmt));
2583}
Mike Stump1eb44332009-09-09 15:08:12 +00002584
Douglas Gregor43959a92009-08-20 07:17:43 +00002585template<typename Derived>
2586Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002587TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002588 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2589 if (SubStmt.isInvalid())
2590 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002591
Douglas Gregor43959a92009-08-20 07:17:43 +00002592 // FIXME: Pass the real colon location in.
2593 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2594 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2595 move(SubStmt));
2596}
Mike Stump1eb44332009-09-09 15:08:12 +00002597
Douglas Gregor43959a92009-08-20 07:17:43 +00002598template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002599Sema::OwningStmtResult
2600TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002601 // Transform the condition
2602 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2603 if (Cond.isInvalid())
2604 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002605
Douglas Gregor43959a92009-08-20 07:17:43 +00002606 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00002607
Douglas Gregor43959a92009-08-20 07:17:43 +00002608 // Transform the "then" branch.
2609 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2610 if (Then.isInvalid())
2611 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002612
Douglas Gregor43959a92009-08-20 07:17:43 +00002613 // Transform the "else" branch.
2614 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2615 if (Else.isInvalid())
2616 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002617
Douglas Gregor43959a92009-08-20 07:17:43 +00002618 if (!getDerived().AlwaysRebuild() &&
2619 FullCond->get() == S->getCond() &&
2620 Then.get() == S->getThen() &&
2621 Else.get() == S->getElse())
Mike Stump1eb44332009-09-09 15:08:12 +00002622 return SemaRef.Owned(S->Retain());
2623
Douglas Gregor43959a92009-08-20 07:17:43 +00002624 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump1eb44332009-09-09 15:08:12 +00002625 S->getElseLoc(), move(Else));
Douglas Gregor43959a92009-08-20 07:17:43 +00002626}
2627
2628template<typename Derived>
2629Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002630TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002631 // Transform the condition.
2632 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2633 if (Cond.isInvalid())
2634 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002635
Douglas Gregor43959a92009-08-20 07:17:43 +00002636 // Rebuild the switch statement.
2637 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2638 if (Switch.isInvalid())
2639 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002640
Douglas Gregor43959a92009-08-20 07:17:43 +00002641 // Transform the body of the switch statement.
2642 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2643 if (Body.isInvalid())
2644 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002645
Douglas Gregor43959a92009-08-20 07:17:43 +00002646 // Complete the switch statement.
2647 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2648 move(Body));
2649}
Mike Stump1eb44332009-09-09 15:08:12 +00002650
Douglas Gregor43959a92009-08-20 07:17:43 +00002651template<typename Derived>
2652Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002653TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002654 // Transform the condition
2655 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2656 if (Cond.isInvalid())
2657 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002658
Douglas Gregor43959a92009-08-20 07:17:43 +00002659 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00002660
Douglas Gregor43959a92009-08-20 07:17:43 +00002661 // Transform the body
2662 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2663 if (Body.isInvalid())
2664 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002665
Douglas Gregor43959a92009-08-20 07:17:43 +00002666 if (!getDerived().AlwaysRebuild() &&
2667 FullCond->get() == S->getCond() &&
2668 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00002669 return SemaRef.Owned(S->Retain());
2670
Douglas Gregor43959a92009-08-20 07:17:43 +00002671 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2672}
Mike Stump1eb44332009-09-09 15:08:12 +00002673
Douglas Gregor43959a92009-08-20 07:17:43 +00002674template<typename Derived>
2675Sema::OwningStmtResult
2676TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2677 // Transform the condition
2678 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2679 if (Cond.isInvalid())
2680 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002681
Douglas Gregor43959a92009-08-20 07:17:43 +00002682 // Transform the body
2683 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2684 if (Body.isInvalid())
2685 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002686
Douglas Gregor43959a92009-08-20 07:17:43 +00002687 if (!getDerived().AlwaysRebuild() &&
2688 Cond.get() == S->getCond() &&
2689 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00002690 return SemaRef.Owned(S->Retain());
2691
Douglas Gregor43959a92009-08-20 07:17:43 +00002692 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
2693 /*FIXME:*/S->getWhileLoc(), move(Cond),
2694 S->getRParenLoc());
2695}
Mike Stump1eb44332009-09-09 15:08:12 +00002696
Douglas Gregor43959a92009-08-20 07:17:43 +00002697template<typename Derived>
2698Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002699TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002700 // Transform the initialization statement
2701 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
2702 if (Init.isInvalid())
2703 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002704
Douglas Gregor43959a92009-08-20 07:17:43 +00002705 // Transform the condition
2706 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2707 if (Cond.isInvalid())
2708 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002709
Douglas Gregor43959a92009-08-20 07:17:43 +00002710 // Transform the increment
2711 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
2712 if (Inc.isInvalid())
2713 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002714
Douglas Gregor43959a92009-08-20 07:17:43 +00002715 // Transform the body
2716 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2717 if (Body.isInvalid())
2718 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002719
Douglas Gregor43959a92009-08-20 07:17:43 +00002720 if (!getDerived().AlwaysRebuild() &&
2721 Init.get() == S->getInit() &&
2722 Cond.get() == S->getCond() &&
2723 Inc.get() == S->getInc() &&
2724 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00002725 return SemaRef.Owned(S->Retain());
2726
Douglas Gregor43959a92009-08-20 07:17:43 +00002727 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
2728 move(Init), move(Cond), move(Inc),
2729 S->getRParenLoc(), move(Body));
2730}
2731
2732template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002733Sema::OwningStmtResult
2734TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002735 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump1eb44332009-09-09 15:08:12 +00002736 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregor43959a92009-08-20 07:17:43 +00002737 S->getLabel());
2738}
2739
2740template<typename Derived>
2741Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002742TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002743 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
2744 if (Target.isInvalid())
2745 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002746
Douglas Gregor43959a92009-08-20 07:17:43 +00002747 if (!getDerived().AlwaysRebuild() &&
2748 Target.get() == S->getTarget())
Mike Stump1eb44332009-09-09 15:08:12 +00002749 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002750
2751 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
2752 move(Target));
2753}
2754
2755template<typename Derived>
2756Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002757TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
2758 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002759}
Mike Stump1eb44332009-09-09 15:08:12 +00002760
Douglas Gregor43959a92009-08-20 07:17:43 +00002761template<typename Derived>
2762Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002763TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
2764 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002765}
Mike Stump1eb44332009-09-09 15:08:12 +00002766
Douglas Gregor43959a92009-08-20 07:17:43 +00002767template<typename Derived>
2768Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002769TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002770 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
2771 if (Result.isInvalid())
2772 return SemaRef.StmtError();
2773
Mike Stump1eb44332009-09-09 15:08:12 +00002774 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregor43959a92009-08-20 07:17:43 +00002775 // to tell whether the return type of the function has changed.
2776 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
2777}
Mike Stump1eb44332009-09-09 15:08:12 +00002778
Douglas Gregor43959a92009-08-20 07:17:43 +00002779template<typename Derived>
2780Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002781TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002782 bool DeclChanged = false;
2783 llvm::SmallVector<Decl *, 4> Decls;
2784 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
2785 D != DEnd; ++D) {
2786 Decl *Transformed = getDerived().TransformDefinition(*D);
2787 if (!Transformed)
2788 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002789
Douglas Gregor43959a92009-08-20 07:17:43 +00002790 if (Transformed != *D)
2791 DeclChanged = true;
Mike Stump1eb44332009-09-09 15:08:12 +00002792
Douglas Gregor43959a92009-08-20 07:17:43 +00002793 Decls.push_back(Transformed);
2794 }
Mike Stump1eb44332009-09-09 15:08:12 +00002795
Douglas Gregor43959a92009-08-20 07:17:43 +00002796 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00002797 return SemaRef.Owned(S->Retain());
2798
2799 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregor43959a92009-08-20 07:17:43 +00002800 S->getStartLoc(), S->getEndLoc());
2801}
Mike Stump1eb44332009-09-09 15:08:12 +00002802
Douglas Gregor43959a92009-08-20 07:17:43 +00002803template<typename Derived>
2804Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002805TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002806 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00002807 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002808}
2809
2810template<typename Derived>
2811Sema::OwningStmtResult
2812TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
2813 // FIXME: Implement!
2814 assert(false && "Inline assembly cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00002815 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002816}
2817
2818
2819template<typename Derived>
2820Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002821TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002822 // FIXME: Implement this
2823 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump1eb44332009-09-09 15:08:12 +00002824 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002825}
Mike Stump1eb44332009-09-09 15:08:12 +00002826
Douglas Gregor43959a92009-08-20 07:17:43 +00002827template<typename Derived>
2828Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002829TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002830 // FIXME: Implement this
2831 assert(false && "Cannot transform an Objective-C @catch statement");
2832 return SemaRef.Owned(S->Retain());
2833}
Mike Stump1eb44332009-09-09 15:08:12 +00002834
Douglas Gregor43959a92009-08-20 07:17:43 +00002835template<typename Derived>
2836Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002837TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002838 // FIXME: Implement this
2839 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump1eb44332009-09-09 15:08:12 +00002840 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002841}
Mike Stump1eb44332009-09-09 15:08:12 +00002842
Douglas Gregor43959a92009-08-20 07:17:43 +00002843template<typename Derived>
2844Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002845TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002846 // FIXME: Implement this
2847 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump1eb44332009-09-09 15:08:12 +00002848 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002849}
Mike Stump1eb44332009-09-09 15:08:12 +00002850
Douglas Gregor43959a92009-08-20 07:17:43 +00002851template<typename Derived>
2852Sema::OwningStmtResult
2853TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00002854 ObjCAtSynchronizedStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002855 // FIXME: Implement this
2856 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump1eb44332009-09-09 15:08:12 +00002857 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002858}
2859
2860template<typename Derived>
2861Sema::OwningStmtResult
2862TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00002863 ObjCForCollectionStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00002864 // FIXME: Implement this
2865 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump1eb44332009-09-09 15:08:12 +00002866 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002867}
2868
2869
2870template<typename Derived>
2871Sema::OwningStmtResult
2872TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
2873 // Transform the exception declaration, if any.
2874 VarDecl *Var = 0;
2875 if (S->getExceptionDecl()) {
2876 VarDecl *ExceptionDecl = S->getExceptionDecl();
2877 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
2878 ExceptionDecl->getDeclName());
2879
2880 QualType T = getDerived().TransformType(ExceptionDecl->getType());
2881 if (T.isNull())
2882 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002883
Douglas Gregor43959a92009-08-20 07:17:43 +00002884 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
2885 T,
2886 ExceptionDecl->getDeclaratorInfo(),
2887 ExceptionDecl->getIdentifier(),
2888 ExceptionDecl->getLocation(),
2889 /*FIXME: Inaccurate*/
2890 SourceRange(ExceptionDecl->getLocation()));
2891 if (!Var || Var->isInvalidDecl()) {
2892 if (Var)
2893 Var->Destroy(SemaRef.Context);
2894 return SemaRef.StmtError();
2895 }
2896 }
Mike Stump1eb44332009-09-09 15:08:12 +00002897
Douglas Gregor43959a92009-08-20 07:17:43 +00002898 // Transform the actual exception handler.
2899 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
2900 if (Handler.isInvalid()) {
2901 if (Var)
2902 Var->Destroy(SemaRef.Context);
2903 return SemaRef.StmtError();
2904 }
Mike Stump1eb44332009-09-09 15:08:12 +00002905
Douglas Gregor43959a92009-08-20 07:17:43 +00002906 if (!getDerived().AlwaysRebuild() &&
2907 !Var &&
2908 Handler.get() == S->getHandlerBlock())
Mike Stump1eb44332009-09-09 15:08:12 +00002909 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002910
2911 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
2912 Var,
2913 move(Handler));
2914}
Mike Stump1eb44332009-09-09 15:08:12 +00002915
Douglas Gregor43959a92009-08-20 07:17:43 +00002916template<typename Derived>
2917Sema::OwningStmtResult
2918TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
2919 // Transform the try block itself.
Mike Stump1eb44332009-09-09 15:08:12 +00002920 OwningStmtResult TryBlock
Douglas Gregor43959a92009-08-20 07:17:43 +00002921 = getDerived().TransformCompoundStmt(S->getTryBlock());
2922 if (TryBlock.isInvalid())
2923 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002924
Douglas Gregor43959a92009-08-20 07:17:43 +00002925 // Transform the handlers.
2926 bool HandlerChanged = false;
2927 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
2928 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +00002929 OwningStmtResult Handler
Douglas Gregor43959a92009-08-20 07:17:43 +00002930 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
2931 if (Handler.isInvalid())
2932 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002933
Douglas Gregor43959a92009-08-20 07:17:43 +00002934 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
2935 Handlers.push_back(Handler.takeAs<Stmt>());
2936 }
Mike Stump1eb44332009-09-09 15:08:12 +00002937
Douglas Gregor43959a92009-08-20 07:17:43 +00002938 if (!getDerived().AlwaysRebuild() &&
2939 TryBlock.get() == S->getTryBlock() &&
2940 !HandlerChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00002941 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002942
2943 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump1eb44332009-09-09 15:08:12 +00002944 move_arg(Handlers));
Douglas Gregor43959a92009-08-20 07:17:43 +00002945}
Mike Stump1eb44332009-09-09 15:08:12 +00002946
Douglas Gregor43959a92009-08-20 07:17:43 +00002947//===----------------------------------------------------------------------===//
Douglas Gregorb98b1992009-08-11 05:31:07 +00002948// Expression transformation
2949//===----------------------------------------------------------------------===//
Mike Stump1eb44332009-09-09 15:08:12 +00002950template<typename Derived>
2951Sema::OwningExprResult
2952TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
2953 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00002954}
Mike Stump1eb44332009-09-09 15:08:12 +00002955
2956template<typename Derived>
2957Sema::OwningExprResult
2958TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
2959 NamedDecl *ND
Douglas Gregorb98b1992009-08-11 05:31:07 +00002960 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
2961 if (!ND)
2962 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00002963
Douglas Gregorb98b1992009-08-11 05:31:07 +00002964 if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
Mike Stump1eb44332009-09-09 15:08:12 +00002965 return SemaRef.Owned(E->Retain());
2966
Douglas Gregorb98b1992009-08-11 05:31:07 +00002967 return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
2968}
Mike Stump1eb44332009-09-09 15:08:12 +00002969
Douglas Gregorb98b1992009-08-11 05:31:07 +00002970template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002971Sema::OwningExprResult
2972TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
2973 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00002974}
Mike Stump1eb44332009-09-09 15:08:12 +00002975
Douglas Gregorb98b1992009-08-11 05:31:07 +00002976template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002977Sema::OwningExprResult
2978TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
2979 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00002980}
Mike Stump1eb44332009-09-09 15:08:12 +00002981
Douglas Gregorb98b1992009-08-11 05:31:07 +00002982template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002983Sema::OwningExprResult
2984TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
2985 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00002986}
Mike Stump1eb44332009-09-09 15:08:12 +00002987
Douglas Gregorb98b1992009-08-11 05:31:07 +00002988template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002989Sema::OwningExprResult
2990TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
2991 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00002992}
Mike Stump1eb44332009-09-09 15:08:12 +00002993
Douglas Gregorb98b1992009-08-11 05:31:07 +00002994template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002995Sema::OwningExprResult
2996TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
2997 return SemaRef.Owned(E->Retain());
2998}
2999
3000template<typename Derived>
3001Sema::OwningExprResult
3002TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003003 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3004 if (SubExpr.isInvalid())
3005 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003006
Douglas Gregorb98b1992009-08-11 05:31:07 +00003007 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003008 return SemaRef.Owned(E->Retain());
3009
3010 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003011 E->getRParen());
3012}
3013
Mike Stump1eb44332009-09-09 15:08:12 +00003014template<typename Derived>
3015Sema::OwningExprResult
3016TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003017 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3018 if (SubExpr.isInvalid())
3019 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003020
Douglas Gregorb98b1992009-08-11 05:31:07 +00003021 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003022 return SemaRef.Owned(E->Retain());
3023
Douglas Gregorb98b1992009-08-11 05:31:07 +00003024 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3025 E->getOpcode(),
3026 move(SubExpr));
3027}
Mike Stump1eb44332009-09-09 15:08:12 +00003028
Douglas Gregorb98b1992009-08-11 05:31:07 +00003029template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003030Sema::OwningExprResult
3031TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003032 if (E->isArgumentType()) {
3033 QualType T = getDerived().TransformType(E->getArgumentType());
3034 if (T.isNull())
3035 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003036
Douglas Gregorb98b1992009-08-11 05:31:07 +00003037 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3038 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003039
3040 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3041 E->isSizeOf(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003042 E->getSourceRange());
3043 }
Mike Stump1eb44332009-09-09 15:08:12 +00003044
Douglas Gregorb98b1992009-08-11 05:31:07 +00003045 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00003046 {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003047 // C++0x [expr.sizeof]p1:
3048 // The operand is either an expression, which is an unevaluated operand
3049 // [...]
3050 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003051
Douglas Gregorb98b1992009-08-11 05:31:07 +00003052 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3053 if (SubExpr.isInvalid())
3054 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003055
Douglas Gregorb98b1992009-08-11 05:31:07 +00003056 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3057 return SemaRef.Owned(E->Retain());
3058 }
Mike Stump1eb44332009-09-09 15:08:12 +00003059
Douglas Gregorb98b1992009-08-11 05:31:07 +00003060 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3061 E->isSizeOf(),
3062 E->getSourceRange());
3063}
Mike Stump1eb44332009-09-09 15:08:12 +00003064
Douglas Gregorb98b1992009-08-11 05:31:07 +00003065template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003066Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003067TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3068 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3069 if (LHS.isInvalid())
3070 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003071
Douglas Gregorb98b1992009-08-11 05:31:07 +00003072 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3073 if (RHS.isInvalid())
3074 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003075
3076
Douglas Gregorb98b1992009-08-11 05:31:07 +00003077 if (!getDerived().AlwaysRebuild() &&
3078 LHS.get() == E->getLHS() &&
3079 RHS.get() == E->getRHS())
3080 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003081
Douglas Gregorb98b1992009-08-11 05:31:07 +00003082 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3083 /*FIXME:*/E->getLHS()->getLocStart(),
3084 move(RHS),
3085 E->getRBracketLoc());
3086}
Mike Stump1eb44332009-09-09 15:08:12 +00003087
3088template<typename Derived>
3089Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003090TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3091 // Transform the callee.
3092 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3093 if (Callee.isInvalid())
3094 return SemaRef.ExprError();
3095
3096 // Transform arguments.
3097 bool ArgChanged = false;
3098 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3099 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3100 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3101 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3102 if (Arg.isInvalid())
3103 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003104
Douglas Gregorb98b1992009-08-11 05:31:07 +00003105 // FIXME: Wrong source location information for the ','.
3106 FakeCommaLocs.push_back(
3107 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump1eb44332009-09-09 15:08:12 +00003108
3109 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003110 Args.push_back(Arg.takeAs<Expr>());
3111 }
Mike Stump1eb44332009-09-09 15:08:12 +00003112
Douglas Gregorb98b1992009-08-11 05:31:07 +00003113 if (!getDerived().AlwaysRebuild() &&
3114 Callee.get() == E->getCallee() &&
3115 !ArgChanged)
3116 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003117
Douglas Gregorb98b1992009-08-11 05:31:07 +00003118 // FIXME: Wrong source location information for the '('.
Mike Stump1eb44332009-09-09 15:08:12 +00003119 SourceLocation FakeLParenLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003120 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3121 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3122 move_arg(Args),
3123 FakeCommaLocs.data(),
3124 E->getRParenLoc());
3125}
Mike Stump1eb44332009-09-09 15:08:12 +00003126
3127template<typename Derived>
3128Sema::OwningExprResult
3129TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003130 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3131 if (Base.isInvalid())
3132 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003133
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003134 NestedNameSpecifier *Qualifier = 0;
3135 if (E->hasQualifier()) {
Mike Stump1eb44332009-09-09 15:08:12 +00003136 Qualifier
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003137 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3138 E->getQualifierRange());
Douglas Gregorc4bf26f2009-09-01 00:37:14 +00003139 if (Qualifier == 0)
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003140 return SemaRef.ExprError();
3141 }
Mike Stump1eb44332009-09-09 15:08:12 +00003142
3143 NamedDecl *Member
Douglas Gregorb98b1992009-08-11 05:31:07 +00003144 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3145 if (!Member)
3146 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003147
Douglas Gregorb98b1992009-08-11 05:31:07 +00003148 if (!getDerived().AlwaysRebuild() &&
3149 Base.get() == E->getBase() &&
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003150 Qualifier == E->getQualifier() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00003151 Member == E->getMemberDecl())
Mike Stump1eb44332009-09-09 15:08:12 +00003152 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003153
3154 // FIXME: Bogus source location for the operator
3155 SourceLocation FakeOperatorLoc
3156 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3157
3158 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3159 E->isArrow(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003160 Qualifier,
3161 E->getQualifierRange(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003162 E->getMemberLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003163 Member);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003164}
Mike Stump1eb44332009-09-09 15:08:12 +00003165
Douglas Gregorb98b1992009-08-11 05:31:07 +00003166template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003167Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003168TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3169 assert(false && "Cannot transform abstract class");
3170 return SemaRef.Owned(E->Retain());
3171}
3172
3173template<typename Derived>
3174Sema::OwningExprResult
3175TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003176 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3177 if (LHS.isInvalid())
3178 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003179
Douglas Gregorb98b1992009-08-11 05:31:07 +00003180 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3181 if (RHS.isInvalid())
3182 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003183
Douglas Gregorb98b1992009-08-11 05:31:07 +00003184 if (!getDerived().AlwaysRebuild() &&
3185 LHS.get() == E->getLHS() &&
3186 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00003187 return SemaRef.Owned(E->Retain());
3188
Douglas Gregorb98b1992009-08-11 05:31:07 +00003189 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3190 move(LHS), move(RHS));
3191}
3192
Mike Stump1eb44332009-09-09 15:08:12 +00003193template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003194Sema::OwningExprResult
3195TreeTransform<Derived>::TransformCompoundAssignOperator(
3196 CompoundAssignOperator *E) {
3197 return getDerived().TransformBinaryOperator(E);
3198}
Mike Stump1eb44332009-09-09 15:08:12 +00003199
Douglas Gregorb98b1992009-08-11 05:31:07 +00003200template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003201Sema::OwningExprResult
3202TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003203 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3204 if (Cond.isInvalid())
3205 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003206
Douglas Gregorb98b1992009-08-11 05:31:07 +00003207 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3208 if (LHS.isInvalid())
3209 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003210
Douglas Gregorb98b1992009-08-11 05:31:07 +00003211 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3212 if (RHS.isInvalid())
3213 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003214
Douglas Gregorb98b1992009-08-11 05:31:07 +00003215 if (!getDerived().AlwaysRebuild() &&
3216 Cond.get() == E->getCond() &&
3217 LHS.get() == E->getLHS() &&
3218 RHS.get() == E->getRHS())
3219 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003220
3221 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003222 E->getQuestionLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003223 move(LHS),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003224 E->getColonLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003225 move(RHS));
3226}
Mike Stump1eb44332009-09-09 15:08:12 +00003227
3228template<typename Derived>
3229Sema::OwningExprResult
3230TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003231 QualType T = getDerived().TransformType(E->getType());
3232 if (T.isNull())
3233 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003234
Douglas Gregorb98b1992009-08-11 05:31:07 +00003235 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3236 if (SubExpr.isInvalid())
3237 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003238
Douglas Gregorb98b1992009-08-11 05:31:07 +00003239 if (!getDerived().AlwaysRebuild() &&
3240 T == E->getType() &&
3241 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003242 return SemaRef.Owned(E->Retain());
3243
Douglas Gregorb98b1992009-08-11 05:31:07 +00003244 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump1eb44332009-09-09 15:08:12 +00003245 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003246 E->isLvalueCast());
3247}
Mike Stump1eb44332009-09-09 15:08:12 +00003248
Douglas Gregorb98b1992009-08-11 05:31:07 +00003249template<typename Derived>
3250Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003251TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3252 assert(false && "Cannot transform abstract class");
3253 return SemaRef.Owned(E->Retain());
3254}
3255
3256template<typename Derived>
3257Sema::OwningExprResult
3258TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003259 QualType T;
3260 {
3261 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003262 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003263 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3264 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003265
Douglas Gregorb98b1992009-08-11 05:31:07 +00003266 T = getDerived().TransformType(E->getTypeAsWritten());
3267 if (T.isNull())
3268 return SemaRef.ExprError();
3269 }
Mike Stump1eb44332009-09-09 15:08:12 +00003270
Douglas Gregorb98b1992009-08-11 05:31:07 +00003271 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3272 if (SubExpr.isInvalid())
3273 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003274
Douglas Gregorb98b1992009-08-11 05:31:07 +00003275 if (!getDerived().AlwaysRebuild() &&
3276 T == E->getTypeAsWritten() &&
3277 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003278 return SemaRef.Owned(E->Retain());
3279
Douglas Gregorb98b1992009-08-11 05:31:07 +00003280 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3281 E->getRParenLoc(),
3282 move(SubExpr));
3283}
Mike Stump1eb44332009-09-09 15:08:12 +00003284
Douglas Gregorb98b1992009-08-11 05:31:07 +00003285template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003286Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003287TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3288 QualType T;
3289 {
3290 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003291 SourceLocation FakeTypeLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003292 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3293 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003294
Douglas Gregorb98b1992009-08-11 05:31:07 +00003295 T = getDerived().TransformType(E->getType());
3296 if (T.isNull())
3297 return SemaRef.ExprError();
3298 }
Mike Stump1eb44332009-09-09 15:08:12 +00003299
Douglas Gregorb98b1992009-08-11 05:31:07 +00003300 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3301 if (Init.isInvalid())
3302 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003303
Douglas Gregorb98b1992009-08-11 05:31:07 +00003304 if (!getDerived().AlwaysRebuild() &&
3305 T == E->getType() &&
3306 Init.get() == E->getInitializer())
Mike Stump1eb44332009-09-09 15:08:12 +00003307 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003308
3309 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3310 /*FIXME:*/E->getInitializer()->getLocEnd(),
3311 move(Init));
3312}
Mike Stump1eb44332009-09-09 15:08:12 +00003313
Douglas Gregorb98b1992009-08-11 05:31:07 +00003314template<typename Derived>
3315Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003316TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003317 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3318 if (Base.isInvalid())
3319 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003320
Douglas Gregorb98b1992009-08-11 05:31:07 +00003321 if (!getDerived().AlwaysRebuild() &&
3322 Base.get() == E->getBase())
Mike Stump1eb44332009-09-09 15:08:12 +00003323 return SemaRef.Owned(E->Retain());
3324
Douglas Gregorb98b1992009-08-11 05:31:07 +00003325 // FIXME: Bad source location
Mike Stump1eb44332009-09-09 15:08:12 +00003326 SourceLocation FakeOperatorLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003327 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3328 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3329 E->getAccessorLoc(),
3330 E->getAccessor());
3331}
Mike Stump1eb44332009-09-09 15:08:12 +00003332
Douglas Gregorb98b1992009-08-11 05:31:07 +00003333template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003334Sema::OwningExprResult
3335TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003336 bool InitChanged = false;
Mike Stump1eb44332009-09-09 15:08:12 +00003337
Douglas Gregorb98b1992009-08-11 05:31:07 +00003338 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3339 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3340 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3341 if (Init.isInvalid())
3342 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003343
Douglas Gregorb98b1992009-08-11 05:31:07 +00003344 InitChanged = InitChanged || Init.get() != E->getInit(I);
3345 Inits.push_back(Init.takeAs<Expr>());
3346 }
Mike Stump1eb44332009-09-09 15:08:12 +00003347
Douglas Gregorb98b1992009-08-11 05:31:07 +00003348 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003349 return SemaRef.Owned(E->Retain());
3350
Douglas Gregorb98b1992009-08-11 05:31:07 +00003351 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3352 E->getRBraceLoc());
3353}
Mike Stump1eb44332009-09-09 15:08:12 +00003354
Douglas Gregorb98b1992009-08-11 05:31:07 +00003355template<typename Derived>
3356Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003357TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003358 Designation Desig;
Mike Stump1eb44332009-09-09 15:08:12 +00003359
Douglas Gregor43959a92009-08-20 07:17:43 +00003360 // transform the initializer value
Douglas Gregorb98b1992009-08-11 05:31:07 +00003361 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3362 if (Init.isInvalid())
3363 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003364
Douglas Gregor43959a92009-08-20 07:17:43 +00003365 // transform the designators.
Douglas Gregorb98b1992009-08-11 05:31:07 +00003366 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3367 bool ExprChanged = false;
3368 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3369 DEnd = E->designators_end();
3370 D != DEnd; ++D) {
3371 if (D->isFieldDesignator()) {
3372 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3373 D->getDotLoc(),
3374 D->getFieldLoc()));
3375 continue;
3376 }
Mike Stump1eb44332009-09-09 15:08:12 +00003377
Douglas Gregorb98b1992009-08-11 05:31:07 +00003378 if (D->isArrayDesignator()) {
3379 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3380 if (Index.isInvalid())
3381 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003382
3383 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003384 D->getLBracketLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003385
Douglas Gregorb98b1992009-08-11 05:31:07 +00003386 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3387 ArrayExprs.push_back(Index.release());
3388 continue;
3389 }
Mike Stump1eb44332009-09-09 15:08:12 +00003390
Douglas Gregorb98b1992009-08-11 05:31:07 +00003391 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump1eb44332009-09-09 15:08:12 +00003392 OwningExprResult Start
Douglas Gregorb98b1992009-08-11 05:31:07 +00003393 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3394 if (Start.isInvalid())
3395 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003396
Douglas Gregorb98b1992009-08-11 05:31:07 +00003397 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3398 if (End.isInvalid())
3399 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003400
3401 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003402 End.get(),
3403 D->getLBracketLoc(),
3404 D->getEllipsisLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003405
Douglas Gregorb98b1992009-08-11 05:31:07 +00003406 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3407 End.get() != E->getArrayRangeEnd(*D);
Mike Stump1eb44332009-09-09 15:08:12 +00003408
Douglas Gregorb98b1992009-08-11 05:31:07 +00003409 ArrayExprs.push_back(Start.release());
3410 ArrayExprs.push_back(End.release());
3411 }
Mike Stump1eb44332009-09-09 15:08:12 +00003412
Douglas Gregorb98b1992009-08-11 05:31:07 +00003413 if (!getDerived().AlwaysRebuild() &&
3414 Init.get() == E->getInit() &&
3415 !ExprChanged)
3416 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003417
Douglas Gregorb98b1992009-08-11 05:31:07 +00003418 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3419 E->getEqualOrColonLoc(),
3420 E->usesGNUSyntax(), move(Init));
3421}
Mike Stump1eb44332009-09-09 15:08:12 +00003422
Douglas Gregorb98b1992009-08-11 05:31:07 +00003423template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003424Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003425TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00003426 ImplicitValueInitExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003427 QualType T = getDerived().TransformType(E->getType());
3428 if (T.isNull())
3429 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003430
Douglas Gregorb98b1992009-08-11 05:31:07 +00003431 if (!getDerived().AlwaysRebuild() &&
3432 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00003433 return SemaRef.Owned(E->Retain());
3434
Douglas Gregorb98b1992009-08-11 05:31:07 +00003435 return getDerived().RebuildImplicitValueInitExpr(T);
3436}
Mike Stump1eb44332009-09-09 15:08:12 +00003437
Douglas Gregorb98b1992009-08-11 05:31:07 +00003438template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003439Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003440TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3441 // FIXME: Do we want the type as written?
3442 QualType T;
Mike Stump1eb44332009-09-09 15:08:12 +00003443
Douglas Gregorb98b1992009-08-11 05:31:07 +00003444 {
3445 // FIXME: Source location isn't quite accurate.
3446 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3447 T = getDerived().TransformType(E->getType());
3448 if (T.isNull())
3449 return SemaRef.ExprError();
3450 }
Mike Stump1eb44332009-09-09 15:08:12 +00003451
Douglas Gregorb98b1992009-08-11 05:31:07 +00003452 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3453 if (SubExpr.isInvalid())
3454 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003455
Douglas Gregorb98b1992009-08-11 05:31:07 +00003456 if (!getDerived().AlwaysRebuild() &&
3457 T == E->getType() &&
3458 SubExpr.get() == E->getSubExpr())
3459 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003460
Douglas Gregorb98b1992009-08-11 05:31:07 +00003461 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3462 T, E->getRParenLoc());
3463}
3464
3465template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003466Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003467TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3468 bool ArgumentChanged = false;
3469 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3470 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3471 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3472 if (Init.isInvalid())
3473 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003474
Douglas Gregorb98b1992009-08-11 05:31:07 +00003475 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3476 Inits.push_back(Init.takeAs<Expr>());
3477 }
Mike Stump1eb44332009-09-09 15:08:12 +00003478
Douglas Gregorb98b1992009-08-11 05:31:07 +00003479 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3480 move_arg(Inits),
3481 E->getRParenLoc());
3482}
Mike Stump1eb44332009-09-09 15:08:12 +00003483
Douglas Gregorb98b1992009-08-11 05:31:07 +00003484/// \brief Transform an address-of-label expression.
3485///
3486/// By default, the transformation of an address-of-label expression always
3487/// rebuilds the expression, so that the label identifier can be resolved to
3488/// the corresponding label statement by semantic analysis.
3489template<typename Derived>
3490Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003491TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003492 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3493 E->getLabel());
3494}
Mike Stump1eb44332009-09-09 15:08:12 +00003495
3496template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003497Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump1eb44332009-09-09 15:08:12 +00003498 OwningStmtResult SubStmt
Douglas Gregorb98b1992009-08-11 05:31:07 +00003499 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3500 if (SubStmt.isInvalid())
3501 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003502
Douglas Gregorb98b1992009-08-11 05:31:07 +00003503 if (!getDerived().AlwaysRebuild() &&
3504 SubStmt.get() == E->getSubStmt())
3505 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003506
3507 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003508 move(SubStmt),
3509 E->getRParenLoc());
3510}
Mike Stump1eb44332009-09-09 15:08:12 +00003511
Douglas Gregorb98b1992009-08-11 05:31:07 +00003512template<typename Derived>
3513Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003514TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003515 QualType T1, T2;
3516 {
3517 // FIXME: Source location isn't quite accurate.
3518 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003519
Douglas Gregorb98b1992009-08-11 05:31:07 +00003520 T1 = getDerived().TransformType(E->getArgType1());
3521 if (T1.isNull())
3522 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003523
Douglas Gregorb98b1992009-08-11 05:31:07 +00003524 T2 = getDerived().TransformType(E->getArgType2());
3525 if (T2.isNull())
3526 return SemaRef.ExprError();
3527 }
3528
3529 if (!getDerived().AlwaysRebuild() &&
3530 T1 == E->getArgType1() &&
3531 T2 == E->getArgType2())
Mike Stump1eb44332009-09-09 15:08:12 +00003532 return SemaRef.Owned(E->Retain());
3533
Douglas Gregorb98b1992009-08-11 05:31:07 +00003534 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3535 T1, T2, E->getRParenLoc());
3536}
Mike Stump1eb44332009-09-09 15:08:12 +00003537
Douglas Gregorb98b1992009-08-11 05:31:07 +00003538template<typename Derived>
3539Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003540TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003541 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3542 if (Cond.isInvalid())
3543 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003544
Douglas Gregorb98b1992009-08-11 05:31:07 +00003545 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3546 if (LHS.isInvalid())
3547 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003548
Douglas Gregorb98b1992009-08-11 05:31:07 +00003549 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3550 if (RHS.isInvalid())
3551 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003552
Douglas Gregorb98b1992009-08-11 05:31:07 +00003553 if (!getDerived().AlwaysRebuild() &&
3554 Cond.get() == E->getCond() &&
3555 LHS.get() == E->getLHS() &&
3556 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00003557 return SemaRef.Owned(E->Retain());
3558
Douglas Gregorb98b1992009-08-11 05:31:07 +00003559 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3560 move(Cond), move(LHS), move(RHS),
3561 E->getRParenLoc());
3562}
Mike Stump1eb44332009-09-09 15:08:12 +00003563
Douglas Gregorb98b1992009-08-11 05:31:07 +00003564template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003565Sema::OwningExprResult
3566TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3567 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003568}
3569
3570template<typename Derived>
3571Sema::OwningExprResult
3572TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3573 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3574 if (Callee.isInvalid())
3575 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003576
Douglas Gregorb98b1992009-08-11 05:31:07 +00003577 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3578 if (First.isInvalid())
3579 return SemaRef.ExprError();
3580
3581 OwningExprResult Second(SemaRef);
3582 if (E->getNumArgs() == 2) {
3583 Second = getDerived().TransformExpr(E->getArg(1));
3584 if (Second.isInvalid())
3585 return SemaRef.ExprError();
3586 }
Mike Stump1eb44332009-09-09 15:08:12 +00003587
Douglas Gregorb98b1992009-08-11 05:31:07 +00003588 if (!getDerived().AlwaysRebuild() &&
3589 Callee.get() == E->getCallee() &&
3590 First.get() == E->getArg(0) &&
Mike Stump1eb44332009-09-09 15:08:12 +00003591 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3592 return SemaRef.Owned(E->Retain());
3593
Douglas Gregorb98b1992009-08-11 05:31:07 +00003594 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3595 E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003596 move(Callee),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003597 move(First),
3598 move(Second));
3599}
Mike Stump1eb44332009-09-09 15:08:12 +00003600
Douglas Gregorb98b1992009-08-11 05:31:07 +00003601template<typename Derived>
3602Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003603TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003604 return getDerived().TransformCallExpr(E);
3605}
Mike Stump1eb44332009-09-09 15:08:12 +00003606
Douglas Gregorb98b1992009-08-11 05:31:07 +00003607template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003608Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003609TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3610 QualType ExplicitTy;
3611 {
3612 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003613 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003614 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3615 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003616
Douglas Gregorb98b1992009-08-11 05:31:07 +00003617 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3618 if (ExplicitTy.isNull())
3619 return SemaRef.ExprError();
3620 }
Mike Stump1eb44332009-09-09 15:08:12 +00003621
Douglas Gregorb98b1992009-08-11 05:31:07 +00003622 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3623 if (SubExpr.isInvalid())
3624 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003625
Douglas Gregorb98b1992009-08-11 05:31:07 +00003626 if (!getDerived().AlwaysRebuild() &&
3627 ExplicitTy == E->getTypeAsWritten() &&
3628 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003629 return SemaRef.Owned(E->Retain());
3630
Douglas Gregorb98b1992009-08-11 05:31:07 +00003631 // FIXME: Poor source location information here.
Mike Stump1eb44332009-09-09 15:08:12 +00003632 SourceLocation FakeLAngleLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003633 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3634 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3635 SourceLocation FakeRParenLoc
3636 = SemaRef.PP.getLocForEndOfToken(
3637 E->getSubExpr()->getSourceRange().getEnd());
3638 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003639 E->getStmtClass(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003640 FakeLAngleLoc,
3641 ExplicitTy,
3642 FakeRAngleLoc,
3643 FakeRAngleLoc,
3644 move(SubExpr),
3645 FakeRParenLoc);
3646}
Mike Stump1eb44332009-09-09 15:08:12 +00003647
Douglas Gregorb98b1992009-08-11 05:31:07 +00003648template<typename Derived>
3649Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003650TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003651 return getDerived().TransformCXXNamedCastExpr(E);
3652}
Mike Stump1eb44332009-09-09 15:08:12 +00003653
3654template<typename Derived>
3655Sema::OwningExprResult
3656TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
3657 return getDerived().TransformCXXNamedCastExpr(E);
3658}
3659
Douglas Gregorb98b1992009-08-11 05:31:07 +00003660template<typename Derived>
3661Sema::OwningExprResult
3662TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00003663 CXXReinterpretCastExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003664 return getDerived().TransformCXXNamedCastExpr(E);
3665}
Mike Stump1eb44332009-09-09 15:08:12 +00003666
Douglas Gregorb98b1992009-08-11 05:31:07 +00003667template<typename Derived>
3668Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003669TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003670 return getDerived().TransformCXXNamedCastExpr(E);
3671}
Mike Stump1eb44332009-09-09 15:08:12 +00003672
Douglas Gregorb98b1992009-08-11 05:31:07 +00003673template<typename Derived>
3674Sema::OwningExprResult
3675TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00003676 CXXFunctionalCastExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003677 QualType ExplicitTy;
3678 {
3679 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003680
Douglas Gregorb98b1992009-08-11 05:31:07 +00003681 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3682 if (ExplicitTy.isNull())
3683 return SemaRef.ExprError();
3684 }
Mike Stump1eb44332009-09-09 15:08:12 +00003685
Douglas Gregorb98b1992009-08-11 05:31:07 +00003686 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3687 if (SubExpr.isInvalid())
3688 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003689
Douglas Gregorb98b1992009-08-11 05:31:07 +00003690 if (!getDerived().AlwaysRebuild() &&
3691 ExplicitTy == E->getTypeAsWritten() &&
3692 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003693 return SemaRef.Owned(E->Retain());
3694
Douglas Gregorb98b1992009-08-11 05:31:07 +00003695 // FIXME: The end of the type's source range is wrong
3696 return getDerived().RebuildCXXFunctionalCastExpr(
3697 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
3698 ExplicitTy,
3699 /*FIXME:*/E->getSubExpr()->getLocStart(),
3700 move(SubExpr),
3701 E->getRParenLoc());
3702}
Mike Stump1eb44332009-09-09 15:08:12 +00003703
Douglas Gregorb98b1992009-08-11 05:31:07 +00003704template<typename Derived>
3705Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003706TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003707 if (E->isTypeOperand()) {
3708 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003709
Douglas Gregorb98b1992009-08-11 05:31:07 +00003710 QualType T = getDerived().TransformType(E->getTypeOperand());
3711 if (T.isNull())
3712 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003713
Douglas Gregorb98b1992009-08-11 05:31:07 +00003714 if (!getDerived().AlwaysRebuild() &&
3715 T == E->getTypeOperand())
3716 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003717
Douglas Gregorb98b1992009-08-11 05:31:07 +00003718 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3719 /*FIXME:*/E->getLocStart(),
3720 T,
3721 E->getLocEnd());
3722 }
Mike Stump1eb44332009-09-09 15:08:12 +00003723
Douglas Gregorb98b1992009-08-11 05:31:07 +00003724 // We don't know whether the expression is potentially evaluated until
3725 // after we perform semantic analysis, so the expression is potentially
3726 // potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00003727 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregorb98b1992009-08-11 05:31:07 +00003728 Action::PotentiallyPotentiallyEvaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003729
Douglas Gregorb98b1992009-08-11 05:31:07 +00003730 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
3731 if (SubExpr.isInvalid())
3732 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003733
Douglas Gregorb98b1992009-08-11 05:31:07 +00003734 if (!getDerived().AlwaysRebuild() &&
3735 SubExpr.get() == E->getExprOperand())
Mike Stump1eb44332009-09-09 15:08:12 +00003736 return SemaRef.Owned(E->Retain());
3737
Douglas Gregorb98b1992009-08-11 05:31:07 +00003738 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3739 /*FIXME:*/E->getLocStart(),
3740 move(SubExpr),
3741 E->getLocEnd());
3742}
3743
3744template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003745Sema::OwningExprResult
3746TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
3747 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003748}
Mike Stump1eb44332009-09-09 15:08:12 +00003749
Douglas Gregorb98b1992009-08-11 05:31:07 +00003750template<typename Derived>
3751Sema::OwningExprResult
3752TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00003753 CXXNullPtrLiteralExpr *E) {
3754 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003755}
Mike Stump1eb44332009-09-09 15:08:12 +00003756
Douglas Gregorb98b1992009-08-11 05:31:07 +00003757template<typename Derived>
3758Sema::OwningExprResult
3759TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
3760 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003761
Douglas Gregorb98b1992009-08-11 05:31:07 +00003762 QualType T = getDerived().TransformType(E->getType());
3763 if (T.isNull())
3764 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003765
Douglas Gregorb98b1992009-08-11 05:31:07 +00003766 if (!getDerived().AlwaysRebuild() &&
3767 T == E->getType())
3768 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003769
Douglas Gregorb98b1992009-08-11 05:31:07 +00003770 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
3771}
Mike Stump1eb44332009-09-09 15:08:12 +00003772
Douglas Gregorb98b1992009-08-11 05:31:07 +00003773template<typename Derived>
3774Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003775TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003776 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3777 if (SubExpr.isInvalid())
3778 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003779
Douglas Gregorb98b1992009-08-11 05:31:07 +00003780 if (!getDerived().AlwaysRebuild() &&
3781 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003782 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003783
3784 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
3785}
Mike Stump1eb44332009-09-09 15:08:12 +00003786
Douglas Gregorb98b1992009-08-11 05:31:07 +00003787template<typename Derived>
3788Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003789TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
3790 ParmVarDecl *Param
Douglas Gregorb98b1992009-08-11 05:31:07 +00003791 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
3792 if (!Param)
3793 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003794
Douglas Gregorb98b1992009-08-11 05:31:07 +00003795 if (getDerived().AlwaysRebuild() &&
3796 Param == E->getParam())
3797 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003798
Douglas Gregorb98b1992009-08-11 05:31:07 +00003799 return getDerived().RebuildCXXDefaultArgExpr(Param);
3800}
Mike Stump1eb44332009-09-09 15:08:12 +00003801
Douglas Gregorb98b1992009-08-11 05:31:07 +00003802template<typename Derived>
3803Sema::OwningExprResult
3804TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
3805 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3806
3807 QualType T = getDerived().TransformType(E->getType());
3808 if (T.isNull())
3809 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003810
Douglas Gregorb98b1992009-08-11 05:31:07 +00003811 if (!getDerived().AlwaysRebuild() &&
3812 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00003813 return SemaRef.Owned(E->Retain());
3814
3815 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003816 /*FIXME:*/E->getTypeBeginLoc(),
3817 T,
3818 E->getRParenLoc());
3819}
Mike Stump1eb44332009-09-09 15:08:12 +00003820
Douglas Gregorb98b1992009-08-11 05:31:07 +00003821template<typename Derived>
3822Sema::OwningExprResult
3823TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump1eb44332009-09-09 15:08:12 +00003824 VarDecl *Var
Douglas Gregor43959a92009-08-20 07:17:43 +00003825 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregorb98b1992009-08-11 05:31:07 +00003826 if (!Var)
3827 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003828
Douglas Gregorb98b1992009-08-11 05:31:07 +00003829 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00003830 Var == E->getVarDecl())
Douglas Gregorb98b1992009-08-11 05:31:07 +00003831 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003832
3833 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003834 /*FIXME:*/E->getStartLoc(),
3835 Var);
3836}
Mike Stump1eb44332009-09-09 15:08:12 +00003837
Douglas Gregorb98b1992009-08-11 05:31:07 +00003838template<typename Derived>
3839Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003840TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003841 // Transform the type that we're allocating
3842 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3843 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
3844 if (AllocType.isNull())
3845 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003846
Douglas Gregorb98b1992009-08-11 05:31:07 +00003847 // Transform the size of the array we're allocating (if any).
3848 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
3849 if (ArraySize.isInvalid())
3850 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003851
Douglas Gregorb98b1992009-08-11 05:31:07 +00003852 // Transform the placement arguments (if any).
3853 bool ArgumentChanged = false;
3854 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
3855 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
3856 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
3857 if (Arg.isInvalid())
3858 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003859
Douglas Gregorb98b1992009-08-11 05:31:07 +00003860 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
3861 PlacementArgs.push_back(Arg.take());
3862 }
Mike Stump1eb44332009-09-09 15:08:12 +00003863
Douglas Gregor43959a92009-08-20 07:17:43 +00003864 // transform the constructor arguments (if any).
Douglas Gregorb98b1992009-08-11 05:31:07 +00003865 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
3866 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
3867 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
3868 if (Arg.isInvalid())
3869 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003870
Douglas Gregorb98b1992009-08-11 05:31:07 +00003871 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
3872 ConstructorArgs.push_back(Arg.take());
3873 }
Mike Stump1eb44332009-09-09 15:08:12 +00003874
Douglas Gregorb98b1992009-08-11 05:31:07 +00003875 if (!getDerived().AlwaysRebuild() &&
3876 AllocType == E->getAllocatedType() &&
3877 ArraySize.get() == E->getArraySize() &&
3878 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003879 return SemaRef.Owned(E->Retain());
3880
Douglas Gregorb98b1992009-08-11 05:31:07 +00003881 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
3882 E->isGlobalNew(),
3883 /*FIXME:*/E->getLocStart(),
3884 move_arg(PlacementArgs),
3885 /*FIXME:*/E->getLocStart(),
3886 E->isParenTypeId(),
3887 AllocType,
3888 /*FIXME:*/E->getLocStart(),
3889 /*FIXME:*/SourceRange(),
3890 move(ArraySize),
3891 /*FIXME:*/E->getLocStart(),
3892 move_arg(ConstructorArgs),
Mike Stump1eb44332009-09-09 15:08:12 +00003893 E->getLocEnd());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003894}
Mike Stump1eb44332009-09-09 15:08:12 +00003895
Douglas Gregorb98b1992009-08-11 05:31:07 +00003896template<typename Derived>
3897Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003898TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003899 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
3900 if (Operand.isInvalid())
3901 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003902
Douglas Gregorb98b1992009-08-11 05:31:07 +00003903 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00003904 Operand.get() == E->getArgument())
3905 return SemaRef.Owned(E->Retain());
3906
Douglas Gregorb98b1992009-08-11 05:31:07 +00003907 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
3908 E->isGlobalDelete(),
3909 E->isArrayForm(),
3910 move(Operand));
3911}
Mike Stump1eb44332009-09-09 15:08:12 +00003912
Douglas Gregorb98b1992009-08-11 05:31:07 +00003913template<typename Derived>
3914Sema::OwningExprResult
Douglas Gregora71d8192009-09-04 17:36:40 +00003915TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
3916 CXXPseudoDestructorExpr *E) {
3917 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3918 if (Base.isInvalid())
3919 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003920
Douglas Gregora71d8192009-09-04 17:36:40 +00003921 NestedNameSpecifier *Qualifier
3922 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3923 E->getQualifierRange());
3924 if (E->getQualifier() && !Qualifier)
3925 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003926
Douglas Gregora71d8192009-09-04 17:36:40 +00003927 QualType DestroyedType;
3928 {
3929 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
3930 DestroyedType = getDerived().TransformType(E->getDestroyedType());
3931 if (DestroyedType.isNull())
3932 return SemaRef.ExprError();
3933 }
Mike Stump1eb44332009-09-09 15:08:12 +00003934
Douglas Gregora71d8192009-09-04 17:36:40 +00003935 if (!getDerived().AlwaysRebuild() &&
3936 Base.get() == E->getBase() &&
3937 Qualifier == E->getQualifier() &&
3938 DestroyedType == E->getDestroyedType())
3939 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003940
Douglas Gregora71d8192009-09-04 17:36:40 +00003941 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
3942 E->getOperatorLoc(),
3943 E->isArrow(),
3944 E->getDestroyedTypeLoc(),
3945 DestroyedType,
3946 Qualifier,
3947 E->getQualifierRange());
3948}
Mike Stump1eb44332009-09-09 15:08:12 +00003949
Douglas Gregora71d8192009-09-04 17:36:40 +00003950template<typename Derived>
3951Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003952TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00003953 UnresolvedFunctionNameExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003954 // There is no transformation we can apply to an unresolved function name.
Mike Stump1eb44332009-09-09 15:08:12 +00003955 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003956}
Mike Stump1eb44332009-09-09 15:08:12 +00003957
Douglas Gregorb98b1992009-08-11 05:31:07 +00003958template<typename Derived>
3959Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00003960TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003961 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003962
Douglas Gregorb98b1992009-08-11 05:31:07 +00003963 QualType T = getDerived().TransformType(E->getQueriedType());
3964 if (T.isNull())
3965 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003966
Douglas Gregorb98b1992009-08-11 05:31:07 +00003967 if (!getDerived().AlwaysRebuild() &&
3968 T == E->getQueriedType())
3969 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003970
Douglas Gregorb98b1992009-08-11 05:31:07 +00003971 // FIXME: Bad location information
3972 SourceLocation FakeLParenLoc
3973 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump1eb44332009-09-09 15:08:12 +00003974
3975 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003976 E->getLocStart(),
3977 /*FIXME:*/FakeLParenLoc,
3978 T,
3979 E->getLocEnd());
3980}
Mike Stump1eb44332009-09-09 15:08:12 +00003981
Douglas Gregorb98b1992009-08-11 05:31:07 +00003982template<typename Derived>
3983Sema::OwningExprResult
3984TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
3985 NestedNameSpecifier *NNS
3986 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3987 E->getQualifierRange());
3988 if (!NNS)
3989 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003990
3991 NamedDecl *ND
Douglas Gregorb98b1992009-08-11 05:31:07 +00003992 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3993 if (!ND)
3994 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003995
3996 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00003997 NNS == E->getQualifier() &&
3998 ND == E->getDecl())
Mike Stump1eb44332009-09-09 15:08:12 +00003999 return SemaRef.Owned(E->Retain());
4000
4001 return getDerived().RebuildQualifiedDeclRefExpr(NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004002 E->getQualifierRange(),
4003 ND,
4004 E->getLocation(),
4005 /*FIXME:*/false);
4006}
Mike Stump1eb44332009-09-09 15:08:12 +00004007
Douglas Gregorb98b1992009-08-11 05:31:07 +00004008template<typename Derived>
4009Sema::OwningExprResult
4010TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00004011 UnresolvedDeclRefExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004012 NestedNameSpecifier *NNS
4013 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4014 E->getQualifierRange());
4015 if (!NNS)
4016 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004017
4018 DeclarationName Name
Douglas Gregor81499bb2009-09-03 22:13:48 +00004019 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4020 if (!Name)
4021 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004022
4023 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00004024 NNS == E->getQualifier() &&
4025 Name == E->getDeclName())
Mike Stump1eb44332009-09-09 15:08:12 +00004026 return SemaRef.Owned(E->Retain());
4027
4028 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004029 E->getQualifierRange(),
4030 Name,
4031 E->getLocation(),
4032 /*FIXME:*/false);
4033}
4034
4035template<typename Derived>
4036Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00004037TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
4038 TemplateName Template
Douglas Gregorb98b1992009-08-11 05:31:07 +00004039 = getDerived().TransformTemplateName(E->getTemplateName());
4040 if (Template.isNull())
4041 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004042
Douglas Gregorb98b1992009-08-11 05:31:07 +00004043 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4044 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +00004045 TemplateArgument TransArg
Douglas Gregorb98b1992009-08-11 05:31:07 +00004046 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4047 if (TransArg.isNull())
4048 return SemaRef.ExprError();
4049
4050 TransArgs.push_back(TransArg);
4051 }
4052
4053 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4054 // compare template arguments (yet).
Mike Stump1eb44332009-09-09 15:08:12 +00004055
4056 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregorb98b1992009-08-11 05:31:07 +00004057 // actually refers to a type, in which case the caller is actually dealing
4058 // with a functional cast. Give a reasonable error message!
4059 return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
4060 E->getLAngleLoc(),
4061 TransArgs.data(),
4062 TransArgs.size(),
4063 E->getRAngleLoc());
4064}
4065
4066template<typename Derived>
4067Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00004068TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004069 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4070
4071 QualType T = getDerived().TransformType(E->getType());
4072 if (T.isNull())
4073 return SemaRef.ExprError();
4074
4075 CXXConstructorDecl *Constructor
4076 = cast_or_null<CXXConstructorDecl>(
4077 getDerived().TransformDecl(E->getConstructor()));
4078 if (!Constructor)
4079 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004080
Douglas Gregorb98b1992009-08-11 05:31:07 +00004081 bool ArgumentChanged = false;
4082 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00004083 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004084 ArgEnd = E->arg_end();
4085 Arg != ArgEnd; ++Arg) {
4086 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4087 if (TransArg.isInvalid())
4088 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004089
Douglas Gregorb98b1992009-08-11 05:31:07 +00004090 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4091 Args.push_back(TransArg.takeAs<Expr>());
4092 }
4093
4094 if (!getDerived().AlwaysRebuild() &&
4095 T == E->getType() &&
4096 Constructor == E->getConstructor() &&
4097 !ArgumentChanged)
4098 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004099
Douglas Gregorb98b1992009-08-11 05:31:07 +00004100 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4101 move_arg(Args));
4102}
Mike Stump1eb44332009-09-09 15:08:12 +00004103
Douglas Gregorb98b1992009-08-11 05:31:07 +00004104/// \brief Transform a C++ temporary-binding expression.
4105///
Mike Stump1eb44332009-09-09 15:08:12 +00004106/// The transformation of a temporary-binding expression always attempts to
4107/// bind a new temporary variable to its subexpression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004108/// subexpression itself did not change, because the temporary variable itself
4109/// must be unique.
4110template<typename Derived>
4111Sema::OwningExprResult
4112TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4113 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4114 if (SubExpr.isInvalid())
4115 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004116
Douglas Gregorb98b1992009-08-11 05:31:07 +00004117 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4118}
Mike Stump1eb44332009-09-09 15:08:12 +00004119
4120/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregorb98b1992009-08-11 05:31:07 +00004121/// be destroyed after the expression is evaluated.
4122///
Mike Stump1eb44332009-09-09 15:08:12 +00004123/// The transformation of a full expression always attempts to build a new
4124/// CXXExprWithTemporaries expression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004125/// subexpression itself did not change, because it will need to capture the
4126/// the new temporary variables introduced in the subexpression.
4127template<typename Derived>
4128Sema::OwningExprResult
4129TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump1eb44332009-09-09 15:08:12 +00004130 CXXExprWithTemporaries *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004131 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4132 if (SubExpr.isInvalid())
4133 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004134
Douglas Gregorb98b1992009-08-11 05:31:07 +00004135 return SemaRef.Owned(
4136 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4137 E->shouldDestroyTemporaries()));
4138}
Mike Stump1eb44332009-09-09 15:08:12 +00004139
Douglas Gregorb98b1992009-08-11 05:31:07 +00004140template<typename Derived>
4141Sema::OwningExprResult
4142TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00004143 CXXTemporaryObjectExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004144 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4145 QualType T = getDerived().TransformType(E->getType());
4146 if (T.isNull())
4147 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004148
Douglas Gregorb98b1992009-08-11 05:31:07 +00004149 CXXConstructorDecl *Constructor
4150 = cast_or_null<CXXConstructorDecl>(
4151 getDerived().TransformDecl(E->getConstructor()));
4152 if (!Constructor)
4153 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004154
Douglas Gregorb98b1992009-08-11 05:31:07 +00004155 bool ArgumentChanged = false;
4156 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4157 Args.reserve(E->getNumArgs());
Mike Stump1eb44332009-09-09 15:08:12 +00004158 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004159 ArgEnd = E->arg_end();
4160 Arg != ArgEnd; ++Arg) {
4161 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4162 if (TransArg.isInvalid())
4163 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004164
Douglas Gregorb98b1992009-08-11 05:31:07 +00004165 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4166 Args.push_back((Expr *)TransArg.release());
4167 }
Mike Stump1eb44332009-09-09 15:08:12 +00004168
Douglas Gregorb98b1992009-08-11 05:31:07 +00004169 if (!getDerived().AlwaysRebuild() &&
4170 T == E->getType() &&
4171 Constructor == E->getConstructor() &&
4172 !ArgumentChanged)
4173 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004174
Douglas Gregorb98b1992009-08-11 05:31:07 +00004175 // FIXME: Bogus location information
4176 SourceLocation CommaLoc;
4177 if (Args.size() > 1) {
4178 Expr *First = (Expr *)Args[0];
Mike Stump1eb44332009-09-09 15:08:12 +00004179 CommaLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004180 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4181 }
4182 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4183 T,
4184 /*FIXME:*/E->getTypeBeginLoc(),
4185 move_arg(Args),
4186 &CommaLoc,
4187 E->getLocEnd());
4188}
Mike Stump1eb44332009-09-09 15:08:12 +00004189
Douglas Gregorb98b1992009-08-11 05:31:07 +00004190template<typename Derived>
4191Sema::OwningExprResult
4192TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00004193 CXXUnresolvedConstructExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004194 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4195 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4196 if (T.isNull())
4197 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004198
Douglas Gregorb98b1992009-08-11 05:31:07 +00004199 bool ArgumentChanged = false;
4200 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4201 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4202 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4203 ArgEnd = E->arg_end();
4204 Arg != ArgEnd; ++Arg) {
4205 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4206 if (TransArg.isInvalid())
4207 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004208
Douglas Gregorb98b1992009-08-11 05:31:07 +00004209 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4210 FakeCommaLocs.push_back(
4211 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4212 Args.push_back(TransArg.takeAs<Expr>());
4213 }
Mike Stump1eb44332009-09-09 15:08:12 +00004214
Douglas Gregorb98b1992009-08-11 05:31:07 +00004215 if (!getDerived().AlwaysRebuild() &&
4216 T == E->getTypeAsWritten() &&
4217 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004218 return SemaRef.Owned(E->Retain());
4219
Douglas Gregorb98b1992009-08-11 05:31:07 +00004220 // FIXME: we're faking the locations of the commas
4221 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4222 T,
4223 E->getLParenLoc(),
4224 move_arg(Args),
4225 FakeCommaLocs.data(),
4226 E->getRParenLoc());
4227}
Mike Stump1eb44332009-09-09 15:08:12 +00004228
Douglas Gregorb98b1992009-08-11 05:31:07 +00004229template<typename Derived>
4230Sema::OwningExprResult
4231TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00004232 CXXUnresolvedMemberExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004233 // Transform the base of the expression.
4234 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4235 if (Base.isInvalid())
4236 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004237
Douglas Gregora38c6872009-09-03 16:14:30 +00004238 Sema::TypeTy *ObjectType = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00004239 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregora38c6872009-09-03 16:14:30 +00004240 E->getOperatorLoc(),
4241 E->isArrow()? tok::arrow : tok::period,
4242 ObjectType);
4243 if (Base.isInvalid())
4244 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004245
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004246 // FIXME: The first qualifier found might be a template type parameter,
4247 // in which case there is no transformed declaration to refer to (it might
4248 // refer to a built-in type!).
Douglas Gregorc68afe22009-09-03 21:38:09 +00004249 NamedDecl *FirstQualifierInScope
4250 = cast_or_null<NamedDecl>(
4251 getDerived().TransformDecl(E->getFirstQualifierFoundInScope()));
Mike Stump1eb44332009-09-09 15:08:12 +00004252
Douglas Gregora38c6872009-09-03 16:14:30 +00004253 NestedNameSpecifier *Qualifier = 0;
4254 if (E->getQualifier()) {
4255 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4256 E->getQualifierRange(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00004257 QualType::getFromOpaquePtr(ObjectType),
4258 FirstQualifierInScope);
Douglas Gregora38c6872009-09-03 16:14:30 +00004259 if (!Qualifier)
4260 return SemaRef.ExprError();
4261 }
Mike Stump1eb44332009-09-09 15:08:12 +00004262
4263 DeclarationName Name
Douglas Gregor81499bb2009-09-03 22:13:48 +00004264 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc());
4265 if (!Name)
4266 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004267
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004268 if (!E->hasExplicitTemplateArgumentList()) {
4269 // This is a reference to a member without an explicitly-specified
4270 // template argument list. Optimize for this common case.
4271 if (!getDerived().AlwaysRebuild() &&
4272 Base.get() == E->getBase() &&
4273 Qualifier == E->getQualifier() &&
4274 Name == E->getMember() &&
4275 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump1eb44332009-09-09 15:08:12 +00004276 return SemaRef.Owned(E->Retain());
4277
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004278 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4279 E->isArrow(),
4280 E->getOperatorLoc(),
4281 Qualifier,
4282 E->getQualifierRange(),
4283 Name,
4284 E->getMemberLoc(),
4285 FirstQualifierInScope);
4286 }
4287
4288 // FIXME: This is an ugly hack, which forces the same template name to
4289 // be looked up multiple times. Yuck!
4290 // FIXME: This also won't work for, e.g., x->template operator+<int>
4291 TemplateName OrigTemplateName
4292 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump1eb44332009-09-09 15:08:12 +00004293
4294 TemplateName Template
4295 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004296 QualType::getFromOpaquePtr(ObjectType));
4297 if (Template.isNull())
4298 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004299
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004300 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4301 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +00004302 TemplateArgument TransArg
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004303 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4304 if (TransArg.isNull())
4305 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004306
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004307 TransArgs.push_back(TransArg);
4308 }
Mike Stump1eb44332009-09-09 15:08:12 +00004309
Douglas Gregorb98b1992009-08-11 05:31:07 +00004310 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4311 E->isArrow(),
4312 E->getOperatorLoc(),
Douglas Gregora38c6872009-09-03 16:14:30 +00004313 Qualifier,
4314 E->getQualifierRange(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004315 Template,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004316 E->getMemberLoc(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004317 FirstQualifierInScope,
4318 E->getLAngleLoc(),
4319 TransArgs.data(),
4320 TransArgs.size(),
4321 E->getRAngleLoc());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004322}
4323
4324template<typename Derived>
4325Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00004326TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4327 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004328}
4329
Mike Stump1eb44332009-09-09 15:08:12 +00004330template<typename Derived>
4331Sema::OwningExprResult
4332TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004333 // FIXME: poor source location
4334 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4335 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4336 if (EncodedType.isNull())
4337 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004338
Douglas Gregorb98b1992009-08-11 05:31:07 +00004339 if (!getDerived().AlwaysRebuild() &&
4340 EncodedType == E->getEncodedType())
Mike Stump1eb44332009-09-09 15:08:12 +00004341 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004342
4343 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4344 EncodedType,
4345 E->getRParenLoc());
4346}
Mike Stump1eb44332009-09-09 15:08:12 +00004347
Douglas Gregorb98b1992009-08-11 05:31:07 +00004348template<typename Derived>
4349Sema::OwningExprResult
Mike Stump1eb44332009-09-09 15:08:12 +00004350TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004351 // FIXME: Implement this!
4352 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004353 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004354}
4355
Mike Stump1eb44332009-09-09 15:08:12 +00004356template<typename Derived>
4357Sema::OwningExprResult
4358TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4359 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004360}
4361
Mike Stump1eb44332009-09-09 15:08:12 +00004362template<typename Derived>
4363Sema::OwningExprResult
4364TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4365 ObjCProtocolDecl *Protocol
Douglas Gregorb98b1992009-08-11 05:31:07 +00004366 = cast_or_null<ObjCProtocolDecl>(
4367 getDerived().TransformDecl(E->getProtocol()));
4368 if (!Protocol)
4369 return SemaRef.ExprError();
4370
4371 if (!getDerived().AlwaysRebuild() &&
4372 Protocol == E->getProtocol())
Mike Stump1eb44332009-09-09 15:08:12 +00004373 return SemaRef.Owned(E->Retain());
4374
Douglas Gregorb98b1992009-08-11 05:31:07 +00004375 return getDerived().RebuildObjCProtocolExpr(Protocol,
4376 E->getAtLoc(),
4377 /*FIXME:*/E->getAtLoc(),
4378 /*FIXME:*/E->getAtLoc(),
4379 E->getRParenLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00004380
Douglas Gregorb98b1992009-08-11 05:31:07 +00004381}
4382
Mike Stump1eb44332009-09-09 15:08:12 +00004383template<typename Derived>
4384Sema::OwningExprResult
4385TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004386 // FIXME: Implement this!
4387 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004388 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004389}
4390
Mike Stump1eb44332009-09-09 15:08:12 +00004391template<typename Derived>
4392Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00004393TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4394 // FIXME: Implement this!
4395 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004396 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004397}
4398
Mike Stump1eb44332009-09-09 15:08:12 +00004399template<typename Derived>
4400Sema::OwningExprResult
Fariborz Jahanian09105f52009-08-20 17:02:02 +00004401TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump1eb44332009-09-09 15:08:12 +00004402 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004403 // FIXME: Implement this!
4404 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004405 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004406}
4407
Mike Stump1eb44332009-09-09 15:08:12 +00004408template<typename Derived>
4409Sema::OwningExprResult
4410TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004411 // FIXME: Implement this!
4412 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004413 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004414}
4415
Mike Stump1eb44332009-09-09 15:08:12 +00004416template<typename Derived>
4417Sema::OwningExprResult
4418TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004419 // FIXME: Implement this!
4420 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004421 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004422}
4423
Mike Stump1eb44332009-09-09 15:08:12 +00004424template<typename Derived>
4425Sema::OwningExprResult
4426TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004427 bool ArgumentChanged = false;
4428 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4429 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4430 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4431 if (SubExpr.isInvalid())
4432 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004433
Douglas Gregorb98b1992009-08-11 05:31:07 +00004434 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4435 SubExprs.push_back(SubExpr.takeAs<Expr>());
4436 }
Mike Stump1eb44332009-09-09 15:08:12 +00004437
Douglas Gregorb98b1992009-08-11 05:31:07 +00004438 if (!getDerived().AlwaysRebuild() &&
4439 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004440 return SemaRef.Owned(E->Retain());
4441
Douglas Gregorb98b1992009-08-11 05:31:07 +00004442 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4443 move_arg(SubExprs),
4444 E->getRParenLoc());
4445}
4446
Mike Stump1eb44332009-09-09 15:08:12 +00004447template<typename Derived>
4448Sema::OwningExprResult
4449TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004450 // FIXME: Implement this!
4451 assert(false && "Cannot transform block expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004452 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004453}
4454
Mike Stump1eb44332009-09-09 15:08:12 +00004455template<typename Derived>
4456Sema::OwningExprResult
4457TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004458 // FIXME: Implement this!
4459 assert(false && "Cannot transform block-related expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004460 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004461}
Mike Stump1eb44332009-09-09 15:08:12 +00004462
Douglas Gregorb98b1992009-08-11 05:31:07 +00004463//===----------------------------------------------------------------------===//
Douglas Gregor577f75a2009-08-04 16:50:30 +00004464// Type reconstruction
4465//===----------------------------------------------------------------------===//
4466
Mike Stump1eb44332009-09-09 15:08:12 +00004467template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00004468QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
John McCall0953e762009-09-24 19:53:00 +00004469 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00004470 getDerived().getBaseLocation(),
4471 getDerived().getBaseEntity());
4472}
4473
Mike Stump1eb44332009-09-09 15:08:12 +00004474template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00004475QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
John McCall0953e762009-09-24 19:53:00 +00004476 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00004477 getDerived().getBaseLocation(),
4478 getDerived().getBaseEntity());
4479}
4480
Mike Stump1eb44332009-09-09 15:08:12 +00004481template<typename Derived>
4482QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00004483TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
John McCall0953e762009-09-24 19:53:00 +00004484 return SemaRef.BuildReferenceType(ReferentType, true, Qualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00004485 getDerived().getBaseLocation(),
4486 getDerived().getBaseEntity());
4487}
4488
4489template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004490QualType
4491TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
John McCall0953e762009-09-24 19:53:00 +00004492 return SemaRef.BuildReferenceType(ReferentType, false, Qualifiers(),
Mike Stump1eb44332009-09-09 15:08:12 +00004493 getDerived().getBaseLocation(),
4494 getDerived().getBaseEntity());
4495}
4496
4497template<typename Derived>
4498QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004499 QualType ClassType) {
John McCall0953e762009-09-24 19:53:00 +00004500 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00004501 getDerived().getBaseLocation(),
4502 getDerived().getBaseEntity());
4503}
4504
4505template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004506QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00004507TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4508 ArrayType::ArraySizeModifier SizeMod,
4509 const llvm::APInt *Size,
4510 Expr *SizeExpr,
4511 unsigned IndexTypeQuals,
4512 SourceRange BracketsRange) {
4513 if (SizeExpr || !Size)
4514 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4515 IndexTypeQuals, BracketsRange,
4516 getDerived().getBaseEntity());
Mike Stump1eb44332009-09-09 15:08:12 +00004517
4518 QualType Types[] = {
4519 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4520 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4521 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregor577f75a2009-08-04 16:50:30 +00004522 };
4523 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4524 QualType SizeType;
4525 for (unsigned I = 0; I != NumTypes; ++I)
4526 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4527 SizeType = Types[I];
4528 break;
4529 }
Mike Stump1eb44332009-09-09 15:08:12 +00004530
Douglas Gregor577f75a2009-08-04 16:50:30 +00004531 if (SizeType.isNull())
4532 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump1eb44332009-09-09 15:08:12 +00004533
Douglas Gregor577f75a2009-08-04 16:50:30 +00004534 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00004535 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004536 IndexTypeQuals, BracketsRange,
Mike Stump1eb44332009-09-09 15:08:12 +00004537 getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00004538}
Mike Stump1eb44332009-09-09 15:08:12 +00004539
Douglas Gregor577f75a2009-08-04 16:50:30 +00004540template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004541QualType
4542TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004543 ArrayType::ArraySizeModifier SizeMod,
4544 const llvm::APInt &Size,
4545 unsigned IndexTypeQuals) {
Mike Stump1eb44332009-09-09 15:08:12 +00004546 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004547 IndexTypeQuals, SourceRange());
4548}
4549
4550template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004551QualType
4552TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004553 ArrayType::ArraySizeModifier SizeMod,
4554 const llvm::APInt &Size,
4555 Expr *SizeExpr,
4556 unsigned IndexTypeQuals,
4557 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00004558 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004559 IndexTypeQuals, BracketsRange);
4560}
4561
4562template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004563QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00004564TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
Mike Stump1eb44332009-09-09 15:08:12 +00004565 QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004566 ArrayType::ArraySizeModifier SizeMod,
4567 const llvm::APInt &Size,
4568 unsigned IndexTypeQuals) {
Mike Stump1eb44332009-09-09 15:08:12 +00004569 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004570 IndexTypeQuals, SourceRange());
4571}
4572
4573template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004574QualType
4575TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004576 ArrayType::ArraySizeModifier SizeMod,
4577 unsigned IndexTypeQuals) {
Mike Stump1eb44332009-09-09 15:08:12 +00004578 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004579 IndexTypeQuals, SourceRange());
4580}
Mike Stump1eb44332009-09-09 15:08:12 +00004581
Douglas Gregor577f75a2009-08-04 16:50:30 +00004582template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004583QualType
4584TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004585 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004586 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004587 unsigned IndexTypeQuals,
4588 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00004589 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004590 SizeExpr.takeAs<Expr>(),
4591 IndexTypeQuals, BracketsRange);
4592}
4593
4594template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004595QualType
4596TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004597 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004598 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004599 unsigned IndexTypeQuals,
4600 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00004601 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004602 SizeExpr.takeAs<Expr>(),
4603 IndexTypeQuals, BracketsRange);
4604}
4605
4606template<typename Derived>
4607QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4608 unsigned NumElements) {
4609 // FIXME: semantic checking!
4610 return SemaRef.Context.getVectorType(ElementType, NumElements);
4611}
Mike Stump1eb44332009-09-09 15:08:12 +00004612
Douglas Gregor577f75a2009-08-04 16:50:30 +00004613template<typename Derived>
4614QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4615 unsigned NumElements,
4616 SourceLocation AttributeLoc) {
4617 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4618 NumElements, true);
4619 IntegerLiteral *VectorSize
Mike Stump1eb44332009-09-09 15:08:12 +00004620 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004621 AttributeLoc);
4622 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4623 AttributeLoc);
4624}
Mike Stump1eb44332009-09-09 15:08:12 +00004625
Douglas Gregor577f75a2009-08-04 16:50:30 +00004626template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004627QualType
4628TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004629 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004630 SourceLocation AttributeLoc) {
4631 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4632}
Mike Stump1eb44332009-09-09 15:08:12 +00004633
Douglas Gregor577f75a2009-08-04 16:50:30 +00004634template<typename Derived>
4635QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +00004636 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004637 unsigned NumParamTypes,
Mike Stump1eb44332009-09-09 15:08:12 +00004638 bool Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004639 unsigned Quals) {
Mike Stump1eb44332009-09-09 15:08:12 +00004640 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004641 Quals,
4642 getDerived().getBaseLocation(),
4643 getDerived().getBaseEntity());
4644}
Mike Stump1eb44332009-09-09 15:08:12 +00004645
Douglas Gregor577f75a2009-08-04 16:50:30 +00004646template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00004647QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00004648 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4649}
4650
4651template<typename Derived>
4652QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4653 return SemaRef.Context.getTypeOfType(Underlying);
4654}
4655
4656template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00004657QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00004658 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4659}
4660
4661template<typename Derived>
4662QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4663 TemplateName Template,
4664 const TemplateArgument *Args,
4665 unsigned NumArgs) {
4666 // FIXME: Missing source locations for the template name, <, >.
4667 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
Mike Stump1eb44332009-09-09 15:08:12 +00004668 SourceLocation(), Args, NumArgs,
4669 SourceLocation());
Douglas Gregor577f75a2009-08-04 16:50:30 +00004670}
Mike Stump1eb44332009-09-09 15:08:12 +00004671
Douglas Gregordcee1a12009-08-06 05:28:30 +00004672template<typename Derived>
4673NestedNameSpecifier *
4674TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4675 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00004676 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004677 QualType ObjectType,
4678 NamedDecl *FirstQualifierInScope) {
Douglas Gregordcee1a12009-08-06 05:28:30 +00004679 CXXScopeSpec SS;
4680 // FIXME: The source location information is all wrong.
4681 SS.setRange(Range);
4682 SS.setScopeRep(Prefix);
4683 return static_cast<NestedNameSpecifier *>(
Mike Stump1eb44332009-09-09 15:08:12 +00004684 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregor495c35d2009-08-25 22:51:20 +00004685 Range.getEnd(), II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004686 ObjectType,
4687 FirstQualifierInScope,
Douglas Gregor495c35d2009-08-25 22:51:20 +00004688 false));
Douglas Gregordcee1a12009-08-06 05:28:30 +00004689}
4690
4691template<typename Derived>
4692NestedNameSpecifier *
4693TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4694 SourceRange Range,
4695 NamespaceDecl *NS) {
4696 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
4697}
4698
4699template<typename Derived>
4700NestedNameSpecifier *
4701TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4702 SourceRange Range,
4703 bool TemplateKW,
4704 QualType T) {
4705 if (T->isDependentType() || T->isRecordType() ||
4706 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall0953e762009-09-24 19:53:00 +00004707 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregordcee1a12009-08-06 05:28:30 +00004708 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
4709 T.getTypePtr());
4710 }
Mike Stump1eb44332009-09-09 15:08:12 +00004711
Douglas Gregordcee1a12009-08-06 05:28:30 +00004712 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
4713 return 0;
4714}
Mike Stump1eb44332009-09-09 15:08:12 +00004715
Douglas Gregord1067e52009-08-06 06:41:21 +00004716template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004717TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00004718TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4719 bool TemplateKW,
4720 TemplateDecl *Template) {
Mike Stump1eb44332009-09-09 15:08:12 +00004721 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregord1067e52009-08-06 06:41:21 +00004722 Template);
4723}
4724
4725template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004726TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00004727TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4728 bool TemplateKW,
4729 OverloadedFunctionDecl *Ovl) {
4730 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
4731}
4732
4733template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004734TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00004735TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004736 const IdentifierInfo &II,
4737 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00004738 CXXScopeSpec SS;
4739 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump1eb44332009-09-09 15:08:12 +00004740 SS.setScopeRep(Qualifier);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004741 return getSema().ActOnDependentTemplateName(
4742 /*FIXME:*/getDerived().getBaseLocation(),
4743 II,
4744 /*FIXME:*/getDerived().getBaseLocation(),
4745 SS,
4746 ObjectType.getAsOpaquePtr())
4747 .template getAsVal<TemplateName>();
Douglas Gregord1067e52009-08-06 06:41:21 +00004748}
Mike Stump1eb44332009-09-09 15:08:12 +00004749
Douglas Gregorb98b1992009-08-11 05:31:07 +00004750template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004751Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00004752TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
4753 SourceLocation OpLoc,
4754 ExprArg Callee,
4755 ExprArg First,
4756 ExprArg Second) {
4757 Expr *FirstExpr = (Expr *)First.get();
4758 Expr *SecondExpr = (Expr *)Second.get();
4759 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump1eb44332009-09-09 15:08:12 +00004760
Douglas Gregorb98b1992009-08-11 05:31:07 +00004761 // Determine whether this should be a builtin operation.
4762 if (SecondExpr == 0 || isPostIncDec) {
4763 if (!FirstExpr->getType()->isOverloadableType()) {
4764 // The argument is not of overloadable type, so try to create a
4765 // built-in unary operation.
Mike Stump1eb44332009-09-09 15:08:12 +00004766 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004767 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump1eb44332009-09-09 15:08:12 +00004768
Douglas Gregorb98b1992009-08-11 05:31:07 +00004769 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
4770 }
4771 } else {
Mike Stump1eb44332009-09-09 15:08:12 +00004772 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00004773 !SecondExpr->getType()->isOverloadableType()) {
4774 // Neither of the arguments is an overloadable type, so try to
4775 // create a built-in binary operation.
4776 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00004777 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00004778 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
4779 if (Result.isInvalid())
4780 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004781
Douglas Gregorb98b1992009-08-11 05:31:07 +00004782 First.release();
4783 Second.release();
4784 return move(Result);
4785 }
4786 }
Mike Stump1eb44332009-09-09 15:08:12 +00004787
4788 // Compute the transformed set of functions (and function templates) to be
Douglas Gregorb98b1992009-08-11 05:31:07 +00004789 // used during overload resolution.
4790 Sema::FunctionSet Functions;
Mike Stump1eb44332009-09-09 15:08:12 +00004791
4792 DeclRefExpr *DRE
Douglas Gregor8f1d89e2009-09-01 16:58:52 +00004793 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Mike Stump1eb44332009-09-09 15:08:12 +00004794
Douglas Gregorb98b1992009-08-11 05:31:07 +00004795 // FIXME: Do we have to check
4796 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor8f1d89e2009-09-01 16:58:52 +00004797 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregorb98b1992009-08-11 05:31:07 +00004798 Functions.insert(*F);
Mike Stump1eb44332009-09-09 15:08:12 +00004799
Douglas Gregorb98b1992009-08-11 05:31:07 +00004800 // Add any functions found via argument-dependent lookup.
4801 Expr *Args[2] = { FirstExpr, SecondExpr };
4802 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump1eb44332009-09-09 15:08:12 +00004803 DeclarationName OpName
Douglas Gregorb98b1992009-08-11 05:31:07 +00004804 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
4805 SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
Mike Stump1eb44332009-09-09 15:08:12 +00004806
Douglas Gregorb98b1992009-08-11 05:31:07 +00004807 // Create the overloaded operator invocation for unary operators.
4808 if (NumArgs == 1 || isPostIncDec) {
Mike Stump1eb44332009-09-09 15:08:12 +00004809 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004810 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4811 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
4812 }
Mike Stump1eb44332009-09-09 15:08:12 +00004813
Douglas Gregorb98b1992009-08-11 05:31:07 +00004814 // Create the overloaded operator invocation for binary operators.
Mike Stump1eb44332009-09-09 15:08:12 +00004815 BinaryOperator::Opcode Opc =
Douglas Gregorb98b1992009-08-11 05:31:07 +00004816 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00004817 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00004818 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
4819 if (Result.isInvalid())
4820 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004821
Douglas Gregorb98b1992009-08-11 05:31:07 +00004822 First.release();
4823 Second.release();
Mike Stump1eb44332009-09-09 15:08:12 +00004824 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004825}
Mike Stump1eb44332009-09-09 15:08:12 +00004826
Douglas Gregor577f75a2009-08-04 16:50:30 +00004827} // end namespace clang
4828
4829#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H