blob: bd7fb4f2f89e15dbfbd01cce29164ab9f58ffd42 [file] [log] [blame]
Douglas Gregor841324a2009-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 Gregor12431cb2009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor72f34bb2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregor9d879762009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregor23a44be2009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
Douglas Gregor9d879762009-08-11 05:31:07 +000025#include "clang/Parse/Ownership.h"
26#include "clang/Parse/Designator.h"
27#include "clang/Lex/Preprocessor.h"
Douglas Gregor841324a2009-08-04 16:50:30 +000028#include <algorithm>
29
30namespace clang {
Mike Stump25cf7602009-09-09 15:08:12 +000031
Douglas Gregor841324a2009-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 Stump25cf7602009-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 Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +000045/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +000060/// Subclasses can customize the transformation at various levels. The
Douglas Gregor2999faa2009-08-04 22:27:00 +000061/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor841324a2009-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 Gregor23a44be2009-08-20 07:17:43 +000068/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregor841324a2009-08-04 16:50:30 +000069/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump25cf7602009-09-09 15:08:12 +000070/// to substitute template arguments for their corresponding template
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +000078/// to avoid traversing nodes that don't need any transformation
Douglas Gregor841324a2009-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 Gregor841324a2009-08-04 16:50:30 +000083template<typename Derived>
84class TreeTransform {
85protected:
86 Sema &SemaRef;
Mike Stump25cf7602009-09-09 15:08:12 +000087
88public:
Douglas Gregor9d879762009-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 Gregor23a44be2009-08-20 07:17:43 +000094 typedef Sema::MultiStmtArg MultiStmtArg;
Mike Stump25cf7602009-09-09 15:08:12 +000095
Douglas Gregor841324a2009-08-04 16:50:30 +000096 /// \brief Initializes a new tree transformer.
97 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump25cf7602009-09-09 15:08:12 +000098
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000103 const Derived &getDerived() const {
104 return static_cast<const Derived&>(*this);
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000110
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000117
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000121 /// By default, returns no source-location information. Subclasses can
Douglas Gregor841324a2009-08-04 16:50:30 +0000122 /// provide an alternative implementation that provides better location
123 /// information.
124 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump25cf7602009-09-09 15:08:12 +0000125
Douglas Gregor841324a2009-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 Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000139
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000146
Douglas Gregor9d879762009-08-11 05:31:07 +0000147 public:
148 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump25cf7602009-09-09 15:08:12 +0000149 DeclarationName Entity) : Self(Self) {
Douglas Gregor9d879762009-08-11 05:31:07 +0000150 OldLocation = Self.getDerived().getBaseLocation();
151 OldEntity = Self.getDerived().getBaseEntity();
152 Self.getDerived().setBase(Location, Entity);
153 }
Mike Stump25cf7602009-09-09 15:08:12 +0000154
Douglas Gregor9d879762009-08-11 05:31:07 +0000155 ~TemporaryBase() {
156 Self.getDerived().setBase(OldLocation, OldEntity);
157 }
158 };
Mike Stump25cf7602009-09-09 15:08:12 +0000159
160 /// \brief Determine whether the given type \p T has already been
Douglas Gregor841324a2009-08-04 16:50:30 +0000161 /// transformed.
162 ///
163 /// Subclasses can provide an alternative implementation of this routine
Mike Stump25cf7602009-09-09 15:08:12 +0000164 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregor841324a2009-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 Stump25cf7602009-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 Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000182
Douglas Gregor841324a2009-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.
191 QualType AddTypeQualifiers(QualType T, unsigned CVRQualifiers);
Mike Stump25cf7602009-09-09 15:08:12 +0000192
Douglas Gregor72f34bb2009-08-06 22:17:10 +0000193 /// \brief Transform the given statement.
Douglas Gregor841324a2009-08-04 16:50:30 +0000194 ///
Mike Stump25cf7602009-09-09 15:08:12 +0000195 /// By default, this routine transforms a statement by delegating to the
Douglas Gregor23a44be2009-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 Gregor9d879762009-08-11 05:31:07 +0000202 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump25cf7602009-09-09 15:08:12 +0000203
Douglas Gregor72f34bb2009-08-06 22:17:10 +0000204 /// \brief Transform the given expression.
205 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000225
Douglas Gregor841324a2009-08-04 16:50:30 +0000226 /// \brief Transform the given declaration, which is referenced from a type
227 /// or expression.
228 ///
Douglas Gregor12431cb2009-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 Gregor23a44be2009-08-20 07:17:43 +0000232
233 /// \brief Transform the definition of the given declaration.
234 ///
Mike Stump25cf7602009-09-09 15:08:12 +0000235 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000238
Douglas Gregor841324a2009-08-04 16:50:30 +0000239 /// \brief Transform the given nested-name-specifier.
240 ///
Mike Stump25cf7602009-09-09 15:08:12 +0000241 /// By default, transforms all of the types and declarations within the
Douglas Gregor12431cb2009-08-06 05:28:30 +0000242 /// nested-name-specifier. Subclasses may override this function to provide
243 /// alternate behavior.
Douglas Gregor841324a2009-08-04 16:50:30 +0000244 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregor0f927cf2009-09-03 16:14:30 +0000245 SourceRange Range,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +0000246 QualType ObjectType = QualType(),
247 NamedDecl *FirstQualifierInScope = 0);
Mike Stump25cf7602009-09-09 15:08:12 +0000248
Douglas Gregora0651052009-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 Stump25cf7602009-09-09 15:08:12 +0000257
Douglas Gregor841324a2009-08-04 16:50:30 +0000258 /// \brief Transform the given template name.
Mike Stump25cf7602009-09-09 15:08:12 +0000259 ///
Douglas Gregor214d0462009-08-06 06:41:21 +0000260 /// By default, transforms the template name by transforming the declarations
Mike Stump25cf7602009-09-09 15:08:12 +0000261 /// and nested-name-specifiers that occur within the template name.
Douglas Gregor214d0462009-08-06 06:41:21 +0000262 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregorcc00fc02009-09-09 00:23:06 +0000263 TemplateName TransformTemplateName(TemplateName Name,
264 QualType ObjectType = QualType());
Mike Stump25cf7602009-09-09 15:08:12 +0000265
Douglas Gregor841324a2009-08-04 16:50:30 +0000266 /// \brief Transform the given template argument.
267 ///
Mike Stump25cf7602009-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 Gregor2999faa2009-08-04 22:27:00 +0000270 /// new template argument from the transformed result. Subclasses may
271 /// override this function to provide alternate behavior.
Douglas Gregor841324a2009-08-04 16:50:30 +0000272 TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
Mike Stump25cf7602009-09-09 15:08:12 +0000273
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000277#include "clang/AST/TypeNodes.def"
Douglas Gregor841324a2009-08-04 16:50:30 +0000278
Douglas Gregor23a44be2009-08-20 07:17:43 +0000279 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump25cf7602009-09-09 15:08:12 +0000280
Douglas Gregor23a44be2009-08-20 07:17:43 +0000281#define STMT(Node, Parent) \
282 OwningStmtResult Transform##Node(Node *S);
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000287
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000296 /// By default, performs semantic analysis when building the block pointer
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000311
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000318
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000325 /// Also by default, all of the other Rebuild*Array
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000332
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000338 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000344 /// modifier, (known) size of the array, size expression, and index type
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000349 QualType RebuildConstantArrayWithExprType(QualType ElementType,
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000361 QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000371 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +0000372 ArrayType::ArraySizeModifier SizeMod,
373 unsigned IndexTypeQuals);
374
Mike Stump25cf7602009-09-09 15:08:12 +0000375 /// \brief Build a new variable-length array type given the element type,
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000380 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +0000381 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +0000382 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +0000383 unsigned IndexTypeQuals,
384 SourceRange BracketsRange);
385
Mike Stump25cf7602009-09-09 15:08:12 +0000386 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000391 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +0000392 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +0000393 ExprArg SizeExpr,
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000403
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000411
412 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000417 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregor9d879762009-08-11 05:31:07 +0000418 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +0000419 SourceLocation AttributeLoc);
Mike Stump25cf7602009-09-09 15:08:12 +0000420
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000426 QualType *ParamTypes,
Douglas Gregor841324a2009-08-04 16:50:30 +0000427 unsigned NumParamTypes,
428 bool Variadic, unsigned Quals);
Mike Stump25cf7602009-09-09 15:08:12 +0000429
Douglas Gregor841324a2009-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 McCall379448f2009-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 Stump25cf7602009-09-09 15:08:12 +0000449
450 /// \brief Build a new typeof(expr) type.
Douglas Gregor841324a2009-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 Gregor9d879762009-08-11 05:31:07 +0000454 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregor841324a2009-08-04 16:50:30 +0000455
Mike Stump25cf7602009-09-09 15:08:12 +0000456 /// \brief Build a new typeof(type) type.
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000461 /// \brief Build a new C++0x decltype type.
Douglas Gregor841324a2009-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 Gregor9d879762009-08-11 05:31:07 +0000465 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump25cf7602009-09-09 15:08:12 +0000466
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000475
Douglas Gregor841324a2009-08-04 16:50:30 +0000476 /// \brief Build a new qualified name type.
477 ///
Mike Stump25cf7602009-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 Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000483 }
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000488 /// and the given type. Subclasses may override this routine to provide
Douglas Gregor841324a2009-08-04 16:50:30 +0000489 /// different behavior.
490 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
491 if (NNS->isDependent())
Mike Stump25cf7602009-09-09 15:08:12 +0000492 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregor841324a2009-08-04 16:50:30 +0000493 cast<TemplateSpecializationType>(T));
Mike Stump25cf7602009-09-09 15:08:12 +0000494
Douglas Gregor841324a2009-08-04 16:50:30 +0000495 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump25cf7602009-09-09 15:08:12 +0000496 }
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +0000501 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregor841324a2009-08-04 16:50:30 +0000502 /// different behavior.
Mike Stump25cf7602009-09-09 15:08:12 +0000503 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
Douglas Gregor841324a2009-08-04 16:50:30 +0000504 const IdentifierInfo *Id) {
505 return SemaRef.CheckTypenameType(NNS, *Id,
506 SourceRange(getDerived().getBaseLocation()));
Douglas Gregor12431cb2009-08-06 05:28:30 +0000507 }
Mike Stump25cf7602009-09-09 15:08:12 +0000508
Douglas Gregor12431cb2009-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 Gregor0f927cf2009-09-03 16:14:30 +0000517 IdentifierInfo &II,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +0000518 QualType ObjectType,
519 NamedDecl *FirstQualifierInScope);
Douglas Gregor12431cb2009-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 Gregor214d0462009-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 Stump25cf7602009-09-09 15:08:12 +0000561
Douglas Gregor214d0462009-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 Gregorcc00fc02009-09-09 00:23:06 +0000570 const IdentifierInfo &II,
571 QualType ObjectType);
Mike Stump25cf7602009-09-09 15:08:12 +0000572
573
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000595 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregor23a44be2009-08-20 07:17:43 +0000596 ColonLoc);
597 }
Mike Stump25cf7602009-09-09 15:08:12 +0000598
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000607
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000612 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregor23a44be2009-08-20 07:17:43 +0000613 SourceLocation ColonLoc,
614 StmtArg SubStmt) {
Mike Stump25cf7602009-09-09 15:08:12 +0000615 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregor23a44be2009-08-20 07:17:43 +0000616 /*CurScope=*/0);
617 }
Mike Stump25cf7602009-09-09 15:08:12 +0000618
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000623 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000629
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000634 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
635 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregor23a44be2009-08-20 07:17:43 +0000636 StmtArg Else) {
637 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
638 }
Mike Stump25cf7602009-09-09 15:08:12 +0000639
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000647
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000652 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000667
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000677 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000685 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregor23a44be2009-08-20 07:17:43 +0000686 SourceLocation LParenLoc,
687 StmtArg Init, ExprArg Cond, ExprArg Inc,
688 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump25cf7602009-09-09 15:08:12 +0000689 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregor23a44be2009-08-20 07:17:43 +0000690 move(Inc), RParenLoc, move(Body));
691 }
Mike Stump25cf7602009-09-09 15:08:12 +0000692
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000712
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000719
Douglas Gregor23a44be2009-08-20 07:17:43 +0000720 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
721 }
Mike Stump25cf7602009-09-09 15:08:12 +0000722
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000728 SourceLocation StartLoc,
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000736
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000741 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregor23a44be2009-08-20 07:17:43 +0000742 DeclaratorInfo *Declarator,
743 IdentifierInfo *Name,
744 SourceLocation Loc,
745 SourceRange TypeRange) {
Mike Stump25cf7602009-09-09 15:08:12 +0000746 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000758 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregor23a44be2009-08-20 07:17:43 +0000759 Handler.takeAs<Stmt>()));
760 }
Mike Stump25cf7602009-09-09 15:08:12 +0000761
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +0000771
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000782
Douglas Gregor9d879762009-08-11 05:31:07 +0000783 /// \brief Build a new expression in parentheses.
Mike Stump25cf7602009-09-09 15:08:12 +0000784 ///
Douglas Gregor9d879762009-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 Gregor3e368512009-09-04 17:36:40 +0000792 /// \brief Build a new pseudo-destructor expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000793 ///
Douglas Gregor3e368512009-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 Stump25cf7602009-09-09 15:08:12 +0000809 DeclarationName Name
Douglas Gregor3e368512009-09-04 17:36:40 +0000810 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
811 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump25cf7602009-09-09 15:08:12 +0000812
813 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor3e368512009-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 Stump25cf7602009-09-09 15:08:12 +0000820 }
821
Douglas Gregor9d879762009-08-11 05:31:07 +0000822 /// \brief Build a new unary operator expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000823 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000831
Douglas Gregor9d879762009-08-11 05:31:07 +0000832 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump25cf7602009-09-09 15:08:12 +0000833 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000841 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregor9d879762009-08-11 05:31:07 +0000842 /// argument.
Mike Stump25cf7602009-09-09 15:08:12 +0000843 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000848 OwningExprResult Result
Douglas Gregor9d879762009-08-11 05:31:07 +0000849 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
850 OpLoc, isSizeOf, R);
851 if (Result.isInvalid())
852 return getSema().ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +0000853
Douglas Gregor9d879762009-08-11 05:31:07 +0000854 SubExpr.release();
855 return move(Result);
856 }
Mike Stump25cf7602009-09-09 15:08:12 +0000857
Douglas Gregor9d879762009-08-11 05:31:07 +0000858 /// \brief Build a new array subscript expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000859 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000862 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregor9d879762009-08-11 05:31:07 +0000863 SourceLocation LBracketLoc,
864 ExprArg RHS,
865 SourceLocation RBracketLoc) {
866 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump25cf7602009-09-09 15:08:12 +0000867 LBracketLoc, move(RHS),
Douglas Gregor9d879762009-08-11 05:31:07 +0000868 RBracketLoc);
869 }
870
871 /// \brief Build a new call expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000872 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000884 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000888 bool isArrow,
Douglas Gregorc1991bf2009-08-31 23:41:50 +0000889 NestedNameSpecifier *Qualifier,
890 SourceRange QualifierRange,
891 SourceLocation MemberLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +0000892 NamedDecl *Member) {
Anders Carlsson20c55142009-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 Stump25cf7602009-09-09 15:08:12 +0000896
897 MemberExpr *ME =
Anders Carlsson20c55142009-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 Stump25cf7602009-09-09 15:08:12 +0000903
Douglas Gregorc1991bf2009-08-31 23:41:50 +0000904 CXXScopeSpec SS;
905 if (Qualifier) {
906 SS.setRange(QualifierRange);
907 SS.setScopeRep(Qualifier);
908 }
909
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +0000910 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +0000911 isArrow? tok::arrow : tok::period,
912 MemberLoc,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +0000913 Member->getDeclName(),
Douglas Gregorc1991bf2009-08-31 23:41:50 +0000914 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
915 &SS);
Douglas Gregor9d879762009-08-11 05:31:07 +0000916 }
Mike Stump25cf7602009-09-09 15:08:12 +0000917
Douglas Gregor9d879762009-08-11 05:31:07 +0000918 /// \brief Build a new binary operator expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000919 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000926 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregor9d879762009-08-11 05:31:07 +0000927 (Expr *)RHS.get());
928 if (Result.isInvalid())
929 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +0000930
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000937 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000945 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregor9d879762009-08-11 05:31:07 +0000946 move(LHS), move(RHS));
947 }
948
949 /// \brief Build a new implicit cast expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000950 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000956 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000963 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000976
Douglas Gregor9d879762009-08-11 05:31:07 +0000977 /// \brief Build a new compound literal expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000978 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000988
Douglas Gregor9d879762009-08-11 05:31:07 +0000989 /// \brief Build a new extended vector element access expression.
Mike Stump25cf7602009-09-09 15:08:12 +0000990 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +0000993 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001002
Douglas Gregor9d879762009-08-11 05:31:07 +00001003 /// \brief Build a new initializer list expression.
Mike Stump25cf7602009-09-09 15:08:12 +00001004 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001012
Douglas Gregor9d879762009-08-11 05:31:07 +00001013 /// \brief Build a new designated initializer expression.
Mike Stump25cf7602009-09-09 15:08:12 +00001014 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001027
Douglas Gregor9d879762009-08-11 05:31:07 +00001028 ArrayExprs.release();
1029 return move(Result);
1030 }
Mike Stump25cf7602009-09-09 15:08:12 +00001031
Douglas Gregor9d879762009-08-11 05:31:07 +00001032 /// \brief Build a new value-initialized expression.
Mike Stump25cf7602009-09-09 15:08:12 +00001033 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001040
Douglas Gregor9d879762009-08-11 05:31:07 +00001041 /// \brief Build a new \c va_arg expression.
Mike Stump25cf7602009-09-09 15:08:12 +00001042 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001047 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregor9d879762009-08-11 05:31:07 +00001048 RParenLoc);
1049 }
1050
1051 /// \brief Build a new expression list in parentheses.
Mike Stump25cf7602009-09-09 15:08:12 +00001052 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001060
Douglas Gregor9d879762009-08-11 05:31:07 +00001061 /// \brief Build a new address-of-label expression.
Mike Stump25cf7602009-09-09 15:08:12 +00001062 ///
1063 /// By default, performs semantic analysis, using the name of the label
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001071
Douglas Gregor9d879762009-08-11 05:31:07 +00001072 /// \brief Build a new GNU statement expression.
Mike Stump25cf7602009-09-09 15:08:12 +00001073 ///
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001081
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001094
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001106
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001112 /// operator call into a use of a builtin operator, performing
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001120
1121 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregor9d879762009-08-11 05:31:07 +00001122 /// reinterpret_cast.
1123 ///
1124 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump25cf7602009-09-09 15:08:12 +00001125 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001137 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1138 RAngleLoc, LParenLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +00001139 move(SubExpr), RParenLoc);
1140
1141 case Stmt::CXXDynamicCastExprClass:
Mike Stump25cf7602009-09-09 15:08:12 +00001142 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1143 RAngleLoc, LParenLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +00001144 move(SubExpr), RParenLoc);
Mike Stump25cf7602009-09-09 15:08:12 +00001145
Douglas Gregor9d879762009-08-11 05:31:07 +00001146 case Stmt::CXXReinterpretCastExprClass:
Mike Stump25cf7602009-09-09 15:08:12 +00001147 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1148 RAngleLoc, LParenLoc,
1149 move(SubExpr),
Douglas Gregor9d879762009-08-11 05:31:07 +00001150 RParenLoc);
Mike Stump25cf7602009-09-09 15:08:12 +00001151
Douglas Gregor9d879762009-08-11 05:31:07 +00001152 case Stmt::CXXConstCastExprClass:
Mike Stump25cf7602009-09-09 15:08:12 +00001153 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1154 RAngleLoc, LParenLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +00001155 move(SubExpr), RParenLoc);
Mike Stump25cf7602009-09-09 15:08:12 +00001156
Douglas Gregor9d879762009-08-11 05:31:07 +00001157 default:
1158 assert(false && "Invalid C++ named cast");
1159 break;
1160 }
Mike Stump25cf7602009-09-09 15:08:12 +00001161
Douglas Gregor9d879762009-08-11 05:31:07 +00001162 return getSema().ExprError();
1163 }
Mike Stump25cf7602009-09-09 15:08:12 +00001164
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001177 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001193 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001225 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +00001226 LParenLoc, move(SubExpr), RParenLoc);
1227 }
Mike Stump25cf7602009-09-09 15:08:12 +00001228
Douglas Gregor9d879762009-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 Lattnercf9d6a02009-08-24 05:19:01 +00001238 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregor9d879762009-08-11 05:31:07 +00001239 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1240 T.getAsOpaquePtr(),
1241 LParenLoc,
Chris Lattnercf9d6a02009-08-24 05:19:01 +00001242 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump25cf7602009-09-09 15:08:12 +00001243 /*CommaLocs=*/0,
Douglas Gregor9d879762009-08-11 05:31:07 +00001244 RParenLoc);
1245 }
Mike Stump25cf7602009-09-09 15:08:12 +00001246
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001255 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregor9d879762009-08-11 05:31:07 +00001256 T.getAsOpaquePtr(), RParenLoc);
1257 }
Mike Stump25cf7602009-09-09 15:08:12 +00001258
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001267 OwningExprResult Result
Douglas Gregor9d879762009-08-11 05:31:07 +00001268 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1269 RParenLoc);
1270 if (Result.isInvalid())
1271 return getSema().ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00001272
Douglas Gregor9d879762009-08-11 05:31:07 +00001273 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1274 return move(Result);
Mike Stump25cf7602009-09-09 15:08:12 +00001275 }
1276
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001280 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregor9d879762009-08-11 05:31:07 +00001281 /// different behavior.
Mike Stump25cf7602009-09-09 15:08:12 +00001282 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregor9d879762009-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 Carlsson3d752db2009-08-14 18:30:22 +00001302 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001309 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +00001310 SourceLocation LParenLoc,
1311 QualType T,
1312 SourceLocation RParenLoc) {
Mike Stump25cf7602009-09-09 15:08:12 +00001313 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1314 T.getAsOpaquePtr(), LParenLoc,
1315 MultiExprArg(getSema(), 0, 0),
Douglas Gregor9d879762009-08-11 05:31:07 +00001316 0, RParenLoc);
1317 }
Mike Stump25cf7602009-09-09 15:08:12 +00001318
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001323 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001330
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001335 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +00001336 bool UseGlobal,
1337 SourceLocation PlacementLParen,
1338 MultiExprArg PlacementArgs,
1339 SourceLocation PlacementRParen,
Mike Stump25cf7602009-09-09 15:08:12 +00001340 bool ParenTypeId,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001348 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001361
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001373
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001383 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001399 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregor9d879762009-08-11 05:31:07 +00001400 Location,
1401 ND->getDeclName(),
1402 /*Trailing lparen=*/false,
1403 &SS,
1404 IsAddressOfOperand);
1405 }
1406
Mike Stump25cf7602009-09-09 15:08:12 +00001407 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001420 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregor9d879762009-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 Carlssonbf2dfb12009-09-05 07:40:38 +00001452 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1453 SourceLocation(),
1454 T, Constructor, IsElidable,
Anders Carlsson0d49ba62009-09-07 22:23:31 +00001455 move(Args));
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001494
Douglas Gregor9d879762009-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 Gregor6ffe7b42009-08-11 15:56:57 +00001499 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregor9d879762009-08-11 05:31:07 +00001500 bool IsArrow,
1501 SourceLocation OperatorLoc,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001502 NestedNameSpecifier *Qualifier,
1503 SourceRange QualifierRange,
Douglas Gregor9d879762009-08-11 05:31:07 +00001504 DeclarationName Name,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001505 SourceLocation MemberLoc,
1506 NamedDecl *FirstQualifierInScope) {
Douglas Gregor6ffe7b42009-08-11 15:56:57 +00001507 OwningExprResult Base = move(BaseE);
Douglas Gregor9d879762009-08-11 05:31:07 +00001508 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001509
Douglas Gregor9d879762009-08-11 05:31:07 +00001510 CXXScopeSpec SS;
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001511 SS.setRange(QualifierRange);
1512 SS.setScopeRep(Qualifier);
Mike Stump25cf7602009-09-09 15:08:12 +00001513
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001514 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregor9d879762009-08-11 05:31:07 +00001515 move(Base), OperatorLoc, OpKind,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001516 MemberLoc,
1517 Name,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001518 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001519 &SS,
1520 FirstQualifierInScope);
Douglas Gregor9d879762009-08-11 05:31:07 +00001521 }
1522
Douglas Gregorcc00fc02009-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 Stump25cf7602009-09-09 15:08:12 +00001542
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001543 CXXScopeSpec SS;
1544 SS.setRange(QualifierRange);
1545 SS.setScopeRep(Qualifier);
Mike Stump25cf7602009-09-09 15:08:12 +00001546
Douglas Gregorcc00fc02009-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 Stump25cf7602009-09-09 15:08:12 +00001552 else if (OverloadedFunctionDecl *Ovl
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001553 = Template.getAsOverloadedFunctionDecl())
1554 Name = Ovl->getDeclName();
1555 else
1556 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump25cf7602009-09-09 15:08:12 +00001557
1558 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001559 OperatorLoc, OpKind,
1560 TemplateNameLoc, Name, true,
1561 LAngleLoc, TemplateArgs,
1562 NumTemplateArgs, RAngleLoc,
1563 Sema::DeclPtrTy(), &SS);
1564 }
Mike Stump25cf7602009-09-09 15:08:12 +00001565
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001575 }
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001591 RParenLoc));
Douglas Gregor9d879762009-08-11 05:31:07 +00001592 }
Mike Stump25cf7602009-09-09 15:08:12 +00001593
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001602 const IdentifierInfo &Name
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001607
Douglas Gregor9d879762009-08-11 05:31:07 +00001608 // Build a reference to the __builtin_shufflevector builtin
1609 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump25cf7602009-09-09 15:08:12 +00001610 Expr *Callee
Douglas Gregor9d879762009-08-11 05:31:07 +00001611 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1612 BuiltinLoc, false, false);
1613 SemaRef.UsualUnaryConversions(Callee);
Mike Stump25cf7602009-09-09 15:08:12 +00001614
1615 // Build the CallExpr
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001623
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001628
Douglas Gregor9d879762009-08-11 05:31:07 +00001629 OwnedCall.release();
Mike Stump25cf7602009-09-09 15:08:12 +00001630 return move(Result);
Douglas Gregor9d879762009-08-11 05:31:07 +00001631 }
Douglas Gregor841324a2009-08-04 16:50:30 +00001632};
Douglas Gregor9d879762009-08-11 05:31:07 +00001633
Douglas Gregor23a44be2009-08-20 07:17:43 +00001634template<typename Derived>
1635Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1636 if (!S)
1637 return SemaRef.Owned(S);
Mike Stump25cf7602009-09-09 15:08:12 +00001638
Douglas Gregor23a44be2009-08-20 07:17:43 +00001639 switch (S->getStmtClass()) {
1640 case Stmt::NoStmtClass: break;
Mike Stump25cf7602009-09-09 15:08:12 +00001641
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +00001647
Douglas Gregor23a44be2009-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 Stump25cf7602009-09-09 15:08:12 +00001656
Douglas Gregor23a44be2009-08-20 07:17:43 +00001657 return getSema().Owned(E.takeAs<Stmt>());
1658 }
Mike Stump25cf7602009-09-09 15:08:12 +00001659 }
1660
Douglas Gregor23a44be2009-08-20 07:17:43 +00001661 return SemaRef.Owned(S->Retain());
1662}
Mike Stump25cf7602009-09-09 15:08:12 +00001663
1664
Douglas Gregor2999faa2009-08-04 22:27:00 +00001665template<typename Derived>
Douglas Gregor9d879762009-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 Stump25cf7602009-09-09 15:08:12 +00001677 }
1678
Douglas Gregor9d879762009-08-11 05:31:07 +00001679 return SemaRef.Owned(E->Retain());
Douglas Gregor72f34bb2009-08-06 22:17:10 +00001680}
1681
1682template<typename Derived>
Douglas Gregor12431cb2009-08-06 05:28:30 +00001683NestedNameSpecifier *
1684TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001685 SourceRange Range,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001686 QualType ObjectType,
1687 NamedDecl *FirstQualifierInScope) {
Douglas Gregorefccbec2009-08-31 21:41:48 +00001688 if (!NNS)
1689 return 0;
Mike Stump25cf7602009-09-09 15:08:12 +00001690
Douglas Gregor23a44be2009-08-20 07:17:43 +00001691 // Transform the prefix of this nested name specifier.
Douglas Gregor12431cb2009-08-06 05:28:30 +00001692 NestedNameSpecifier *Prefix = NNS->getPrefix();
1693 if (Prefix) {
Mike Stump25cf7602009-09-09 15:08:12 +00001694 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001695 ObjectType,
1696 FirstQualifierInScope);
Douglas Gregor12431cb2009-08-06 05:28:30 +00001697 if (!Prefix)
1698 return 0;
Mike Stump25cf7602009-09-09 15:08:12 +00001699
1700 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001701 // apply to the first element in the nested-name-specifier.
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001702 ObjectType = QualType();
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001703 FirstQualifierInScope = 0;
Douglas Gregor12431cb2009-08-06 05:28:30 +00001704 }
Mike Stump25cf7602009-09-09 15:08:12 +00001705
Douglas Gregor12431cb2009-08-06 05:28:30 +00001706 switch (NNS->getKind()) {
1707 case NestedNameSpecifier::Identifier:
Mike Stump25cf7602009-09-09 15:08:12 +00001708 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregor0f927cf2009-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 Gregor12431cb2009-08-06 05:28:30 +00001712 return NNS;
Mike Stump25cf7602009-09-09 15:08:12 +00001713
1714 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001715 *NNS->getAsIdentifier(),
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001716 ObjectType,
1717 FirstQualifierInScope);
Mike Stump25cf7602009-09-09 15:08:12 +00001718
Douglas Gregor12431cb2009-08-06 05:28:30 +00001719 case NestedNameSpecifier::Namespace: {
Mike Stump25cf7602009-09-09 15:08:12 +00001720 NamespaceDecl *NS
Douglas Gregor12431cb2009-08-06 05:28:30 +00001721 = cast_or_null<NamespaceDecl>(
1722 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump25cf7602009-09-09 15:08:12 +00001723 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor12431cb2009-08-06 05:28:30 +00001724 Prefix == NNS->getPrefix() &&
1725 NS == NNS->getAsNamespace())
1726 return NNS;
Mike Stump25cf7602009-09-09 15:08:12 +00001727
Douglas Gregor12431cb2009-08-06 05:28:30 +00001728 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1729 }
Mike Stump25cf7602009-09-09 15:08:12 +00001730
Douglas Gregor12431cb2009-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 Stump25cf7602009-09-09 15:08:12 +00001735
Douglas Gregor12431cb2009-08-06 05:28:30 +00001736 case NestedNameSpecifier::TypeSpecWithTemplate:
1737 case NestedNameSpecifier::TypeSpec: {
1738 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor214d0462009-08-06 06:41:21 +00001739 if (T.isNull())
1740 return 0;
Mike Stump25cf7602009-09-09 15:08:12 +00001741
Douglas Gregor12431cb2009-08-06 05:28:30 +00001742 if (!getDerived().AlwaysRebuild() &&
1743 Prefix == NNS->getPrefix() &&
1744 T == QualType(NNS->getAsType(), 0))
1745 return NNS;
Mike Stump25cf7602009-09-09 15:08:12 +00001746
1747 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1748 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor12431cb2009-08-06 05:28:30 +00001749 T);
1750 }
1751 }
Mike Stump25cf7602009-09-09 15:08:12 +00001752
Douglas Gregor12431cb2009-08-06 05:28:30 +00001753 // Required to silence a GCC warning
Mike Stump25cf7602009-09-09 15:08:12 +00001754 return 0;
Douglas Gregor12431cb2009-08-06 05:28:30 +00001755}
1756
1757template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00001758DeclarationName
Douglas Gregora0651052009-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 Stump25cf7602009-09-09 15:08:12 +00001772
Douglas Gregora0651052009-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 Stump25cf7602009-09-09 15:08:12 +00001780
Douglas Gregora0651052009-09-03 22:13:48 +00001781 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump25cf7602009-09-09 15:08:12 +00001782 Name.getNameKind(),
Douglas Gregora0651052009-09-03 22:13:48 +00001783 SemaRef.Context.getCanonicalType(T));
Douglas Gregora0651052009-09-03 22:13:48 +00001784 }
Mike Stump25cf7602009-09-09 15:08:12 +00001785 }
1786
Douglas Gregora0651052009-09-03 22:13:48 +00001787 return DeclarationName();
1788}
1789
1790template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00001791TemplateName
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001792TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1793 QualType ObjectType) {
Douglas Gregor214d0462009-08-06 06:41:21 +00001794 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump25cf7602009-09-09 15:08:12 +00001795 NestedNameSpecifier *NNS
Douglas Gregor214d0462009-08-06 06:41:21 +00001796 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1797 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1798 if (!NNS)
1799 return TemplateName();
Mike Stump25cf7602009-09-09 15:08:12 +00001800
Douglas Gregor214d0462009-08-06 06:41:21 +00001801 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump25cf7602009-09-09 15:08:12 +00001802 TemplateDecl *TransTemplate
Douglas Gregor214d0462009-08-06 06:41:21 +00001803 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1804 if (!TransTemplate)
1805 return TemplateName();
Mike Stump25cf7602009-09-09 15:08:12 +00001806
Douglas Gregor214d0462009-08-06 06:41:21 +00001807 if (!getDerived().AlwaysRebuild() &&
1808 NNS == QTN->getQualifier() &&
1809 TransTemplate == Template)
1810 return Name;
Mike Stump25cf7602009-09-09 15:08:12 +00001811
Douglas Gregor214d0462009-08-06 06:41:21 +00001812 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1813 TransTemplate);
1814 }
Mike Stump25cf7602009-09-09 15:08:12 +00001815
Douglas Gregor214d0462009-08-06 06:41:21 +00001816 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1817 assert(Ovl && "Not a template name or an overload set?");
Mike Stump25cf7602009-09-09 15:08:12 +00001818 OverloadedFunctionDecl *TransOvl
Douglas Gregor214d0462009-08-06 06:41:21 +00001819 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1820 if (!TransOvl)
1821 return TemplateName();
Mike Stump25cf7602009-09-09 15:08:12 +00001822
Douglas Gregor214d0462009-08-06 06:41:21 +00001823 if (!getDerived().AlwaysRebuild() &&
1824 NNS == QTN->getQualifier() &&
1825 TransOvl == Ovl)
1826 return Name;
Mike Stump25cf7602009-09-09 15:08:12 +00001827
Douglas Gregor214d0462009-08-06 06:41:21 +00001828 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1829 TransOvl);
1830 }
Mike Stump25cf7602009-09-09 15:08:12 +00001831
Douglas Gregor214d0462009-08-06 06:41:21 +00001832 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump25cf7602009-09-09 15:08:12 +00001833 NestedNameSpecifier *NNS
Douglas Gregor214d0462009-08-06 06:41:21 +00001834 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1835 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001836 if (!NNS && DTN->getQualifier())
Douglas Gregor214d0462009-08-06 06:41:21 +00001837 return TemplateName();
Mike Stump25cf7602009-09-09 15:08:12 +00001838
Douglas Gregor214d0462009-08-06 06:41:21 +00001839 if (!getDerived().AlwaysRebuild() &&
1840 NNS == DTN->getQualifier())
1841 return Name;
Mike Stump25cf7602009-09-09 15:08:12 +00001842
Douglas Gregorcc00fc02009-09-09 00:23:06 +00001843 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregor214d0462009-08-06 06:41:21 +00001844 }
Mike Stump25cf7602009-09-09 15:08:12 +00001845
Douglas Gregor214d0462009-08-06 06:41:21 +00001846 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump25cf7602009-09-09 15:08:12 +00001847 TemplateDecl *TransTemplate
Douglas Gregor214d0462009-08-06 06:41:21 +00001848 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1849 if (!TransTemplate)
1850 return TemplateName();
Mike Stump25cf7602009-09-09 15:08:12 +00001851
Douglas Gregor214d0462009-08-06 06:41:21 +00001852 if (!getDerived().AlwaysRebuild() &&
1853 TransTemplate == Template)
1854 return Name;
Mike Stump25cf7602009-09-09 15:08:12 +00001855
Douglas Gregor214d0462009-08-06 06:41:21 +00001856 return TemplateName(TransTemplate);
1857 }
Mike Stump25cf7602009-09-09 15:08:12 +00001858
Douglas Gregor214d0462009-08-06 06:41:21 +00001859 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1860 assert(Ovl && "Not a template name or an overload set?");
Mike Stump25cf7602009-09-09 15:08:12 +00001861 OverloadedFunctionDecl *TransOvl
Douglas Gregor214d0462009-08-06 06:41:21 +00001862 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1863 if (!TransOvl)
1864 return TemplateName();
Mike Stump25cf7602009-09-09 15:08:12 +00001865
Douglas Gregor214d0462009-08-06 06:41:21 +00001866 if (!getDerived().AlwaysRebuild() &&
1867 TransOvl == Ovl)
1868 return Name;
Mike Stump25cf7602009-09-09 15:08:12 +00001869
Douglas Gregor214d0462009-08-06 06:41:21 +00001870 return TemplateName(TransOvl);
1871}
1872
1873template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00001874TemplateArgument
Douglas Gregor2999faa2009-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 Stump25cf7602009-09-09 15:08:12 +00001880
Douglas Gregor2999faa2009-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 Stump25cf7602009-09-09 15:08:12 +00001887
Douglas Gregor2999faa2009-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 Stump25cf7602009-09-09 15:08:12 +00001894
Douglas Gregor2999faa2009-08-04 22:27:00 +00001895 case TemplateArgument::Expression: {
1896 // Template argument expressions are not potentially evaluated.
Mike Stump25cf7602009-09-09 15:08:12 +00001897 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregor2999faa2009-08-04 22:27:00 +00001898 Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00001899
Douglas Gregor2999faa2009-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 Stump25cf7602009-09-09 15:08:12 +00001905
Douglas Gregor2999faa2009-08-04 22:27:00 +00001906 case TemplateArgument::Pack: {
1907 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1908 TransformedArgs.reserve(Arg.pack_size());
Mike Stump25cf7602009-09-09 15:08:12 +00001909 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregor2999faa2009-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 Stump25cf7602009-09-09 15:08:12 +00001915
Douglas Gregor2999faa2009-08-04 22:27:00 +00001916 TransformedArgs.push_back(TA);
1917 }
1918 TemplateArgument Result;
Mike Stump25cf7602009-09-09 15:08:12 +00001919 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregor2999faa2009-08-04 22:27:00 +00001920 true);
1921 return Result;
1922 }
1923 }
Mike Stump25cf7602009-09-09 15:08:12 +00001924
Douglas Gregor2999faa2009-08-04 22:27:00 +00001925 // Work around bogus GCC warning
1926 return TemplateArgument();
1927}
1928
Douglas Gregor841324a2009-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 Stump25cf7602009-09-09 15:08:12 +00001937
Douglas Gregor841324a2009-08-04 16:50:30 +00001938 QualType Result;
1939 switch (T->getTypeClass()) {
Mike Stump25cf7602009-09-09 15:08:12 +00001940#define ABSTRACT_TYPE(CLASS, PARENT)
Douglas Gregor841324a2009-08-04 16:50:30 +00001941#define TYPE(CLASS, PARENT) \
1942 case Type::CLASS: \
1943 Result = getDerived().Transform##CLASS##Type( \
1944 static_cast<CLASS##Type*>(T.getTypePtr())); \
1945 break;
Mike Stump25cf7602009-09-09 15:08:12 +00001946#include "clang/AST/TypeNodes.def"
Douglas Gregor841324a2009-08-04 16:50:30 +00001947 }
Mike Stump25cf7602009-09-09 15:08:12 +00001948
Douglas Gregor841324a2009-08-04 16:50:30 +00001949 if (Result.isNull() || T == Result)
1950 return Result;
Mike Stump25cf7602009-09-09 15:08:12 +00001951
Douglas Gregor841324a2009-08-04 16:50:30 +00001952 return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
1953}
Mike Stump25cf7602009-09-09 15:08:12 +00001954
Douglas Gregor841324a2009-08-04 16:50:30 +00001955template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00001956QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00001957TreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
1958 if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
1959 return T.getWithAdditionalQualifiers(CVRQualifiers);
Mike Stump25cf7602009-09-09 15:08:12 +00001960
Douglas Gregor841324a2009-08-04 16:50:30 +00001961 return T;
1962}
Argiris Kirtzidisfd3d5fd2009-08-19 01:28:17 +00001963
Douglas Gregor841324a2009-08-04 16:50:30 +00001964template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00001965QualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
1966 // FIXME: Implement
1967 return QualType(T, 0);
1968}
1969
1970template<typename Derived>
1971QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00001972 // Nothing to do
Mike Stump25cf7602009-09-09 15:08:12 +00001973 return QualType(T, 0);
Douglas Gregor841324a2009-08-04 16:50:30 +00001974}
Mike Stump25cf7602009-09-09 15:08:12 +00001975
Douglas Gregor841324a2009-08-04 16:50:30 +00001976template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00001977QualType TreeTransform<Derived>::TransformFixedWidthIntType(
1978 const FixedWidthIntType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00001979 // FIXME: Implement
Mike Stump25cf7602009-09-09 15:08:12 +00001980 return QualType(T, 0);
Douglas Gregor841324a2009-08-04 16:50:30 +00001981}
Mike Stump25cf7602009-09-09 15:08:12 +00001982
1983template<typename Derived>
1984QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
1985 // FIXME: Implement
1986 return QualType(T, 0);
1987}
1988
1989template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00001990QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
1991 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1992 if (PointeeType.isNull())
1993 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00001994
Douglas Gregor841324a2009-08-04 16:50:30 +00001995 if (!getDerived().AlwaysRebuild() &&
1996 PointeeType == T->getPointeeType())
1997 return QualType(T, 0);
1998
1999 return getDerived().RebuildPointerType(PointeeType);
2000}
Mike Stump25cf7602009-09-09 15:08:12 +00002001
2002template<typename Derived>
2003QualType
2004TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002005 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2006 if (PointeeType.isNull())
2007 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002008
Douglas Gregor841324a2009-08-04 16:50:30 +00002009 if (!getDerived().AlwaysRebuild() &&
2010 PointeeType == T->getPointeeType())
2011 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002012
Douglas Gregor841324a2009-08-04 16:50:30 +00002013 return getDerived().RebuildBlockPointerType(PointeeType);
2014}
2015
Mike Stump25cf7602009-09-09 15:08:12 +00002016template<typename Derived>
2017QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00002018TreeTransform<Derived>::TransformLValueReferenceType(
Mike Stump25cf7602009-09-09 15:08:12 +00002019 const LValueReferenceType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002020 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2021 if (PointeeType.isNull())
2022 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002023
Douglas Gregor841324a2009-08-04 16:50:30 +00002024 if (!getDerived().AlwaysRebuild() &&
2025 PointeeType == T->getPointeeType())
2026 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002027
Douglas Gregor841324a2009-08-04 16:50:30 +00002028 return getDerived().RebuildLValueReferenceType(PointeeType);
2029}
2030
Mike Stump25cf7602009-09-09 15:08:12 +00002031template<typename Derived>
2032QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00002033TreeTransform<Derived>::TransformRValueReferenceType(
Mike Stump25cf7602009-09-09 15:08:12 +00002034 const RValueReferenceType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002035 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2036 if (PointeeType.isNull())
2037 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002038
Douglas Gregor841324a2009-08-04 16:50:30 +00002039 if (!getDerived().AlwaysRebuild() &&
2040 PointeeType == T->getPointeeType())
2041 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002042
Douglas Gregor841324a2009-08-04 16:50:30 +00002043 return getDerived().RebuildRValueReferenceType(PointeeType);
2044}
Mike Stump25cf7602009-09-09 15:08:12 +00002045
Douglas Gregor841324a2009-08-04 16:50:30 +00002046template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002047QualType
2048TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002049 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2050 if (PointeeType.isNull())
2051 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002052
Douglas Gregor841324a2009-08-04 16:50:30 +00002053 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
2054 if (ClassType.isNull())
2055 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002056
Douglas Gregor841324a2009-08-04 16:50:30 +00002057 if (!getDerived().AlwaysRebuild() &&
2058 PointeeType == T->getPointeeType() &&
2059 ClassType == QualType(T->getClass(), 0))
2060 return QualType(T, 0);
2061
2062 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2063}
2064
Mike Stump25cf7602009-09-09 15:08:12 +00002065template<typename Derived>
2066QualType
2067TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002068 QualType ElementType = getDerived().TransformType(T->getElementType());
2069 if (ElementType.isNull())
2070 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002071
Douglas Gregor841324a2009-08-04 16:50:30 +00002072 if (!getDerived().AlwaysRebuild() &&
2073 ElementType == T->getElementType())
2074 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002075
2076 return getDerived().RebuildConstantArrayType(ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00002077 T->getSizeModifier(),
2078 T->getSize(),
2079 T->getIndexTypeQualifier());
2080}
Mike Stump25cf7602009-09-09 15:08:12 +00002081
Douglas Gregor841324a2009-08-04 16:50:30 +00002082template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002083QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00002084TreeTransform<Derived>::TransformConstantArrayWithExprType(
Mike Stump25cf7602009-09-09 15:08:12 +00002085 const ConstantArrayWithExprType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002086 QualType ElementType = getDerived().TransformType(T->getElementType());
2087 if (ElementType.isNull())
2088 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002089
Douglas Gregor2999faa2009-08-04 22:27:00 +00002090 // Array bounds are not potentially evaluated contexts
2091 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00002092
Douglas Gregor2999faa2009-08-04 22:27:00 +00002093 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2094 if (Size.isInvalid())
2095 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002096
Douglas Gregor841324a2009-08-04 16:50:30 +00002097 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor2999faa2009-08-04 22:27:00 +00002098 ElementType == T->getElementType() &&
2099 Size.get() == T->getSizeExpr())
Douglas Gregor841324a2009-08-04 16:50:30 +00002100 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002101
2102 return getDerived().RebuildConstantArrayWithExprType(ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00002103 T->getSizeModifier(),
2104 T->getSize(),
Douglas Gregor2999faa2009-08-04 22:27:00 +00002105 Size.takeAs<Expr>(),
Douglas Gregor841324a2009-08-04 16:50:30 +00002106 T->getIndexTypeQualifier(),
2107 T->getBracketsRange());
2108}
Mike Stump25cf7602009-09-09 15:08:12 +00002109
2110template<typename Derived>
2111QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00002112TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
Mike Stump25cf7602009-09-09 15:08:12 +00002113 const ConstantArrayWithoutExprType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002114 QualType ElementType = getDerived().TransformType(T->getElementType());
2115 if (ElementType.isNull())
2116 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002117
Douglas Gregor841324a2009-08-04 16:50:30 +00002118 if (!getDerived().AlwaysRebuild() &&
2119 ElementType == T->getElementType())
2120 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002121
2122 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00002123 T->getSizeModifier(),
2124 T->getSize(),
2125 T->getIndexTypeQualifier());
2126}
2127
Mike Stump25cf7602009-09-09 15:08:12 +00002128template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002129QualType TreeTransform<Derived>::TransformIncompleteArrayType(
Mike Stump25cf7602009-09-09 15:08:12 +00002130 const IncompleteArrayType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002131 QualType ElementType = getDerived().TransformType(T->getElementType());
2132 if (ElementType.isNull())
2133 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002134
Douglas Gregor841324a2009-08-04 16:50:30 +00002135 if (!getDerived().AlwaysRebuild() &&
2136 ElementType == T->getElementType())
2137 return QualType(T, 0);
2138
2139 return getDerived().RebuildIncompleteArrayType(ElementType,
2140 T->getSizeModifier(),
2141 T->getIndexTypeQualifier());
2142}
Mike Stump25cf7602009-09-09 15:08:12 +00002143
Douglas Gregor841324a2009-08-04 16:50:30 +00002144template<typename Derived>
2145QualType TreeTransform<Derived>::TransformVariableArrayType(
Mike Stump25cf7602009-09-09 15:08:12 +00002146 const VariableArrayType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002147 QualType ElementType = getDerived().TransformType(T->getElementType());
2148 if (ElementType.isNull())
2149 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002150
Douglas Gregor2999faa2009-08-04 22:27:00 +00002151 // Array bounds are not potentially evaluated contexts
2152 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2153
Douglas Gregor841324a2009-08-04 16:50:30 +00002154 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2155 if (Size.isInvalid())
2156 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002157
Douglas Gregor841324a2009-08-04 16:50:30 +00002158 if (!getDerived().AlwaysRebuild() &&
2159 ElementType == T->getElementType() &&
2160 Size.get() == T->getSizeExpr()) {
2161 Size.take();
2162 return QualType(T, 0);
2163 }
Mike Stump25cf7602009-09-09 15:08:12 +00002164
2165 return getDerived().RebuildVariableArrayType(ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00002166 T->getSizeModifier(),
2167 move(Size),
2168 T->getIndexTypeQualifier(),
2169 T->getBracketsRange());
2170}
Mike Stump25cf7602009-09-09 15:08:12 +00002171
2172template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002173QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
Mike Stump25cf7602009-09-09 15:08:12 +00002174 const DependentSizedArrayType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002175 QualType ElementType = getDerived().TransformType(T->getElementType());
2176 if (ElementType.isNull())
2177 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002178
Douglas Gregor2999faa2009-08-04 22:27:00 +00002179 // Array bounds are not potentially evaluated contexts
2180 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00002181
Douglas Gregor841324a2009-08-04 16:50:30 +00002182 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2183 if (Size.isInvalid())
2184 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002185
Douglas Gregor841324a2009-08-04 16:50:30 +00002186 if (!getDerived().AlwaysRebuild() &&
2187 ElementType == T->getElementType() &&
2188 Size.get() == T->getSizeExpr()) {
2189 Size.take();
2190 return QualType(T, 0);
2191 }
Mike Stump25cf7602009-09-09 15:08:12 +00002192
2193 return getDerived().RebuildDependentSizedArrayType(ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00002194 T->getSizeModifier(),
2195 move(Size),
2196 T->getIndexTypeQualifier(),
2197 T->getBracketsRange());
2198}
Mike Stump25cf7602009-09-09 15:08:12 +00002199
2200template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002201QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
Mike Stump25cf7602009-09-09 15:08:12 +00002202 const DependentSizedExtVectorType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002203 QualType ElementType = getDerived().TransformType(T->getElementType());
2204 if (ElementType.isNull())
2205 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002206
Douglas Gregor2999faa2009-08-04 22:27:00 +00002207 // Vector sizes are not potentially evaluated contexts
2208 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2209
Douglas Gregor841324a2009-08-04 16:50:30 +00002210 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2211 if (Size.isInvalid())
2212 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002213
Douglas Gregor841324a2009-08-04 16:50:30 +00002214 if (!getDerived().AlwaysRebuild() &&
2215 ElementType == T->getElementType() &&
2216 Size.get() == T->getSizeExpr()) {
2217 Size.take();
2218 return QualType(T, 0);
2219 }
Mike Stump25cf7602009-09-09 15:08:12 +00002220
2221 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00002222 move(Size),
2223 T->getAttributeLoc());
2224}
Mike Stump25cf7602009-09-09 15:08:12 +00002225
2226template<typename Derived>
2227QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002228 QualType ElementType = getDerived().TransformType(T->getElementType());
2229 if (ElementType.isNull())
2230 return QualType();
2231
2232 if (!getDerived().AlwaysRebuild() &&
2233 ElementType == T->getElementType())
2234 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002235
Douglas Gregor841324a2009-08-04 16:50:30 +00002236 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
2237}
Mike Stump25cf7602009-09-09 15:08:12 +00002238
2239template<typename Derived>
2240QualType
2241TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002242 QualType ElementType = getDerived().TransformType(T->getElementType());
2243 if (ElementType.isNull())
2244 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002245
Douglas Gregor841324a2009-08-04 16:50:30 +00002246 if (!getDerived().AlwaysRebuild() &&
2247 ElementType == T->getElementType())
2248 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002249
Douglas Gregor841324a2009-08-04 16:50:30 +00002250 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
2251 /*FIXME*/SourceLocation());
2252}
2253
Mike Stump25cf7602009-09-09 15:08:12 +00002254template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002255QualType TreeTransform<Derived>::TransformFunctionProtoType(
Mike Stump25cf7602009-09-09 15:08:12 +00002256 const FunctionProtoType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002257 QualType ResultType = getDerived().TransformType(T->getResultType());
2258 if (ResultType.isNull())
2259 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002260
Douglas Gregor841324a2009-08-04 16:50:30 +00002261 llvm::SmallVector<QualType, 4> ParamTypes;
2262 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
Mike Stump25cf7602009-09-09 15:08:12 +00002263 ParamEnd = T->arg_type_end();
Douglas Gregor841324a2009-08-04 16:50:30 +00002264 Param != ParamEnd; ++Param) {
2265 QualType P = getDerived().TransformType(*Param);
2266 if (P.isNull())
2267 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002268
Douglas Gregor841324a2009-08-04 16:50:30 +00002269 ParamTypes.push_back(P);
2270 }
Mike Stump25cf7602009-09-09 15:08:12 +00002271
Douglas Gregor841324a2009-08-04 16:50:30 +00002272 if (!getDerived().AlwaysRebuild() &&
2273 ResultType == T->getResultType() &&
2274 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
2275 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002276
2277 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
Douglas Gregor841324a2009-08-04 16:50:30 +00002278 ParamTypes.size(), T->isVariadic(),
2279 T->getTypeQuals());
2280}
Mike Stump25cf7602009-09-09 15:08:12 +00002281
Douglas Gregor841324a2009-08-04 16:50:30 +00002282template<typename Derived>
2283QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
Mike Stump25cf7602009-09-09 15:08:12 +00002284 const FunctionNoProtoType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002285 // FIXME: Implement
Mike Stump25cf7602009-09-09 15:08:12 +00002286 return QualType(T, 0);
Douglas Gregor841324a2009-08-04 16:50:30 +00002287}
Mike Stump25cf7602009-09-09 15:08:12 +00002288
Douglas Gregor841324a2009-08-04 16:50:30 +00002289template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002290QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002291 TypedefDecl *Typedef
2292 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2293 if (!Typedef)
2294 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002295
Douglas Gregor841324a2009-08-04 16:50:30 +00002296 if (!getDerived().AlwaysRebuild() &&
2297 Typedef == T->getDecl())
2298 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002299
Douglas Gregor841324a2009-08-04 16:50:30 +00002300 return getDerived().RebuildTypedefType(Typedef);
2301}
Mike Stump25cf7602009-09-09 15:08:12 +00002302
Douglas Gregor841324a2009-08-04 16:50:30 +00002303template<typename Derived>
2304QualType TreeTransform<Derived>::TransformTypeOfExprType(
Mike Stump25cf7602009-09-09 15:08:12 +00002305 const TypeOfExprType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00002306 // typeof expressions are not potentially evaluated contexts
2307 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00002308
Douglas Gregor841324a2009-08-04 16:50:30 +00002309 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2310 if (E.isInvalid())
2311 return QualType();
2312
2313 if (!getDerived().AlwaysRebuild() &&
2314 E.get() == T->getUnderlyingExpr()) {
2315 E.take();
2316 return QualType(T, 0);
2317 }
Mike Stump25cf7602009-09-09 15:08:12 +00002318
Douglas Gregor841324a2009-08-04 16:50:30 +00002319 return getDerived().RebuildTypeOfExprType(move(E));
2320}
Mike Stump25cf7602009-09-09 15:08:12 +00002321
2322template<typename Derived>
2323QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002324 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2325 if (Underlying.isNull())
2326 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002327
Douglas Gregor841324a2009-08-04 16:50:30 +00002328 if (!getDerived().AlwaysRebuild() &&
2329 Underlying == T->getUnderlyingType())
2330 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002331
Douglas Gregor841324a2009-08-04 16:50:30 +00002332 return getDerived().RebuildTypeOfType(Underlying);
2333}
Mike Stump25cf7602009-09-09 15:08:12 +00002334
2335template<typename Derived>
2336QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00002337 // decltype expressions are not potentially evaluated contexts
2338 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00002339
Douglas Gregor841324a2009-08-04 16:50:30 +00002340 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2341 if (E.isInvalid())
2342 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002343
Douglas Gregor841324a2009-08-04 16:50:30 +00002344 if (!getDerived().AlwaysRebuild() &&
2345 E.get() == T->getUnderlyingExpr()) {
2346 E.take();
2347 return QualType(T, 0);
2348 }
Mike Stump25cf7602009-09-09 15:08:12 +00002349
Douglas Gregor841324a2009-08-04 16:50:30 +00002350 return getDerived().RebuildDecltypeType(move(E));
2351}
2352
2353template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002354QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002355 RecordDecl *Record
2356 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
2357 if (!Record)
2358 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002359
Douglas Gregor841324a2009-08-04 16:50:30 +00002360 if (!getDerived().AlwaysRebuild() &&
2361 Record == T->getDecl())
2362 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002363
Douglas Gregor841324a2009-08-04 16:50:30 +00002364 return getDerived().RebuildRecordType(Record);
2365}
Mike Stump25cf7602009-09-09 15:08:12 +00002366
2367template<typename Derived>
2368QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002369 EnumDecl *Enum
2370 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
2371 if (!Enum)
2372 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002373
Douglas Gregor841324a2009-08-04 16:50:30 +00002374 if (!getDerived().AlwaysRebuild() &&
2375 Enum == T->getDecl())
2376 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002377
Douglas Gregor841324a2009-08-04 16:50:30 +00002378 return getDerived().RebuildEnumType(Enum);
2379}
John McCall379448f2009-09-05 00:15:47 +00002380
2381template <typename Derived>
2382QualType TreeTransform<Derived>::TransformElaboratedType(
2383 const ElaboratedType *T) {
2384 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2385 if (Underlying.isNull())
2386 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002387
John McCall379448f2009-09-05 00:15:47 +00002388 if (!getDerived().AlwaysRebuild() &&
2389 Underlying == T->getUnderlyingType())
2390 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002391
John McCall379448f2009-09-05 00:15:47 +00002392 return getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2393}
Mike Stump25cf7602009-09-09 15:08:12 +00002394
2395
Douglas Gregor841324a2009-08-04 16:50:30 +00002396template<typename Derived>
2397QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
Mike Stump25cf7602009-09-09 15:08:12 +00002398 const TemplateTypeParmType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002399 // Nothing to do
Mike Stump25cf7602009-09-09 15:08:12 +00002400 return QualType(T, 0);
Douglas Gregor841324a2009-08-04 16:50:30 +00002401}
2402
Mike Stump25cf7602009-09-09 15:08:12 +00002403template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002404QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
Mike Stump25cf7602009-09-09 15:08:12 +00002405 const TemplateSpecializationType *T) {
2406 TemplateName Template
Douglas Gregor841324a2009-08-04 16:50:30 +00002407 = getDerived().TransformTemplateName(T->getTemplateName());
2408 if (Template.isNull())
2409 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002410
Douglas Gregor841324a2009-08-04 16:50:30 +00002411 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2412 NewTemplateArgs.reserve(T->getNumArgs());
2413 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2414 Arg != ArgEnd; ++Arg) {
2415 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2416 if (NewArg.isNull())
2417 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002418
Douglas Gregor841324a2009-08-04 16:50:30 +00002419 NewTemplateArgs.push_back(NewArg);
2420 }
Mike Stump25cf7602009-09-09 15:08:12 +00002421
Douglas Gregor841324a2009-08-04 16:50:30 +00002422 // FIXME: early abort if all of the template arguments and such are the
2423 // same.
Mike Stump25cf7602009-09-09 15:08:12 +00002424
Douglas Gregor841324a2009-08-04 16:50:30 +00002425 // FIXME: We're missing the locations of the template name, '<', and '>'.
2426 return getDerived().RebuildTemplateSpecializationType(Template,
2427 NewTemplateArgs.data(),
2428 NewTemplateArgs.size());
2429}
Mike Stump25cf7602009-09-09 15:08:12 +00002430
2431template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002432QualType TreeTransform<Derived>::TransformQualifiedNameType(
2433 const QualifiedNameType *T) {
2434 NestedNameSpecifier *NNS
2435 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2436 SourceRange());
2437 if (!NNS)
2438 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002439
Douglas Gregor841324a2009-08-04 16:50:30 +00002440 QualType Named = getDerived().TransformType(T->getNamedType());
2441 if (Named.isNull())
2442 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002443
Douglas Gregor841324a2009-08-04 16:50:30 +00002444 if (!getDerived().AlwaysRebuild() &&
2445 NNS == T->getQualifier() &&
2446 Named == T->getNamedType())
2447 return QualType(T, 0);
2448
2449 return getDerived().RebuildQualifiedNameType(NNS, Named);
2450}
Mike Stump25cf7602009-09-09 15:08:12 +00002451
2452template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002453QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
2454 NestedNameSpecifier *NNS
2455 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor3f220e82009-08-06 16:20:37 +00002456 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregor841324a2009-08-04 16:50:30 +00002457 if (!NNS)
2458 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002459
Douglas Gregor841324a2009-08-04 16:50:30 +00002460 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump25cf7602009-09-09 15:08:12 +00002461 QualType NewTemplateId
Douglas Gregor841324a2009-08-04 16:50:30 +00002462 = getDerived().TransformType(QualType(TemplateId, 0));
2463 if (NewTemplateId.isNull())
2464 return QualType();
Mike Stump25cf7602009-09-09 15:08:12 +00002465
Douglas Gregor841324a2009-08-04 16:50:30 +00002466 if (!getDerived().AlwaysRebuild() &&
2467 NNS == T->getQualifier() &&
2468 NewTemplateId == QualType(TemplateId, 0))
2469 return QualType(T, 0);
Mike Stump25cf7602009-09-09 15:08:12 +00002470
Douglas Gregor841324a2009-08-04 16:50:30 +00002471 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
2472 }
2473
2474 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
2475}
Mike Stump25cf7602009-09-09 15:08:12 +00002476
Douglas Gregor841324a2009-08-04 16:50:30 +00002477template<typename Derived>
2478QualType TreeTransform<Derived>::TransformObjCInterfaceType(
Mike Stump25cf7602009-09-09 15:08:12 +00002479 const ObjCInterfaceType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002480 // FIXME: Implement
Mike Stump25cf7602009-09-09 15:08:12 +00002481 return QualType(T, 0);
Douglas Gregor841324a2009-08-04 16:50:30 +00002482}
Mike Stump25cf7602009-09-09 15:08:12 +00002483
2484template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00002485QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
Mike Stump25cf7602009-09-09 15:08:12 +00002486 const ObjCObjectPointerType *T) {
Douglas Gregor841324a2009-08-04 16:50:30 +00002487 // FIXME: Implement
Mike Stump25cf7602009-09-09 15:08:12 +00002488 return QualType(T, 0);
Douglas Gregor841324a2009-08-04 16:50:30 +00002489}
2490
2491//===----------------------------------------------------------------------===//
Douglas Gregor23a44be2009-08-20 07:17:43 +00002492// Statement transformation
2493//===----------------------------------------------------------------------===//
2494template<typename Derived>
2495Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002496TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2497 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002498}
2499
2500template<typename Derived>
2501Sema::OwningStmtResult
2502TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2503 return getDerived().TransformCompoundStmt(S, false);
2504}
2505
2506template<typename Derived>
2507Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002508TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregor23a44be2009-08-20 07:17:43 +00002509 bool IsStmtExpr) {
2510 bool SubStmtChanged = false;
2511 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2512 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2513 B != BEnd; ++B) {
2514 OwningStmtResult Result = getDerived().TransformStmt(*B);
2515 if (Result.isInvalid())
2516 return getSema().StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002517
Douglas Gregor23a44be2009-08-20 07:17:43 +00002518 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2519 Statements.push_back(Result.takeAs<Stmt>());
2520 }
Mike Stump25cf7602009-09-09 15:08:12 +00002521
Douglas Gregor23a44be2009-08-20 07:17:43 +00002522 if (!getDerived().AlwaysRebuild() &&
2523 !SubStmtChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00002524 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002525
2526 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2527 move_arg(Statements),
2528 S->getRBracLoc(),
2529 IsStmtExpr);
2530}
Mike Stump25cf7602009-09-09 15:08:12 +00002531
Douglas Gregor23a44be2009-08-20 07:17:43 +00002532template<typename Derived>
2533Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002534TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002535 // The case value expressions are not potentially evaluated.
2536 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00002537
Douglas Gregor23a44be2009-08-20 07:17:43 +00002538 // Transform the left-hand case value.
2539 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2540 if (LHS.isInvalid())
2541 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002542
Douglas Gregor23a44be2009-08-20 07:17:43 +00002543 // Transform the right-hand case value (for the GNU case-range extension).
2544 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2545 if (RHS.isInvalid())
2546 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002547
Douglas Gregor23a44be2009-08-20 07:17:43 +00002548 // Build the case statement.
2549 // Case statements are always rebuilt so that they will attached to their
2550 // transformed switch statement.
2551 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2552 move(LHS),
2553 S->getEllipsisLoc(),
2554 move(RHS),
2555 S->getColonLoc());
2556 if (Case.isInvalid())
2557 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002558
Douglas Gregor23a44be2009-08-20 07:17:43 +00002559 // Transform the statement following the case
2560 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2561 if (SubStmt.isInvalid())
2562 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002563
Douglas Gregor23a44be2009-08-20 07:17:43 +00002564 // Attach the body to the case statement
2565 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2566}
2567
2568template<typename Derived>
2569Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002570TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002571 // Transform the statement following the default case
2572 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2573 if (SubStmt.isInvalid())
2574 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002575
Douglas Gregor23a44be2009-08-20 07:17:43 +00002576 // Default statements are always rebuilt
2577 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2578 move(SubStmt));
2579}
Mike Stump25cf7602009-09-09 15:08:12 +00002580
Douglas Gregor23a44be2009-08-20 07:17:43 +00002581template<typename Derived>
2582Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002583TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002584 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2585 if (SubStmt.isInvalid())
2586 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002587
Douglas Gregor23a44be2009-08-20 07:17:43 +00002588 // FIXME: Pass the real colon location in.
2589 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2590 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2591 move(SubStmt));
2592}
Mike Stump25cf7602009-09-09 15:08:12 +00002593
Douglas Gregor23a44be2009-08-20 07:17:43 +00002594template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002595Sema::OwningStmtResult
2596TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002597 // Transform the condition
2598 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2599 if (Cond.isInvalid())
2600 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002601
Douglas Gregor23a44be2009-08-20 07:17:43 +00002602 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump25cf7602009-09-09 15:08:12 +00002603
Douglas Gregor23a44be2009-08-20 07:17:43 +00002604 // Transform the "then" branch.
2605 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2606 if (Then.isInvalid())
2607 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002608
Douglas Gregor23a44be2009-08-20 07:17:43 +00002609 // Transform the "else" branch.
2610 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2611 if (Else.isInvalid())
2612 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002613
Douglas Gregor23a44be2009-08-20 07:17:43 +00002614 if (!getDerived().AlwaysRebuild() &&
2615 FullCond->get() == S->getCond() &&
2616 Then.get() == S->getThen() &&
2617 Else.get() == S->getElse())
Mike Stump25cf7602009-09-09 15:08:12 +00002618 return SemaRef.Owned(S->Retain());
2619
Douglas Gregor23a44be2009-08-20 07:17:43 +00002620 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump25cf7602009-09-09 15:08:12 +00002621 S->getElseLoc(), move(Else));
Douglas Gregor23a44be2009-08-20 07:17:43 +00002622}
2623
2624template<typename Derived>
2625Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002626TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002627 // Transform the condition.
2628 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2629 if (Cond.isInvalid())
2630 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002631
Douglas Gregor23a44be2009-08-20 07:17:43 +00002632 // Rebuild the switch statement.
2633 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2634 if (Switch.isInvalid())
2635 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002636
Douglas Gregor23a44be2009-08-20 07:17:43 +00002637 // Transform the body of the switch statement.
2638 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2639 if (Body.isInvalid())
2640 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002641
Douglas Gregor23a44be2009-08-20 07:17:43 +00002642 // Complete the switch statement.
2643 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2644 move(Body));
2645}
Mike Stump25cf7602009-09-09 15:08:12 +00002646
Douglas Gregor23a44be2009-08-20 07:17:43 +00002647template<typename Derived>
2648Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002649TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002650 // Transform the condition
2651 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2652 if (Cond.isInvalid())
2653 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002654
Douglas Gregor23a44be2009-08-20 07:17:43 +00002655 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump25cf7602009-09-09 15:08:12 +00002656
Douglas Gregor23a44be2009-08-20 07:17:43 +00002657 // Transform the body
2658 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2659 if (Body.isInvalid())
2660 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002661
Douglas Gregor23a44be2009-08-20 07:17:43 +00002662 if (!getDerived().AlwaysRebuild() &&
2663 FullCond->get() == S->getCond() &&
2664 Body.get() == S->getBody())
Mike Stump25cf7602009-09-09 15:08:12 +00002665 return SemaRef.Owned(S->Retain());
2666
Douglas Gregor23a44be2009-08-20 07:17:43 +00002667 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2668}
Mike Stump25cf7602009-09-09 15:08:12 +00002669
Douglas Gregor23a44be2009-08-20 07:17:43 +00002670template<typename Derived>
2671Sema::OwningStmtResult
2672TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2673 // Transform the condition
2674 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2675 if (Cond.isInvalid())
2676 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002677
Douglas Gregor23a44be2009-08-20 07:17:43 +00002678 // Transform the body
2679 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2680 if (Body.isInvalid())
2681 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002682
Douglas Gregor23a44be2009-08-20 07:17:43 +00002683 if (!getDerived().AlwaysRebuild() &&
2684 Cond.get() == S->getCond() &&
2685 Body.get() == S->getBody())
Mike Stump25cf7602009-09-09 15:08:12 +00002686 return SemaRef.Owned(S->Retain());
2687
Douglas Gregor23a44be2009-08-20 07:17:43 +00002688 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
2689 /*FIXME:*/S->getWhileLoc(), move(Cond),
2690 S->getRParenLoc());
2691}
Mike Stump25cf7602009-09-09 15:08:12 +00002692
Douglas Gregor23a44be2009-08-20 07:17:43 +00002693template<typename Derived>
2694Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002695TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002696 // Transform the initialization statement
2697 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
2698 if (Init.isInvalid())
2699 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002700
Douglas Gregor23a44be2009-08-20 07:17:43 +00002701 // Transform the condition
2702 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2703 if (Cond.isInvalid())
2704 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002705
Douglas Gregor23a44be2009-08-20 07:17:43 +00002706 // Transform the increment
2707 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
2708 if (Inc.isInvalid())
2709 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002710
Douglas Gregor23a44be2009-08-20 07:17:43 +00002711 // Transform the body
2712 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2713 if (Body.isInvalid())
2714 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002715
Douglas Gregor23a44be2009-08-20 07:17:43 +00002716 if (!getDerived().AlwaysRebuild() &&
2717 Init.get() == S->getInit() &&
2718 Cond.get() == S->getCond() &&
2719 Inc.get() == S->getInc() &&
2720 Body.get() == S->getBody())
Mike Stump25cf7602009-09-09 15:08:12 +00002721 return SemaRef.Owned(S->Retain());
2722
Douglas Gregor23a44be2009-08-20 07:17:43 +00002723 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
2724 move(Init), move(Cond), move(Inc),
2725 S->getRParenLoc(), move(Body));
2726}
2727
2728template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002729Sema::OwningStmtResult
2730TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002731 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump25cf7602009-09-09 15:08:12 +00002732 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregor23a44be2009-08-20 07:17:43 +00002733 S->getLabel());
2734}
2735
2736template<typename Derived>
2737Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002738TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002739 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
2740 if (Target.isInvalid())
2741 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002742
Douglas Gregor23a44be2009-08-20 07:17:43 +00002743 if (!getDerived().AlwaysRebuild() &&
2744 Target.get() == S->getTarget())
Mike Stump25cf7602009-09-09 15:08:12 +00002745 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002746
2747 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
2748 move(Target));
2749}
2750
2751template<typename Derived>
2752Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002753TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
2754 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002755}
Mike Stump25cf7602009-09-09 15:08:12 +00002756
Douglas Gregor23a44be2009-08-20 07:17:43 +00002757template<typename Derived>
2758Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002759TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
2760 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002761}
Mike Stump25cf7602009-09-09 15:08:12 +00002762
Douglas Gregor23a44be2009-08-20 07:17:43 +00002763template<typename Derived>
2764Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002765TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002766 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
2767 if (Result.isInvalid())
2768 return SemaRef.StmtError();
2769
Mike Stump25cf7602009-09-09 15:08:12 +00002770 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregor23a44be2009-08-20 07:17:43 +00002771 // to tell whether the return type of the function has changed.
2772 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
2773}
Mike Stump25cf7602009-09-09 15:08:12 +00002774
Douglas Gregor23a44be2009-08-20 07:17:43 +00002775template<typename Derived>
2776Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002777TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002778 bool DeclChanged = false;
2779 llvm::SmallVector<Decl *, 4> Decls;
2780 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
2781 D != DEnd; ++D) {
2782 Decl *Transformed = getDerived().TransformDefinition(*D);
2783 if (!Transformed)
2784 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002785
Douglas Gregor23a44be2009-08-20 07:17:43 +00002786 if (Transformed != *D)
2787 DeclChanged = true;
Mike Stump25cf7602009-09-09 15:08:12 +00002788
Douglas Gregor23a44be2009-08-20 07:17:43 +00002789 Decls.push_back(Transformed);
2790 }
Mike Stump25cf7602009-09-09 15:08:12 +00002791
Douglas Gregor23a44be2009-08-20 07:17:43 +00002792 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00002793 return SemaRef.Owned(S->Retain());
2794
2795 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregor23a44be2009-08-20 07:17:43 +00002796 S->getStartLoc(), S->getEndLoc());
2797}
Mike Stump25cf7602009-09-09 15:08:12 +00002798
Douglas Gregor23a44be2009-08-20 07:17:43 +00002799template<typename Derived>
2800Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002801TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002802 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump25cf7602009-09-09 15:08:12 +00002803 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002804}
2805
2806template<typename Derived>
2807Sema::OwningStmtResult
2808TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
2809 // FIXME: Implement!
2810 assert(false && "Inline assembly cannot be transformed");
Mike Stump25cf7602009-09-09 15:08:12 +00002811 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002812}
2813
2814
2815template<typename Derived>
2816Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002817TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002818 // FIXME: Implement this
2819 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump25cf7602009-09-09 15:08:12 +00002820 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002821}
Mike Stump25cf7602009-09-09 15:08:12 +00002822
Douglas Gregor23a44be2009-08-20 07:17:43 +00002823template<typename Derived>
2824Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002825TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002826 // FIXME: Implement this
2827 assert(false && "Cannot transform an Objective-C @catch statement");
2828 return SemaRef.Owned(S->Retain());
2829}
Mike Stump25cf7602009-09-09 15:08:12 +00002830
Douglas Gregor23a44be2009-08-20 07:17:43 +00002831template<typename Derived>
2832Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002833TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002834 // FIXME: Implement this
2835 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump25cf7602009-09-09 15:08:12 +00002836 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002837}
Mike Stump25cf7602009-09-09 15:08:12 +00002838
Douglas Gregor23a44be2009-08-20 07:17:43 +00002839template<typename Derived>
2840Sema::OwningStmtResult
Mike Stump25cf7602009-09-09 15:08:12 +00002841TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002842 // FIXME: Implement this
2843 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump25cf7602009-09-09 15:08:12 +00002844 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002845}
Mike Stump25cf7602009-09-09 15:08:12 +00002846
Douglas Gregor23a44be2009-08-20 07:17:43 +00002847template<typename Derived>
2848Sema::OwningStmtResult
2849TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump25cf7602009-09-09 15:08:12 +00002850 ObjCAtSynchronizedStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002851 // FIXME: Implement this
2852 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump25cf7602009-09-09 15:08:12 +00002853 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002854}
2855
2856template<typename Derived>
2857Sema::OwningStmtResult
2858TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump25cf7602009-09-09 15:08:12 +00002859 ObjCForCollectionStmt *S) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00002860 // FIXME: Implement this
2861 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump25cf7602009-09-09 15:08:12 +00002862 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002863}
2864
2865
2866template<typename Derived>
2867Sema::OwningStmtResult
2868TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
2869 // Transform the exception declaration, if any.
2870 VarDecl *Var = 0;
2871 if (S->getExceptionDecl()) {
2872 VarDecl *ExceptionDecl = S->getExceptionDecl();
2873 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
2874 ExceptionDecl->getDeclName());
2875
2876 QualType T = getDerived().TransformType(ExceptionDecl->getType());
2877 if (T.isNull())
2878 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002879
Douglas Gregor23a44be2009-08-20 07:17:43 +00002880 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
2881 T,
2882 ExceptionDecl->getDeclaratorInfo(),
2883 ExceptionDecl->getIdentifier(),
2884 ExceptionDecl->getLocation(),
2885 /*FIXME: Inaccurate*/
2886 SourceRange(ExceptionDecl->getLocation()));
2887 if (!Var || Var->isInvalidDecl()) {
2888 if (Var)
2889 Var->Destroy(SemaRef.Context);
2890 return SemaRef.StmtError();
2891 }
2892 }
Mike Stump25cf7602009-09-09 15:08:12 +00002893
Douglas Gregor23a44be2009-08-20 07:17:43 +00002894 // Transform the actual exception handler.
2895 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
2896 if (Handler.isInvalid()) {
2897 if (Var)
2898 Var->Destroy(SemaRef.Context);
2899 return SemaRef.StmtError();
2900 }
Mike Stump25cf7602009-09-09 15:08:12 +00002901
Douglas Gregor23a44be2009-08-20 07:17:43 +00002902 if (!getDerived().AlwaysRebuild() &&
2903 !Var &&
2904 Handler.get() == S->getHandlerBlock())
Mike Stump25cf7602009-09-09 15:08:12 +00002905 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002906
2907 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
2908 Var,
2909 move(Handler));
2910}
Mike Stump25cf7602009-09-09 15:08:12 +00002911
Douglas Gregor23a44be2009-08-20 07:17:43 +00002912template<typename Derived>
2913Sema::OwningStmtResult
2914TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
2915 // Transform the try block itself.
Mike Stump25cf7602009-09-09 15:08:12 +00002916 OwningStmtResult TryBlock
Douglas Gregor23a44be2009-08-20 07:17:43 +00002917 = getDerived().TransformCompoundStmt(S->getTryBlock());
2918 if (TryBlock.isInvalid())
2919 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002920
Douglas Gregor23a44be2009-08-20 07:17:43 +00002921 // Transform the handlers.
2922 bool HandlerChanged = false;
2923 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
2924 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump25cf7602009-09-09 15:08:12 +00002925 OwningStmtResult Handler
Douglas Gregor23a44be2009-08-20 07:17:43 +00002926 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
2927 if (Handler.isInvalid())
2928 return SemaRef.StmtError();
Mike Stump25cf7602009-09-09 15:08:12 +00002929
Douglas Gregor23a44be2009-08-20 07:17:43 +00002930 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
2931 Handlers.push_back(Handler.takeAs<Stmt>());
2932 }
Mike Stump25cf7602009-09-09 15:08:12 +00002933
Douglas Gregor23a44be2009-08-20 07:17:43 +00002934 if (!getDerived().AlwaysRebuild() &&
2935 TryBlock.get() == S->getTryBlock() &&
2936 !HandlerChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00002937 return SemaRef.Owned(S->Retain());
Douglas Gregor23a44be2009-08-20 07:17:43 +00002938
2939 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump25cf7602009-09-09 15:08:12 +00002940 move_arg(Handlers));
Douglas Gregor23a44be2009-08-20 07:17:43 +00002941}
Mike Stump25cf7602009-09-09 15:08:12 +00002942
Douglas Gregor23a44be2009-08-20 07:17:43 +00002943//===----------------------------------------------------------------------===//
Douglas Gregor9d879762009-08-11 05:31:07 +00002944// Expression transformation
2945//===----------------------------------------------------------------------===//
Mike Stump25cf7602009-09-09 15:08:12 +00002946template<typename Derived>
2947Sema::OwningExprResult
2948TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
2949 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00002950}
Mike Stump25cf7602009-09-09 15:08:12 +00002951
2952template<typename Derived>
2953Sema::OwningExprResult
2954TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
2955 NamedDecl *ND
Douglas Gregor9d879762009-08-11 05:31:07 +00002956 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
2957 if (!ND)
2958 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00002959
Douglas Gregor9d879762009-08-11 05:31:07 +00002960 if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
Mike Stump25cf7602009-09-09 15:08:12 +00002961 return SemaRef.Owned(E->Retain());
2962
Douglas Gregor9d879762009-08-11 05:31:07 +00002963 return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
2964}
Mike Stump25cf7602009-09-09 15:08:12 +00002965
Douglas Gregor9d879762009-08-11 05:31:07 +00002966template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002967Sema::OwningExprResult
2968TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
2969 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00002970}
Mike Stump25cf7602009-09-09 15:08:12 +00002971
Douglas Gregor9d879762009-08-11 05:31:07 +00002972template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002973Sema::OwningExprResult
2974TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
2975 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00002976}
Mike Stump25cf7602009-09-09 15:08:12 +00002977
Douglas Gregor9d879762009-08-11 05:31:07 +00002978template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002979Sema::OwningExprResult
2980TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
2981 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00002982}
Mike Stump25cf7602009-09-09 15:08:12 +00002983
Douglas Gregor9d879762009-08-11 05:31:07 +00002984template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002985Sema::OwningExprResult
2986TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
2987 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00002988}
Mike Stump25cf7602009-09-09 15:08:12 +00002989
Douglas Gregor9d879762009-08-11 05:31:07 +00002990template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00002991Sema::OwningExprResult
2992TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
2993 return SemaRef.Owned(E->Retain());
2994}
2995
2996template<typename Derived>
2997Sema::OwningExprResult
2998TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00002999 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3000 if (SubExpr.isInvalid())
3001 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003002
Douglas Gregor9d879762009-08-11 05:31:07 +00003003 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003004 return SemaRef.Owned(E->Retain());
3005
3006 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003007 E->getRParen());
3008}
3009
Mike Stump25cf7602009-09-09 15:08:12 +00003010template<typename Derived>
3011Sema::OwningExprResult
3012TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003013 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3014 if (SubExpr.isInvalid())
3015 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003016
Douglas Gregor9d879762009-08-11 05:31:07 +00003017 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003018 return SemaRef.Owned(E->Retain());
3019
Douglas Gregor9d879762009-08-11 05:31:07 +00003020 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3021 E->getOpcode(),
3022 move(SubExpr));
3023}
Mike Stump25cf7602009-09-09 15:08:12 +00003024
Douglas Gregor9d879762009-08-11 05:31:07 +00003025template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003026Sema::OwningExprResult
3027TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003028 if (E->isArgumentType()) {
3029 QualType T = getDerived().TransformType(E->getArgumentType());
3030 if (T.isNull())
3031 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003032
Douglas Gregor9d879762009-08-11 05:31:07 +00003033 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3034 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003035
3036 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3037 E->isSizeOf(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003038 E->getSourceRange());
3039 }
Mike Stump25cf7602009-09-09 15:08:12 +00003040
Douglas Gregor9d879762009-08-11 05:31:07 +00003041 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump25cf7602009-09-09 15:08:12 +00003042 {
Douglas Gregor9d879762009-08-11 05:31:07 +00003043 // C++0x [expr.sizeof]p1:
3044 // The operand is either an expression, which is an unevaluated operand
3045 // [...]
3046 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00003047
Douglas Gregor9d879762009-08-11 05:31:07 +00003048 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3049 if (SubExpr.isInvalid())
3050 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003051
Douglas Gregor9d879762009-08-11 05:31:07 +00003052 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3053 return SemaRef.Owned(E->Retain());
3054 }
Mike Stump25cf7602009-09-09 15:08:12 +00003055
Douglas Gregor9d879762009-08-11 05:31:07 +00003056 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3057 E->isSizeOf(),
3058 E->getSourceRange());
3059}
Mike Stump25cf7602009-09-09 15:08:12 +00003060
Douglas Gregor9d879762009-08-11 05:31:07 +00003061template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003062Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003063TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3064 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3065 if (LHS.isInvalid())
3066 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003067
Douglas Gregor9d879762009-08-11 05:31:07 +00003068 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3069 if (RHS.isInvalid())
3070 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003071
3072
Douglas Gregor9d879762009-08-11 05:31:07 +00003073 if (!getDerived().AlwaysRebuild() &&
3074 LHS.get() == E->getLHS() &&
3075 RHS.get() == E->getRHS())
3076 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003077
Douglas Gregor9d879762009-08-11 05:31:07 +00003078 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3079 /*FIXME:*/E->getLHS()->getLocStart(),
3080 move(RHS),
3081 E->getRBracketLoc());
3082}
Mike Stump25cf7602009-09-09 15:08:12 +00003083
3084template<typename Derived>
3085Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003086TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3087 // Transform the callee.
3088 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3089 if (Callee.isInvalid())
3090 return SemaRef.ExprError();
3091
3092 // Transform arguments.
3093 bool ArgChanged = false;
3094 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3095 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3096 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3097 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3098 if (Arg.isInvalid())
3099 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003100
Douglas Gregor9d879762009-08-11 05:31:07 +00003101 // FIXME: Wrong source location information for the ','.
3102 FakeCommaLocs.push_back(
3103 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump25cf7602009-09-09 15:08:12 +00003104
3105 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregor9d879762009-08-11 05:31:07 +00003106 Args.push_back(Arg.takeAs<Expr>());
3107 }
Mike Stump25cf7602009-09-09 15:08:12 +00003108
Douglas Gregor9d879762009-08-11 05:31:07 +00003109 if (!getDerived().AlwaysRebuild() &&
3110 Callee.get() == E->getCallee() &&
3111 !ArgChanged)
3112 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003113
Douglas Gregor9d879762009-08-11 05:31:07 +00003114 // FIXME: Wrong source location information for the '('.
Mike Stump25cf7602009-09-09 15:08:12 +00003115 SourceLocation FakeLParenLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00003116 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3117 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3118 move_arg(Args),
3119 FakeCommaLocs.data(),
3120 E->getRParenLoc());
3121}
Mike Stump25cf7602009-09-09 15:08:12 +00003122
3123template<typename Derived>
3124Sema::OwningExprResult
3125TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003126 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3127 if (Base.isInvalid())
3128 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003129
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003130 NestedNameSpecifier *Qualifier = 0;
3131 if (E->hasQualifier()) {
Mike Stump25cf7602009-09-09 15:08:12 +00003132 Qualifier
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003133 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3134 E->getQualifierRange());
Douglas Gregord33e3282009-09-01 00:37:14 +00003135 if (Qualifier == 0)
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003136 return SemaRef.ExprError();
3137 }
Mike Stump25cf7602009-09-09 15:08:12 +00003138
3139 NamedDecl *Member
Douglas Gregor9d879762009-08-11 05:31:07 +00003140 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3141 if (!Member)
3142 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003143
Douglas Gregor9d879762009-08-11 05:31:07 +00003144 if (!getDerived().AlwaysRebuild() &&
3145 Base.get() == E->getBase() &&
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003146 Qualifier == E->getQualifier() &&
Douglas Gregor9d879762009-08-11 05:31:07 +00003147 Member == E->getMemberDecl())
Mike Stump25cf7602009-09-09 15:08:12 +00003148 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003149
3150 // FIXME: Bogus source location for the operator
3151 SourceLocation FakeOperatorLoc
3152 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3153
3154 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3155 E->isArrow(),
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003156 Qualifier,
3157 E->getQualifierRange(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003158 E->getMemberLoc(),
Mike Stump25cf7602009-09-09 15:08:12 +00003159 Member);
Douglas Gregor9d879762009-08-11 05:31:07 +00003160}
Mike Stump25cf7602009-09-09 15:08:12 +00003161
Douglas Gregor9d879762009-08-11 05:31:07 +00003162template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00003163Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003164TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3165 assert(false && "Cannot transform abstract class");
3166 return SemaRef.Owned(E->Retain());
3167}
3168
3169template<typename Derived>
3170Sema::OwningExprResult
3171TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003172 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3173 if (LHS.isInvalid())
3174 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003175
Douglas Gregor9d879762009-08-11 05:31:07 +00003176 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3177 if (RHS.isInvalid())
3178 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003179
Douglas Gregor9d879762009-08-11 05:31:07 +00003180 if (!getDerived().AlwaysRebuild() &&
3181 LHS.get() == E->getLHS() &&
3182 RHS.get() == E->getRHS())
Mike Stump25cf7602009-09-09 15:08:12 +00003183 return SemaRef.Owned(E->Retain());
3184
Douglas Gregor9d879762009-08-11 05:31:07 +00003185 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3186 move(LHS), move(RHS));
3187}
3188
Mike Stump25cf7602009-09-09 15:08:12 +00003189template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00003190Sema::OwningExprResult
3191TreeTransform<Derived>::TransformCompoundAssignOperator(
3192 CompoundAssignOperator *E) {
3193 return getDerived().TransformBinaryOperator(E);
3194}
Mike Stump25cf7602009-09-09 15:08:12 +00003195
Douglas Gregor9d879762009-08-11 05:31:07 +00003196template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003197Sema::OwningExprResult
3198TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003199 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3200 if (Cond.isInvalid())
3201 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003202
Douglas Gregor9d879762009-08-11 05:31:07 +00003203 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3204 if (LHS.isInvalid())
3205 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003206
Douglas Gregor9d879762009-08-11 05:31:07 +00003207 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3208 if (RHS.isInvalid())
3209 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003210
Douglas Gregor9d879762009-08-11 05:31:07 +00003211 if (!getDerived().AlwaysRebuild() &&
3212 Cond.get() == E->getCond() &&
3213 LHS.get() == E->getLHS() &&
3214 RHS.get() == E->getRHS())
3215 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003216
3217 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor34619872009-08-26 14:37:04 +00003218 E->getQuestionLoc(),
Mike Stump25cf7602009-09-09 15:08:12 +00003219 move(LHS),
Douglas Gregor34619872009-08-26 14:37:04 +00003220 E->getColonLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003221 move(RHS));
3222}
Mike Stump25cf7602009-09-09 15:08:12 +00003223
3224template<typename Derived>
3225Sema::OwningExprResult
3226TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003227 QualType T = getDerived().TransformType(E->getType());
3228 if (T.isNull())
3229 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003230
Douglas Gregor9d879762009-08-11 05:31:07 +00003231 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3232 if (SubExpr.isInvalid())
3233 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003234
Douglas Gregor9d879762009-08-11 05:31:07 +00003235 if (!getDerived().AlwaysRebuild() &&
3236 T == E->getType() &&
3237 SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003238 return SemaRef.Owned(E->Retain());
3239
Douglas Gregor9d879762009-08-11 05:31:07 +00003240 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump25cf7602009-09-09 15:08:12 +00003241 move(SubExpr),
Douglas Gregor9d879762009-08-11 05:31:07 +00003242 E->isLvalueCast());
3243}
Mike Stump25cf7602009-09-09 15:08:12 +00003244
Douglas Gregor9d879762009-08-11 05:31:07 +00003245template<typename Derived>
3246Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003247TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3248 assert(false && "Cannot transform abstract class");
3249 return SemaRef.Owned(E->Retain());
3250}
3251
3252template<typename Derived>
3253Sema::OwningExprResult
3254TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003255 QualType T;
3256 {
3257 // FIXME: Source location isn't quite accurate.
Mike Stump25cf7602009-09-09 15:08:12 +00003258 SourceLocation TypeStartLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00003259 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3260 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003261
Douglas Gregor9d879762009-08-11 05:31:07 +00003262 T = getDerived().TransformType(E->getTypeAsWritten());
3263 if (T.isNull())
3264 return SemaRef.ExprError();
3265 }
Mike Stump25cf7602009-09-09 15:08:12 +00003266
Douglas Gregor9d879762009-08-11 05:31:07 +00003267 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3268 if (SubExpr.isInvalid())
3269 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003270
Douglas Gregor9d879762009-08-11 05:31:07 +00003271 if (!getDerived().AlwaysRebuild() &&
3272 T == E->getTypeAsWritten() &&
3273 SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003274 return SemaRef.Owned(E->Retain());
3275
Douglas Gregor9d879762009-08-11 05:31:07 +00003276 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3277 E->getRParenLoc(),
3278 move(SubExpr));
3279}
Mike Stump25cf7602009-09-09 15:08:12 +00003280
Douglas Gregor9d879762009-08-11 05:31:07 +00003281template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003282Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003283TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3284 QualType T;
3285 {
3286 // FIXME: Source location isn't quite accurate.
Mike Stump25cf7602009-09-09 15:08:12 +00003287 SourceLocation FakeTypeLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00003288 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3289 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003290
Douglas Gregor9d879762009-08-11 05:31:07 +00003291 T = getDerived().TransformType(E->getType());
3292 if (T.isNull())
3293 return SemaRef.ExprError();
3294 }
Mike Stump25cf7602009-09-09 15:08:12 +00003295
Douglas Gregor9d879762009-08-11 05:31:07 +00003296 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3297 if (Init.isInvalid())
3298 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003299
Douglas Gregor9d879762009-08-11 05:31:07 +00003300 if (!getDerived().AlwaysRebuild() &&
3301 T == E->getType() &&
3302 Init.get() == E->getInitializer())
Mike Stump25cf7602009-09-09 15:08:12 +00003303 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003304
3305 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3306 /*FIXME:*/E->getInitializer()->getLocEnd(),
3307 move(Init));
3308}
Mike Stump25cf7602009-09-09 15:08:12 +00003309
Douglas Gregor9d879762009-08-11 05:31:07 +00003310template<typename Derived>
3311Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003312TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003313 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3314 if (Base.isInvalid())
3315 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003316
Douglas Gregor9d879762009-08-11 05:31:07 +00003317 if (!getDerived().AlwaysRebuild() &&
3318 Base.get() == E->getBase())
Mike Stump25cf7602009-09-09 15:08:12 +00003319 return SemaRef.Owned(E->Retain());
3320
Douglas Gregor9d879762009-08-11 05:31:07 +00003321 // FIXME: Bad source location
Mike Stump25cf7602009-09-09 15:08:12 +00003322 SourceLocation FakeOperatorLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00003323 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3324 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3325 E->getAccessorLoc(),
3326 E->getAccessor());
3327}
Mike Stump25cf7602009-09-09 15:08:12 +00003328
Douglas Gregor9d879762009-08-11 05:31:07 +00003329template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003330Sema::OwningExprResult
3331TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003332 bool InitChanged = false;
Mike Stump25cf7602009-09-09 15:08:12 +00003333
Douglas Gregor9d879762009-08-11 05:31:07 +00003334 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3335 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3336 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3337 if (Init.isInvalid())
3338 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003339
Douglas Gregor9d879762009-08-11 05:31:07 +00003340 InitChanged = InitChanged || Init.get() != E->getInit(I);
3341 Inits.push_back(Init.takeAs<Expr>());
3342 }
Mike Stump25cf7602009-09-09 15:08:12 +00003343
Douglas Gregor9d879762009-08-11 05:31:07 +00003344 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00003345 return SemaRef.Owned(E->Retain());
3346
Douglas Gregor9d879762009-08-11 05:31:07 +00003347 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3348 E->getRBraceLoc());
3349}
Mike Stump25cf7602009-09-09 15:08:12 +00003350
Douglas Gregor9d879762009-08-11 05:31:07 +00003351template<typename Derived>
3352Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003353TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003354 Designation Desig;
Mike Stump25cf7602009-09-09 15:08:12 +00003355
Douglas Gregor23a44be2009-08-20 07:17:43 +00003356 // transform the initializer value
Douglas Gregor9d879762009-08-11 05:31:07 +00003357 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3358 if (Init.isInvalid())
3359 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003360
Douglas Gregor23a44be2009-08-20 07:17:43 +00003361 // transform the designators.
Douglas Gregor9d879762009-08-11 05:31:07 +00003362 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3363 bool ExprChanged = false;
3364 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3365 DEnd = E->designators_end();
3366 D != DEnd; ++D) {
3367 if (D->isFieldDesignator()) {
3368 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3369 D->getDotLoc(),
3370 D->getFieldLoc()));
3371 continue;
3372 }
Mike Stump25cf7602009-09-09 15:08:12 +00003373
Douglas Gregor9d879762009-08-11 05:31:07 +00003374 if (D->isArrayDesignator()) {
3375 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3376 if (Index.isInvalid())
3377 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003378
3379 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003380 D->getLBracketLoc()));
Mike Stump25cf7602009-09-09 15:08:12 +00003381
Douglas Gregor9d879762009-08-11 05:31:07 +00003382 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3383 ArrayExprs.push_back(Index.release());
3384 continue;
3385 }
Mike Stump25cf7602009-09-09 15:08:12 +00003386
Douglas Gregor9d879762009-08-11 05:31:07 +00003387 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump25cf7602009-09-09 15:08:12 +00003388 OwningExprResult Start
Douglas Gregor9d879762009-08-11 05:31:07 +00003389 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3390 if (Start.isInvalid())
3391 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003392
Douglas Gregor9d879762009-08-11 05:31:07 +00003393 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3394 if (End.isInvalid())
3395 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003396
3397 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003398 End.get(),
3399 D->getLBracketLoc(),
3400 D->getEllipsisLoc()));
Mike Stump25cf7602009-09-09 15:08:12 +00003401
Douglas Gregor9d879762009-08-11 05:31:07 +00003402 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3403 End.get() != E->getArrayRangeEnd(*D);
Mike Stump25cf7602009-09-09 15:08:12 +00003404
Douglas Gregor9d879762009-08-11 05:31:07 +00003405 ArrayExprs.push_back(Start.release());
3406 ArrayExprs.push_back(End.release());
3407 }
Mike Stump25cf7602009-09-09 15:08:12 +00003408
Douglas Gregor9d879762009-08-11 05:31:07 +00003409 if (!getDerived().AlwaysRebuild() &&
3410 Init.get() == E->getInit() &&
3411 !ExprChanged)
3412 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003413
Douglas Gregor9d879762009-08-11 05:31:07 +00003414 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3415 E->getEqualOrColonLoc(),
3416 E->usesGNUSyntax(), move(Init));
3417}
Mike Stump25cf7602009-09-09 15:08:12 +00003418
Douglas Gregor9d879762009-08-11 05:31:07 +00003419template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003420Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003421TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00003422 ImplicitValueInitExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003423 QualType T = getDerived().TransformType(E->getType());
3424 if (T.isNull())
3425 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003426
Douglas Gregor9d879762009-08-11 05:31:07 +00003427 if (!getDerived().AlwaysRebuild() &&
3428 T == E->getType())
Mike Stump25cf7602009-09-09 15:08:12 +00003429 return SemaRef.Owned(E->Retain());
3430
Douglas Gregor9d879762009-08-11 05:31:07 +00003431 return getDerived().RebuildImplicitValueInitExpr(T);
3432}
Mike Stump25cf7602009-09-09 15:08:12 +00003433
Douglas Gregor9d879762009-08-11 05:31:07 +00003434template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003435Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003436TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3437 // FIXME: Do we want the type as written?
3438 QualType T;
Mike Stump25cf7602009-09-09 15:08:12 +00003439
Douglas Gregor9d879762009-08-11 05:31:07 +00003440 {
3441 // FIXME: Source location isn't quite accurate.
3442 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3443 T = getDerived().TransformType(E->getType());
3444 if (T.isNull())
3445 return SemaRef.ExprError();
3446 }
Mike Stump25cf7602009-09-09 15:08:12 +00003447
Douglas Gregor9d879762009-08-11 05:31:07 +00003448 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3449 if (SubExpr.isInvalid())
3450 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003451
Douglas Gregor9d879762009-08-11 05:31:07 +00003452 if (!getDerived().AlwaysRebuild() &&
3453 T == E->getType() &&
3454 SubExpr.get() == E->getSubExpr())
3455 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003456
Douglas Gregor9d879762009-08-11 05:31:07 +00003457 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3458 T, E->getRParenLoc());
3459}
3460
3461template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003462Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003463TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3464 bool ArgumentChanged = false;
3465 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3466 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3467 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3468 if (Init.isInvalid())
3469 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003470
Douglas Gregor9d879762009-08-11 05:31:07 +00003471 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3472 Inits.push_back(Init.takeAs<Expr>());
3473 }
Mike Stump25cf7602009-09-09 15:08:12 +00003474
Douglas Gregor9d879762009-08-11 05:31:07 +00003475 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3476 move_arg(Inits),
3477 E->getRParenLoc());
3478}
Mike Stump25cf7602009-09-09 15:08:12 +00003479
Douglas Gregor9d879762009-08-11 05:31:07 +00003480/// \brief Transform an address-of-label expression.
3481///
3482/// By default, the transformation of an address-of-label expression always
3483/// rebuilds the expression, so that the label identifier can be resolved to
3484/// the corresponding label statement by semantic analysis.
3485template<typename Derived>
3486Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003487TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003488 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3489 E->getLabel());
3490}
Mike Stump25cf7602009-09-09 15:08:12 +00003491
3492template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00003493Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump25cf7602009-09-09 15:08:12 +00003494 OwningStmtResult SubStmt
Douglas Gregor9d879762009-08-11 05:31:07 +00003495 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3496 if (SubStmt.isInvalid())
3497 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003498
Douglas Gregor9d879762009-08-11 05:31:07 +00003499 if (!getDerived().AlwaysRebuild() &&
3500 SubStmt.get() == E->getSubStmt())
3501 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003502
3503 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003504 move(SubStmt),
3505 E->getRParenLoc());
3506}
Mike Stump25cf7602009-09-09 15:08:12 +00003507
Douglas Gregor9d879762009-08-11 05:31:07 +00003508template<typename Derived>
3509Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003510TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003511 QualType T1, T2;
3512 {
3513 // FIXME: Source location isn't quite accurate.
3514 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003515
Douglas Gregor9d879762009-08-11 05:31:07 +00003516 T1 = getDerived().TransformType(E->getArgType1());
3517 if (T1.isNull())
3518 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003519
Douglas Gregor9d879762009-08-11 05:31:07 +00003520 T2 = getDerived().TransformType(E->getArgType2());
3521 if (T2.isNull())
3522 return SemaRef.ExprError();
3523 }
3524
3525 if (!getDerived().AlwaysRebuild() &&
3526 T1 == E->getArgType1() &&
3527 T2 == E->getArgType2())
Mike Stump25cf7602009-09-09 15:08:12 +00003528 return SemaRef.Owned(E->Retain());
3529
Douglas Gregor9d879762009-08-11 05:31:07 +00003530 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3531 T1, T2, E->getRParenLoc());
3532}
Mike Stump25cf7602009-09-09 15:08:12 +00003533
Douglas Gregor9d879762009-08-11 05:31:07 +00003534template<typename Derived>
3535Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003536TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003537 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3538 if (Cond.isInvalid())
3539 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003540
Douglas Gregor9d879762009-08-11 05:31:07 +00003541 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3542 if (LHS.isInvalid())
3543 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003544
Douglas Gregor9d879762009-08-11 05:31:07 +00003545 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3546 if (RHS.isInvalid())
3547 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003548
Douglas Gregor9d879762009-08-11 05:31:07 +00003549 if (!getDerived().AlwaysRebuild() &&
3550 Cond.get() == E->getCond() &&
3551 LHS.get() == E->getLHS() &&
3552 RHS.get() == E->getRHS())
Mike Stump25cf7602009-09-09 15:08:12 +00003553 return SemaRef.Owned(E->Retain());
3554
Douglas Gregor9d879762009-08-11 05:31:07 +00003555 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3556 move(Cond), move(LHS), move(RHS),
3557 E->getRParenLoc());
3558}
Mike Stump25cf7602009-09-09 15:08:12 +00003559
Douglas Gregor9d879762009-08-11 05:31:07 +00003560template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003561Sema::OwningExprResult
3562TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3563 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003564}
3565
3566template<typename Derived>
3567Sema::OwningExprResult
3568TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3569 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3570 if (Callee.isInvalid())
3571 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003572
Douglas Gregor9d879762009-08-11 05:31:07 +00003573 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3574 if (First.isInvalid())
3575 return SemaRef.ExprError();
3576
3577 OwningExprResult Second(SemaRef);
3578 if (E->getNumArgs() == 2) {
3579 Second = getDerived().TransformExpr(E->getArg(1));
3580 if (Second.isInvalid())
3581 return SemaRef.ExprError();
3582 }
Mike Stump25cf7602009-09-09 15:08:12 +00003583
Douglas Gregor9d879762009-08-11 05:31:07 +00003584 if (!getDerived().AlwaysRebuild() &&
3585 Callee.get() == E->getCallee() &&
3586 First.get() == E->getArg(0) &&
Mike Stump25cf7602009-09-09 15:08:12 +00003587 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3588 return SemaRef.Owned(E->Retain());
3589
Douglas Gregor9d879762009-08-11 05:31:07 +00003590 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3591 E->getOperatorLoc(),
Mike Stump25cf7602009-09-09 15:08:12 +00003592 move(Callee),
Douglas Gregor9d879762009-08-11 05:31:07 +00003593 move(First),
3594 move(Second));
3595}
Mike Stump25cf7602009-09-09 15:08:12 +00003596
Douglas Gregor9d879762009-08-11 05:31:07 +00003597template<typename Derived>
3598Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003599TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003600 return getDerived().TransformCallExpr(E);
3601}
Mike Stump25cf7602009-09-09 15:08:12 +00003602
Douglas Gregor9d879762009-08-11 05:31:07 +00003603template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003604Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003605TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3606 QualType ExplicitTy;
3607 {
3608 // FIXME: Source location isn't quite accurate.
Mike Stump25cf7602009-09-09 15:08:12 +00003609 SourceLocation TypeStartLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00003610 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3611 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003612
Douglas Gregor9d879762009-08-11 05:31:07 +00003613 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3614 if (ExplicitTy.isNull())
3615 return SemaRef.ExprError();
3616 }
Mike Stump25cf7602009-09-09 15:08:12 +00003617
Douglas Gregor9d879762009-08-11 05:31:07 +00003618 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3619 if (SubExpr.isInvalid())
3620 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003621
Douglas Gregor9d879762009-08-11 05:31:07 +00003622 if (!getDerived().AlwaysRebuild() &&
3623 ExplicitTy == E->getTypeAsWritten() &&
3624 SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003625 return SemaRef.Owned(E->Retain());
3626
Douglas Gregor9d879762009-08-11 05:31:07 +00003627 // FIXME: Poor source location information here.
Mike Stump25cf7602009-09-09 15:08:12 +00003628 SourceLocation FakeLAngleLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00003629 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3630 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3631 SourceLocation FakeRParenLoc
3632 = SemaRef.PP.getLocForEndOfToken(
3633 E->getSubExpr()->getSourceRange().getEnd());
3634 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump25cf7602009-09-09 15:08:12 +00003635 E->getStmtClass(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003636 FakeLAngleLoc,
3637 ExplicitTy,
3638 FakeRAngleLoc,
3639 FakeRAngleLoc,
3640 move(SubExpr),
3641 FakeRParenLoc);
3642}
Mike Stump25cf7602009-09-09 15:08:12 +00003643
Douglas Gregor9d879762009-08-11 05:31:07 +00003644template<typename Derived>
3645Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003646TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003647 return getDerived().TransformCXXNamedCastExpr(E);
3648}
Mike Stump25cf7602009-09-09 15:08:12 +00003649
3650template<typename Derived>
3651Sema::OwningExprResult
3652TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
3653 return getDerived().TransformCXXNamedCastExpr(E);
3654}
3655
Douglas Gregor9d879762009-08-11 05:31:07 +00003656template<typename Derived>
3657Sema::OwningExprResult
3658TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00003659 CXXReinterpretCastExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003660 return getDerived().TransformCXXNamedCastExpr(E);
3661}
Mike Stump25cf7602009-09-09 15:08:12 +00003662
Douglas Gregor9d879762009-08-11 05:31:07 +00003663template<typename Derived>
3664Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003665TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003666 return getDerived().TransformCXXNamedCastExpr(E);
3667}
Mike Stump25cf7602009-09-09 15:08:12 +00003668
Douglas Gregor9d879762009-08-11 05:31:07 +00003669template<typename Derived>
3670Sema::OwningExprResult
3671TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00003672 CXXFunctionalCastExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003673 QualType ExplicitTy;
3674 {
3675 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003676
Douglas Gregor9d879762009-08-11 05:31:07 +00003677 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3678 if (ExplicitTy.isNull())
3679 return SemaRef.ExprError();
3680 }
Mike Stump25cf7602009-09-09 15:08:12 +00003681
Douglas Gregor9d879762009-08-11 05:31:07 +00003682 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3683 if (SubExpr.isInvalid())
3684 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003685
Douglas Gregor9d879762009-08-11 05:31:07 +00003686 if (!getDerived().AlwaysRebuild() &&
3687 ExplicitTy == E->getTypeAsWritten() &&
3688 SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003689 return SemaRef.Owned(E->Retain());
3690
Douglas Gregor9d879762009-08-11 05:31:07 +00003691 // FIXME: The end of the type's source range is wrong
3692 return getDerived().RebuildCXXFunctionalCastExpr(
3693 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
3694 ExplicitTy,
3695 /*FIXME:*/E->getSubExpr()->getLocStart(),
3696 move(SubExpr),
3697 E->getRParenLoc());
3698}
Mike Stump25cf7602009-09-09 15:08:12 +00003699
Douglas Gregor9d879762009-08-11 05:31:07 +00003700template<typename Derived>
3701Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003702TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003703 if (E->isTypeOperand()) {
3704 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003705
Douglas Gregor9d879762009-08-11 05:31:07 +00003706 QualType T = getDerived().TransformType(E->getTypeOperand());
3707 if (T.isNull())
3708 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003709
Douglas Gregor9d879762009-08-11 05:31:07 +00003710 if (!getDerived().AlwaysRebuild() &&
3711 T == E->getTypeOperand())
3712 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003713
Douglas Gregor9d879762009-08-11 05:31:07 +00003714 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3715 /*FIXME:*/E->getLocStart(),
3716 T,
3717 E->getLocEnd());
3718 }
Mike Stump25cf7602009-09-09 15:08:12 +00003719
Douglas Gregor9d879762009-08-11 05:31:07 +00003720 // We don't know whether the expression is potentially evaluated until
3721 // after we perform semantic analysis, so the expression is potentially
3722 // potentially evaluated.
Mike Stump25cf7602009-09-09 15:08:12 +00003723 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregor9d879762009-08-11 05:31:07 +00003724 Action::PotentiallyPotentiallyEvaluated);
Mike Stump25cf7602009-09-09 15:08:12 +00003725
Douglas Gregor9d879762009-08-11 05:31:07 +00003726 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
3727 if (SubExpr.isInvalid())
3728 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003729
Douglas Gregor9d879762009-08-11 05:31:07 +00003730 if (!getDerived().AlwaysRebuild() &&
3731 SubExpr.get() == E->getExprOperand())
Mike Stump25cf7602009-09-09 15:08:12 +00003732 return SemaRef.Owned(E->Retain());
3733
Douglas Gregor9d879762009-08-11 05:31:07 +00003734 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3735 /*FIXME:*/E->getLocStart(),
3736 move(SubExpr),
3737 E->getLocEnd());
3738}
3739
3740template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00003741Sema::OwningExprResult
3742TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
3743 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003744}
Mike Stump25cf7602009-09-09 15:08:12 +00003745
Douglas Gregor9d879762009-08-11 05:31:07 +00003746template<typename Derived>
3747Sema::OwningExprResult
3748TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00003749 CXXNullPtrLiteralExpr *E) {
3750 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003751}
Mike Stump25cf7602009-09-09 15:08:12 +00003752
Douglas Gregor9d879762009-08-11 05:31:07 +00003753template<typename Derived>
3754Sema::OwningExprResult
3755TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
3756 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003757
Douglas Gregor9d879762009-08-11 05:31:07 +00003758 QualType T = getDerived().TransformType(E->getType());
3759 if (T.isNull())
3760 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003761
Douglas Gregor9d879762009-08-11 05:31:07 +00003762 if (!getDerived().AlwaysRebuild() &&
3763 T == E->getType())
3764 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003765
Douglas Gregor9d879762009-08-11 05:31:07 +00003766 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
3767}
Mike Stump25cf7602009-09-09 15:08:12 +00003768
Douglas Gregor9d879762009-08-11 05:31:07 +00003769template<typename Derived>
3770Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003771TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003772 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3773 if (SubExpr.isInvalid())
3774 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003775
Douglas Gregor9d879762009-08-11 05:31:07 +00003776 if (!getDerived().AlwaysRebuild() &&
3777 SubExpr.get() == E->getSubExpr())
Mike Stump25cf7602009-09-09 15:08:12 +00003778 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003779
3780 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
3781}
Mike Stump25cf7602009-09-09 15:08:12 +00003782
Douglas Gregor9d879762009-08-11 05:31:07 +00003783template<typename Derived>
3784Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003785TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
3786 ParmVarDecl *Param
Douglas Gregor9d879762009-08-11 05:31:07 +00003787 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
3788 if (!Param)
3789 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003790
Douglas Gregor9d879762009-08-11 05:31:07 +00003791 if (getDerived().AlwaysRebuild() &&
3792 Param == E->getParam())
3793 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003794
Douglas Gregor9d879762009-08-11 05:31:07 +00003795 return getDerived().RebuildCXXDefaultArgExpr(Param);
3796}
Mike Stump25cf7602009-09-09 15:08:12 +00003797
Douglas Gregor9d879762009-08-11 05:31:07 +00003798template<typename Derived>
3799Sema::OwningExprResult
3800TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
3801 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3802
3803 QualType T = getDerived().TransformType(E->getType());
3804 if (T.isNull())
3805 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003806
Douglas Gregor9d879762009-08-11 05:31:07 +00003807 if (!getDerived().AlwaysRebuild() &&
3808 T == E->getType())
Mike Stump25cf7602009-09-09 15:08:12 +00003809 return SemaRef.Owned(E->Retain());
3810
3811 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003812 /*FIXME:*/E->getTypeBeginLoc(),
3813 T,
3814 E->getRParenLoc());
3815}
Mike Stump25cf7602009-09-09 15:08:12 +00003816
Douglas Gregor9d879762009-08-11 05:31:07 +00003817template<typename Derived>
3818Sema::OwningExprResult
3819TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump25cf7602009-09-09 15:08:12 +00003820 VarDecl *Var
Douglas Gregor23a44be2009-08-20 07:17:43 +00003821 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregor9d879762009-08-11 05:31:07 +00003822 if (!Var)
3823 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003824
Douglas Gregor9d879762009-08-11 05:31:07 +00003825 if (!getDerived().AlwaysRebuild() &&
Mike Stump25cf7602009-09-09 15:08:12 +00003826 Var == E->getVarDecl())
Douglas Gregor9d879762009-08-11 05:31:07 +00003827 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003828
3829 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003830 /*FIXME:*/E->getStartLoc(),
3831 Var);
3832}
Mike Stump25cf7602009-09-09 15:08:12 +00003833
Douglas Gregor9d879762009-08-11 05:31:07 +00003834template<typename Derived>
3835Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003836TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003837 // Transform the type that we're allocating
3838 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3839 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
3840 if (AllocType.isNull())
3841 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003842
Douglas Gregor9d879762009-08-11 05:31:07 +00003843 // Transform the size of the array we're allocating (if any).
3844 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
3845 if (ArraySize.isInvalid())
3846 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003847
Douglas Gregor9d879762009-08-11 05:31:07 +00003848 // Transform the placement arguments (if any).
3849 bool ArgumentChanged = false;
3850 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
3851 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
3852 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
3853 if (Arg.isInvalid())
3854 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003855
Douglas Gregor9d879762009-08-11 05:31:07 +00003856 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
3857 PlacementArgs.push_back(Arg.take());
3858 }
Mike Stump25cf7602009-09-09 15:08:12 +00003859
Douglas Gregor23a44be2009-08-20 07:17:43 +00003860 // transform the constructor arguments (if any).
Douglas Gregor9d879762009-08-11 05:31:07 +00003861 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
3862 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
3863 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
3864 if (Arg.isInvalid())
3865 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003866
Douglas Gregor9d879762009-08-11 05:31:07 +00003867 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
3868 ConstructorArgs.push_back(Arg.take());
3869 }
Mike Stump25cf7602009-09-09 15:08:12 +00003870
Douglas Gregor9d879762009-08-11 05:31:07 +00003871 if (!getDerived().AlwaysRebuild() &&
3872 AllocType == E->getAllocatedType() &&
3873 ArraySize.get() == E->getArraySize() &&
3874 !ArgumentChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00003875 return SemaRef.Owned(E->Retain());
3876
Douglas Gregor9d879762009-08-11 05:31:07 +00003877 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
3878 E->isGlobalNew(),
3879 /*FIXME:*/E->getLocStart(),
3880 move_arg(PlacementArgs),
3881 /*FIXME:*/E->getLocStart(),
3882 E->isParenTypeId(),
3883 AllocType,
3884 /*FIXME:*/E->getLocStart(),
3885 /*FIXME:*/SourceRange(),
3886 move(ArraySize),
3887 /*FIXME:*/E->getLocStart(),
3888 move_arg(ConstructorArgs),
Mike Stump25cf7602009-09-09 15:08:12 +00003889 E->getLocEnd());
Douglas Gregor9d879762009-08-11 05:31:07 +00003890}
Mike Stump25cf7602009-09-09 15:08:12 +00003891
Douglas Gregor9d879762009-08-11 05:31:07 +00003892template<typename Derived>
3893Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003894TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003895 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
3896 if (Operand.isInvalid())
3897 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003898
Douglas Gregor9d879762009-08-11 05:31:07 +00003899 if (!getDerived().AlwaysRebuild() &&
Mike Stump25cf7602009-09-09 15:08:12 +00003900 Operand.get() == E->getArgument())
3901 return SemaRef.Owned(E->Retain());
3902
Douglas Gregor9d879762009-08-11 05:31:07 +00003903 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
3904 E->isGlobalDelete(),
3905 E->isArrayForm(),
3906 move(Operand));
3907}
Mike Stump25cf7602009-09-09 15:08:12 +00003908
Douglas Gregor9d879762009-08-11 05:31:07 +00003909template<typename Derived>
3910Sema::OwningExprResult
Douglas Gregor3e368512009-09-04 17:36:40 +00003911TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
3912 CXXPseudoDestructorExpr *E) {
3913 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3914 if (Base.isInvalid())
3915 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003916
Douglas Gregor3e368512009-09-04 17:36:40 +00003917 NestedNameSpecifier *Qualifier
3918 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3919 E->getQualifierRange());
3920 if (E->getQualifier() && !Qualifier)
3921 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003922
Douglas Gregor3e368512009-09-04 17:36:40 +00003923 QualType DestroyedType;
3924 {
3925 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
3926 DestroyedType = getDerived().TransformType(E->getDestroyedType());
3927 if (DestroyedType.isNull())
3928 return SemaRef.ExprError();
3929 }
Mike Stump25cf7602009-09-09 15:08:12 +00003930
Douglas Gregor3e368512009-09-04 17:36:40 +00003931 if (!getDerived().AlwaysRebuild() &&
3932 Base.get() == E->getBase() &&
3933 Qualifier == E->getQualifier() &&
3934 DestroyedType == E->getDestroyedType())
3935 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003936
Douglas Gregor3e368512009-09-04 17:36:40 +00003937 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
3938 E->getOperatorLoc(),
3939 E->isArrow(),
3940 E->getDestroyedTypeLoc(),
3941 DestroyedType,
3942 Qualifier,
3943 E->getQualifierRange());
3944}
Mike Stump25cf7602009-09-09 15:08:12 +00003945
Douglas Gregor3e368512009-09-04 17:36:40 +00003946template<typename Derived>
3947Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003948TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00003949 UnresolvedFunctionNameExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003950 // There is no transformation we can apply to an unresolved function name.
Mike Stump25cf7602009-09-09 15:08:12 +00003951 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00003952}
Mike Stump25cf7602009-09-09 15:08:12 +00003953
Douglas Gregor9d879762009-08-11 05:31:07 +00003954template<typename Derived>
3955Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00003956TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00003957 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump25cf7602009-09-09 15:08:12 +00003958
Douglas Gregor9d879762009-08-11 05:31:07 +00003959 QualType T = getDerived().TransformType(E->getQueriedType());
3960 if (T.isNull())
3961 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003962
Douglas Gregor9d879762009-08-11 05:31:07 +00003963 if (!getDerived().AlwaysRebuild() &&
3964 T == E->getQueriedType())
3965 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00003966
Douglas Gregor9d879762009-08-11 05:31:07 +00003967 // FIXME: Bad location information
3968 SourceLocation FakeLParenLoc
3969 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump25cf7602009-09-09 15:08:12 +00003970
3971 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003972 E->getLocStart(),
3973 /*FIXME:*/FakeLParenLoc,
3974 T,
3975 E->getLocEnd());
3976}
Mike Stump25cf7602009-09-09 15:08:12 +00003977
Douglas Gregor9d879762009-08-11 05:31:07 +00003978template<typename Derived>
3979Sema::OwningExprResult
3980TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
3981 NestedNameSpecifier *NNS
3982 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3983 E->getQualifierRange());
3984 if (!NNS)
3985 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003986
3987 NamedDecl *ND
Douglas Gregor9d879762009-08-11 05:31:07 +00003988 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3989 if (!ND)
3990 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00003991
3992 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor9d879762009-08-11 05:31:07 +00003993 NNS == E->getQualifier() &&
3994 ND == E->getDecl())
Mike Stump25cf7602009-09-09 15:08:12 +00003995 return SemaRef.Owned(E->Retain());
3996
3997 return getDerived().RebuildQualifiedDeclRefExpr(NNS,
Douglas Gregor9d879762009-08-11 05:31:07 +00003998 E->getQualifierRange(),
3999 ND,
4000 E->getLocation(),
4001 /*FIXME:*/false);
4002}
Mike Stump25cf7602009-09-09 15:08:12 +00004003
Douglas Gregor9d879762009-08-11 05:31:07 +00004004template<typename Derived>
4005Sema::OwningExprResult
4006TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00004007 UnresolvedDeclRefExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004008 NestedNameSpecifier *NNS
4009 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4010 E->getQualifierRange());
4011 if (!NNS)
4012 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004013
4014 DeclarationName Name
Douglas Gregora0651052009-09-03 22:13:48 +00004015 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4016 if (!Name)
4017 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004018
4019 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor9d879762009-08-11 05:31:07 +00004020 NNS == E->getQualifier() &&
4021 Name == E->getDeclName())
Mike Stump25cf7602009-09-09 15:08:12 +00004022 return SemaRef.Owned(E->Retain());
4023
4024 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregor9d879762009-08-11 05:31:07 +00004025 E->getQualifierRange(),
4026 Name,
4027 E->getLocation(),
4028 /*FIXME:*/false);
4029}
4030
4031template<typename Derived>
4032Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00004033TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
4034 TemplateName Template
Douglas Gregor9d879762009-08-11 05:31:07 +00004035 = getDerived().TransformTemplateName(E->getTemplateName());
4036 if (Template.isNull())
4037 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004038
Douglas Gregor9d879762009-08-11 05:31:07 +00004039 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4040 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump25cf7602009-09-09 15:08:12 +00004041 TemplateArgument TransArg
Douglas Gregor9d879762009-08-11 05:31:07 +00004042 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4043 if (TransArg.isNull())
4044 return SemaRef.ExprError();
4045
4046 TransArgs.push_back(TransArg);
4047 }
4048
4049 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4050 // compare template arguments (yet).
Mike Stump25cf7602009-09-09 15:08:12 +00004051
4052 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregor9d879762009-08-11 05:31:07 +00004053 // actually refers to a type, in which case the caller is actually dealing
4054 // with a functional cast. Give a reasonable error message!
4055 return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
4056 E->getLAngleLoc(),
4057 TransArgs.data(),
4058 TransArgs.size(),
4059 E->getRAngleLoc());
4060}
4061
4062template<typename Derived>
4063Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00004064TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004065 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4066
4067 QualType T = getDerived().TransformType(E->getType());
4068 if (T.isNull())
4069 return SemaRef.ExprError();
4070
4071 CXXConstructorDecl *Constructor
4072 = cast_or_null<CXXConstructorDecl>(
4073 getDerived().TransformDecl(E->getConstructor()));
4074 if (!Constructor)
4075 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004076
Douglas Gregor9d879762009-08-11 05:31:07 +00004077 bool ArgumentChanged = false;
4078 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump25cf7602009-09-09 15:08:12 +00004079 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregor9d879762009-08-11 05:31:07 +00004080 ArgEnd = E->arg_end();
4081 Arg != ArgEnd; ++Arg) {
4082 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4083 if (TransArg.isInvalid())
4084 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004085
Douglas Gregor9d879762009-08-11 05:31:07 +00004086 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4087 Args.push_back(TransArg.takeAs<Expr>());
4088 }
4089
4090 if (!getDerived().AlwaysRebuild() &&
4091 T == E->getType() &&
4092 Constructor == E->getConstructor() &&
4093 !ArgumentChanged)
4094 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00004095
Douglas Gregor9d879762009-08-11 05:31:07 +00004096 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4097 move_arg(Args));
4098}
Mike Stump25cf7602009-09-09 15:08:12 +00004099
Douglas Gregor9d879762009-08-11 05:31:07 +00004100/// \brief Transform a C++ temporary-binding expression.
4101///
Mike Stump25cf7602009-09-09 15:08:12 +00004102/// The transformation of a temporary-binding expression always attempts to
4103/// bind a new temporary variable to its subexpression, even if the
Douglas Gregor9d879762009-08-11 05:31:07 +00004104/// subexpression itself did not change, because the temporary variable itself
4105/// must be unique.
4106template<typename Derived>
4107Sema::OwningExprResult
4108TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4109 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4110 if (SubExpr.isInvalid())
4111 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004112
Douglas Gregor9d879762009-08-11 05:31:07 +00004113 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4114}
Mike Stump25cf7602009-09-09 15:08:12 +00004115
4116/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregor9d879762009-08-11 05:31:07 +00004117/// be destroyed after the expression is evaluated.
4118///
Mike Stump25cf7602009-09-09 15:08:12 +00004119/// The transformation of a full expression always attempts to build a new
4120/// CXXExprWithTemporaries expression, even if the
Douglas Gregor9d879762009-08-11 05:31:07 +00004121/// subexpression itself did not change, because it will need to capture the
4122/// the new temporary variables introduced in the subexpression.
4123template<typename Derived>
4124Sema::OwningExprResult
4125TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump25cf7602009-09-09 15:08:12 +00004126 CXXExprWithTemporaries *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004127 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4128 if (SubExpr.isInvalid())
4129 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004130
Douglas Gregor9d879762009-08-11 05:31:07 +00004131 return SemaRef.Owned(
4132 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4133 E->shouldDestroyTemporaries()));
4134}
Mike Stump25cf7602009-09-09 15:08:12 +00004135
Douglas Gregor9d879762009-08-11 05:31:07 +00004136template<typename Derived>
4137Sema::OwningExprResult
4138TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00004139 CXXTemporaryObjectExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004140 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4141 QualType T = getDerived().TransformType(E->getType());
4142 if (T.isNull())
4143 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004144
Douglas Gregor9d879762009-08-11 05:31:07 +00004145 CXXConstructorDecl *Constructor
4146 = cast_or_null<CXXConstructorDecl>(
4147 getDerived().TransformDecl(E->getConstructor()));
4148 if (!Constructor)
4149 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004150
Douglas Gregor9d879762009-08-11 05:31:07 +00004151 bool ArgumentChanged = false;
4152 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4153 Args.reserve(E->getNumArgs());
Mike Stump25cf7602009-09-09 15:08:12 +00004154 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregor9d879762009-08-11 05:31:07 +00004155 ArgEnd = E->arg_end();
4156 Arg != ArgEnd; ++Arg) {
4157 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4158 if (TransArg.isInvalid())
4159 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004160
Douglas Gregor9d879762009-08-11 05:31:07 +00004161 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4162 Args.push_back((Expr *)TransArg.release());
4163 }
Mike Stump25cf7602009-09-09 15:08:12 +00004164
Douglas Gregor9d879762009-08-11 05:31:07 +00004165 if (!getDerived().AlwaysRebuild() &&
4166 T == E->getType() &&
4167 Constructor == E->getConstructor() &&
4168 !ArgumentChanged)
4169 return SemaRef.Owned(E->Retain());
Mike Stump25cf7602009-09-09 15:08:12 +00004170
Douglas Gregor9d879762009-08-11 05:31:07 +00004171 // FIXME: Bogus location information
4172 SourceLocation CommaLoc;
4173 if (Args.size() > 1) {
4174 Expr *First = (Expr *)Args[0];
Mike Stump25cf7602009-09-09 15:08:12 +00004175 CommaLoc
Douglas Gregor9d879762009-08-11 05:31:07 +00004176 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4177 }
4178 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4179 T,
4180 /*FIXME:*/E->getTypeBeginLoc(),
4181 move_arg(Args),
4182 &CommaLoc,
4183 E->getLocEnd());
4184}
Mike Stump25cf7602009-09-09 15:08:12 +00004185
Douglas Gregor9d879762009-08-11 05:31:07 +00004186template<typename Derived>
4187Sema::OwningExprResult
4188TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00004189 CXXUnresolvedConstructExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004190 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4191 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4192 if (T.isNull())
4193 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004194
Douglas Gregor9d879762009-08-11 05:31:07 +00004195 bool ArgumentChanged = false;
4196 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4197 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4198 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4199 ArgEnd = E->arg_end();
4200 Arg != ArgEnd; ++Arg) {
4201 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4202 if (TransArg.isInvalid())
4203 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004204
Douglas Gregor9d879762009-08-11 05:31:07 +00004205 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4206 FakeCommaLocs.push_back(
4207 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4208 Args.push_back(TransArg.takeAs<Expr>());
4209 }
Mike Stump25cf7602009-09-09 15:08:12 +00004210
Douglas Gregor9d879762009-08-11 05:31:07 +00004211 if (!getDerived().AlwaysRebuild() &&
4212 T == E->getTypeAsWritten() &&
4213 !ArgumentChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00004214 return SemaRef.Owned(E->Retain());
4215
Douglas Gregor9d879762009-08-11 05:31:07 +00004216 // FIXME: we're faking the locations of the commas
4217 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4218 T,
4219 E->getLParenLoc(),
4220 move_arg(Args),
4221 FakeCommaLocs.data(),
4222 E->getRParenLoc());
4223}
Mike Stump25cf7602009-09-09 15:08:12 +00004224
Douglas Gregor9d879762009-08-11 05:31:07 +00004225template<typename Derived>
4226Sema::OwningExprResult
4227TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00004228 CXXUnresolvedMemberExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004229 // Transform the base of the expression.
4230 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4231 if (Base.isInvalid())
4232 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004233
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004234 Sema::TypeTy *ObjectType = 0;
Mike Stump25cf7602009-09-09 15:08:12 +00004235 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004236 E->getOperatorLoc(),
4237 E->isArrow()? tok::arrow : tok::period,
4238 ObjectType);
4239 if (Base.isInvalid())
4240 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004241
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004242 // FIXME: The first qualifier found might be a template type parameter,
4243 // in which case there is no transformed declaration to refer to (it might
4244 // refer to a built-in type!).
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004245 NamedDecl *FirstQualifierInScope
4246 = cast_or_null<NamedDecl>(
4247 getDerived().TransformDecl(E->getFirstQualifierFoundInScope()));
Mike Stump25cf7602009-09-09 15:08:12 +00004248
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004249 NestedNameSpecifier *Qualifier = 0;
4250 if (E->getQualifier()) {
4251 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4252 E->getQualifierRange(),
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004253 QualType::getFromOpaquePtr(ObjectType),
4254 FirstQualifierInScope);
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004255 if (!Qualifier)
4256 return SemaRef.ExprError();
4257 }
Mike Stump25cf7602009-09-09 15:08:12 +00004258
4259 DeclarationName Name
Douglas Gregora0651052009-09-03 22:13:48 +00004260 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc());
4261 if (!Name)
4262 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004263
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004264 if (!E->hasExplicitTemplateArgumentList()) {
4265 // This is a reference to a member without an explicitly-specified
4266 // template argument list. Optimize for this common case.
4267 if (!getDerived().AlwaysRebuild() &&
4268 Base.get() == E->getBase() &&
4269 Qualifier == E->getQualifier() &&
4270 Name == E->getMember() &&
4271 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump25cf7602009-09-09 15:08:12 +00004272 return SemaRef.Owned(E->Retain());
4273
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004274 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4275 E->isArrow(),
4276 E->getOperatorLoc(),
4277 Qualifier,
4278 E->getQualifierRange(),
4279 Name,
4280 E->getMemberLoc(),
4281 FirstQualifierInScope);
4282 }
4283
4284 // FIXME: This is an ugly hack, which forces the same template name to
4285 // be looked up multiple times. Yuck!
4286 // FIXME: This also won't work for, e.g., x->template operator+<int>
4287 TemplateName OrigTemplateName
4288 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump25cf7602009-09-09 15:08:12 +00004289
4290 TemplateName Template
4291 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004292 QualType::getFromOpaquePtr(ObjectType));
4293 if (Template.isNull())
4294 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004295
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004296 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4297 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump25cf7602009-09-09 15:08:12 +00004298 TemplateArgument TransArg
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004299 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4300 if (TransArg.isNull())
4301 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004302
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004303 TransArgs.push_back(TransArg);
4304 }
Mike Stump25cf7602009-09-09 15:08:12 +00004305
Douglas Gregor9d879762009-08-11 05:31:07 +00004306 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4307 E->isArrow(),
4308 E->getOperatorLoc(),
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004309 Qualifier,
4310 E->getQualifierRange(),
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004311 Template,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004312 E->getMemberLoc(),
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004313 FirstQualifierInScope,
4314 E->getLAngleLoc(),
4315 TransArgs.data(),
4316 TransArgs.size(),
4317 E->getRAngleLoc());
Douglas Gregor9d879762009-08-11 05:31:07 +00004318}
4319
4320template<typename Derived>
4321Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00004322TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4323 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004324}
4325
Mike Stump25cf7602009-09-09 15:08:12 +00004326template<typename Derived>
4327Sema::OwningExprResult
4328TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004329 // FIXME: poor source location
4330 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4331 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4332 if (EncodedType.isNull())
4333 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004334
Douglas Gregor9d879762009-08-11 05:31:07 +00004335 if (!getDerived().AlwaysRebuild() &&
4336 EncodedType == E->getEncodedType())
Mike Stump25cf7602009-09-09 15:08:12 +00004337 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004338
4339 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4340 EncodedType,
4341 E->getRParenLoc());
4342}
Mike Stump25cf7602009-09-09 15:08:12 +00004343
Douglas Gregor9d879762009-08-11 05:31:07 +00004344template<typename Derived>
4345Sema::OwningExprResult
Mike Stump25cf7602009-09-09 15:08:12 +00004346TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004347 // FIXME: Implement this!
4348 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004349 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004350}
4351
Mike Stump25cf7602009-09-09 15:08:12 +00004352template<typename Derived>
4353Sema::OwningExprResult
4354TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4355 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004356}
4357
Mike Stump25cf7602009-09-09 15:08:12 +00004358template<typename Derived>
4359Sema::OwningExprResult
4360TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4361 ObjCProtocolDecl *Protocol
Douglas Gregor9d879762009-08-11 05:31:07 +00004362 = cast_or_null<ObjCProtocolDecl>(
4363 getDerived().TransformDecl(E->getProtocol()));
4364 if (!Protocol)
4365 return SemaRef.ExprError();
4366
4367 if (!getDerived().AlwaysRebuild() &&
4368 Protocol == E->getProtocol())
Mike Stump25cf7602009-09-09 15:08:12 +00004369 return SemaRef.Owned(E->Retain());
4370
Douglas Gregor9d879762009-08-11 05:31:07 +00004371 return getDerived().RebuildObjCProtocolExpr(Protocol,
4372 E->getAtLoc(),
4373 /*FIXME:*/E->getAtLoc(),
4374 /*FIXME:*/E->getAtLoc(),
4375 E->getRParenLoc());
Mike Stump25cf7602009-09-09 15:08:12 +00004376
Douglas Gregor9d879762009-08-11 05:31:07 +00004377}
4378
Mike Stump25cf7602009-09-09 15:08:12 +00004379template<typename Derived>
4380Sema::OwningExprResult
4381TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004382 // FIXME: Implement this!
4383 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004384 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004385}
4386
Mike Stump25cf7602009-09-09 15:08:12 +00004387template<typename Derived>
4388Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00004389TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4390 // FIXME: Implement this!
4391 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004392 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004393}
4394
Mike Stump25cf7602009-09-09 15:08:12 +00004395template<typename Derived>
4396Sema::OwningExprResult
Fariborz Jahanian128cdc52009-08-20 17:02:02 +00004397TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump25cf7602009-09-09 15:08:12 +00004398 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004399 // FIXME: Implement this!
4400 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004401 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004402}
4403
Mike Stump25cf7602009-09-09 15:08:12 +00004404template<typename Derived>
4405Sema::OwningExprResult
4406TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004407 // FIXME: Implement this!
4408 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004409 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004410}
4411
Mike Stump25cf7602009-09-09 15:08:12 +00004412template<typename Derived>
4413Sema::OwningExprResult
4414TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004415 // FIXME: Implement this!
4416 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004417 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004418}
4419
Mike Stump25cf7602009-09-09 15:08:12 +00004420template<typename Derived>
4421Sema::OwningExprResult
4422TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004423 bool ArgumentChanged = false;
4424 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4425 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4426 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4427 if (SubExpr.isInvalid())
4428 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004429
Douglas Gregor9d879762009-08-11 05:31:07 +00004430 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4431 SubExprs.push_back(SubExpr.takeAs<Expr>());
4432 }
Mike Stump25cf7602009-09-09 15:08:12 +00004433
Douglas Gregor9d879762009-08-11 05:31:07 +00004434 if (!getDerived().AlwaysRebuild() &&
4435 !ArgumentChanged)
Mike Stump25cf7602009-09-09 15:08:12 +00004436 return SemaRef.Owned(E->Retain());
4437
Douglas Gregor9d879762009-08-11 05:31:07 +00004438 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4439 move_arg(SubExprs),
4440 E->getRParenLoc());
4441}
4442
Mike Stump25cf7602009-09-09 15:08:12 +00004443template<typename Derived>
4444Sema::OwningExprResult
4445TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004446 // FIXME: Implement this!
4447 assert(false && "Cannot transform block expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004448 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004449}
4450
Mike Stump25cf7602009-09-09 15:08:12 +00004451template<typename Derived>
4452Sema::OwningExprResult
4453TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004454 // FIXME: Implement this!
4455 assert(false && "Cannot transform block-related expressions yet");
Mike Stump25cf7602009-09-09 15:08:12 +00004456 return SemaRef.Owned(E->Retain());
Douglas Gregor9d879762009-08-11 05:31:07 +00004457}
Mike Stump25cf7602009-09-09 15:08:12 +00004458
Douglas Gregor9d879762009-08-11 05:31:07 +00004459//===----------------------------------------------------------------------===//
Douglas Gregor841324a2009-08-04 16:50:30 +00004460// Type reconstruction
4461//===----------------------------------------------------------------------===//
4462
Mike Stump25cf7602009-09-09 15:08:12 +00004463template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00004464QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
Mike Stump25cf7602009-09-09 15:08:12 +00004465 return SemaRef.BuildPointerType(PointeeType, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004466 getDerived().getBaseLocation(),
4467 getDerived().getBaseEntity());
4468}
4469
Mike Stump25cf7602009-09-09 15:08:12 +00004470template<typename Derived>
Douglas Gregor841324a2009-08-04 16:50:30 +00004471QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
Mike Stump25cf7602009-09-09 15:08:12 +00004472 return SemaRef.BuildBlockPointerType(PointeeType, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004473 getDerived().getBaseLocation(),
4474 getDerived().getBaseEntity());
4475}
4476
Mike Stump25cf7602009-09-09 15:08:12 +00004477template<typename Derived>
4478QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00004479TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
Mike Stump25cf7602009-09-09 15:08:12 +00004480 return SemaRef.BuildReferenceType(ReferentType, true, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004481 getDerived().getBaseLocation(),
4482 getDerived().getBaseEntity());
4483}
4484
4485template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004486QualType
4487TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
4488 return SemaRef.BuildReferenceType(ReferentType, false, 0,
4489 getDerived().getBaseLocation(),
4490 getDerived().getBaseEntity());
4491}
4492
4493template<typename Derived>
4494QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004495 QualType ClassType) {
Mike Stump25cf7602009-09-09 15:08:12 +00004496 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004497 getDerived().getBaseLocation(),
4498 getDerived().getBaseEntity());
4499}
4500
4501template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004502QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00004503TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4504 ArrayType::ArraySizeModifier SizeMod,
4505 const llvm::APInt *Size,
4506 Expr *SizeExpr,
4507 unsigned IndexTypeQuals,
4508 SourceRange BracketsRange) {
4509 if (SizeExpr || !Size)
4510 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4511 IndexTypeQuals, BracketsRange,
4512 getDerived().getBaseEntity());
Mike Stump25cf7602009-09-09 15:08:12 +00004513
4514 QualType Types[] = {
4515 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4516 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4517 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregor841324a2009-08-04 16:50:30 +00004518 };
4519 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4520 QualType SizeType;
4521 for (unsigned I = 0; I != NumTypes; ++I)
4522 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4523 SizeType = Types[I];
4524 break;
4525 }
Mike Stump25cf7602009-09-09 15:08:12 +00004526
Douglas Gregor841324a2009-08-04 16:50:30 +00004527 if (SizeType.isNull())
4528 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump25cf7602009-09-09 15:08:12 +00004529
Douglas Gregor841324a2009-08-04 16:50:30 +00004530 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump25cf7602009-09-09 15:08:12 +00004531 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregor841324a2009-08-04 16:50:30 +00004532 IndexTypeQuals, BracketsRange,
Mike Stump25cf7602009-09-09 15:08:12 +00004533 getDerived().getBaseEntity());
Douglas Gregor841324a2009-08-04 16:50:30 +00004534}
Mike Stump25cf7602009-09-09 15:08:12 +00004535
Douglas Gregor841324a2009-08-04 16:50:30 +00004536template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004537QualType
4538TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004539 ArrayType::ArraySizeModifier SizeMod,
4540 const llvm::APInt &Size,
4541 unsigned IndexTypeQuals) {
Mike Stump25cf7602009-09-09 15:08:12 +00004542 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004543 IndexTypeQuals, SourceRange());
4544}
4545
4546template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004547QualType
4548TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004549 ArrayType::ArraySizeModifier SizeMod,
4550 const llvm::APInt &Size,
4551 Expr *SizeExpr,
4552 unsigned IndexTypeQuals,
4553 SourceRange BracketsRange) {
Mike Stump25cf7602009-09-09 15:08:12 +00004554 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004555 IndexTypeQuals, BracketsRange);
4556}
4557
4558template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004559QualType
Douglas Gregor841324a2009-08-04 16:50:30 +00004560TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
Mike Stump25cf7602009-09-09 15:08:12 +00004561 QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004562 ArrayType::ArraySizeModifier SizeMod,
4563 const llvm::APInt &Size,
4564 unsigned IndexTypeQuals) {
Mike Stump25cf7602009-09-09 15:08:12 +00004565 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004566 IndexTypeQuals, SourceRange());
4567}
4568
4569template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004570QualType
4571TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004572 ArrayType::ArraySizeModifier SizeMod,
4573 unsigned IndexTypeQuals) {
Mike Stump25cf7602009-09-09 15:08:12 +00004574 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004575 IndexTypeQuals, SourceRange());
4576}
Mike Stump25cf7602009-09-09 15:08:12 +00004577
Douglas Gregor841324a2009-08-04 16:50:30 +00004578template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004579QualType
4580TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004581 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +00004582 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004583 unsigned IndexTypeQuals,
4584 SourceRange BracketsRange) {
Mike Stump25cf7602009-09-09 15:08:12 +00004585 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004586 SizeExpr.takeAs<Expr>(),
4587 IndexTypeQuals, BracketsRange);
4588}
4589
4590template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004591QualType
4592TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor841324a2009-08-04 16:50:30 +00004593 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +00004594 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004595 unsigned IndexTypeQuals,
4596 SourceRange BracketsRange) {
Mike Stump25cf7602009-09-09 15:08:12 +00004597 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor841324a2009-08-04 16:50:30 +00004598 SizeExpr.takeAs<Expr>(),
4599 IndexTypeQuals, BracketsRange);
4600}
4601
4602template<typename Derived>
4603QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4604 unsigned NumElements) {
4605 // FIXME: semantic checking!
4606 return SemaRef.Context.getVectorType(ElementType, NumElements);
4607}
Mike Stump25cf7602009-09-09 15:08:12 +00004608
Douglas Gregor841324a2009-08-04 16:50:30 +00004609template<typename Derived>
4610QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4611 unsigned NumElements,
4612 SourceLocation AttributeLoc) {
4613 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4614 NumElements, true);
4615 IntegerLiteral *VectorSize
Mike Stump25cf7602009-09-09 15:08:12 +00004616 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregor841324a2009-08-04 16:50:30 +00004617 AttributeLoc);
4618 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4619 AttributeLoc);
4620}
Mike Stump25cf7602009-09-09 15:08:12 +00004621
Douglas Gregor841324a2009-08-04 16:50:30 +00004622template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004623QualType
4624TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregor9d879762009-08-11 05:31:07 +00004625 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004626 SourceLocation AttributeLoc) {
4627 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4628}
Mike Stump25cf7602009-09-09 15:08:12 +00004629
Douglas Gregor841324a2009-08-04 16:50:30 +00004630template<typename Derived>
4631QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump25cf7602009-09-09 15:08:12 +00004632 QualType *ParamTypes,
Douglas Gregor841324a2009-08-04 16:50:30 +00004633 unsigned NumParamTypes,
Mike Stump25cf7602009-09-09 15:08:12 +00004634 bool Variadic,
Douglas Gregor841324a2009-08-04 16:50:30 +00004635 unsigned Quals) {
Mike Stump25cf7602009-09-09 15:08:12 +00004636 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregor841324a2009-08-04 16:50:30 +00004637 Quals,
4638 getDerived().getBaseLocation(),
4639 getDerived().getBaseEntity());
4640}
Mike Stump25cf7602009-09-09 15:08:12 +00004641
Douglas Gregor841324a2009-08-04 16:50:30 +00004642template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00004643QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor841324a2009-08-04 16:50:30 +00004644 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4645}
4646
4647template<typename Derived>
4648QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4649 return SemaRef.Context.getTypeOfType(Underlying);
4650}
4651
4652template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00004653QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor841324a2009-08-04 16:50:30 +00004654 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4655}
4656
4657template<typename Derived>
4658QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4659 TemplateName Template,
4660 const TemplateArgument *Args,
4661 unsigned NumArgs) {
4662 // FIXME: Missing source locations for the template name, <, >.
4663 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
Mike Stump25cf7602009-09-09 15:08:12 +00004664 SourceLocation(), Args, NumArgs,
4665 SourceLocation());
Douglas Gregor841324a2009-08-04 16:50:30 +00004666}
Mike Stump25cf7602009-09-09 15:08:12 +00004667
Douglas Gregor12431cb2009-08-06 05:28:30 +00004668template<typename Derived>
4669NestedNameSpecifier *
4670TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4671 SourceRange Range,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004672 IdentifierInfo &II,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004673 QualType ObjectType,
4674 NamedDecl *FirstQualifierInScope) {
Douglas Gregor12431cb2009-08-06 05:28:30 +00004675 CXXScopeSpec SS;
4676 // FIXME: The source location information is all wrong.
4677 SS.setRange(Range);
4678 SS.setScopeRep(Prefix);
4679 return static_cast<NestedNameSpecifier *>(
Mike Stump25cf7602009-09-09 15:08:12 +00004680 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregorc03d3302009-08-25 22:51:20 +00004681 Range.getEnd(), II,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004682 ObjectType,
4683 FirstQualifierInScope,
Douglas Gregorc03d3302009-08-25 22:51:20 +00004684 false));
Douglas Gregor12431cb2009-08-06 05:28:30 +00004685}
4686
4687template<typename Derived>
4688NestedNameSpecifier *
4689TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4690 SourceRange Range,
4691 NamespaceDecl *NS) {
4692 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
4693}
4694
4695template<typename Derived>
4696NestedNameSpecifier *
4697TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4698 SourceRange Range,
4699 bool TemplateKW,
4700 QualType T) {
4701 if (T->isDependentType() || T->isRecordType() ||
4702 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
4703 assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
4704 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
4705 T.getTypePtr());
4706 }
Mike Stump25cf7602009-09-09 15:08:12 +00004707
Douglas Gregor12431cb2009-08-06 05:28:30 +00004708 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
4709 return 0;
4710}
Mike Stump25cf7602009-09-09 15:08:12 +00004711
Douglas Gregor214d0462009-08-06 06:41:21 +00004712template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004713TemplateName
Douglas Gregor214d0462009-08-06 06:41:21 +00004714TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4715 bool TemplateKW,
4716 TemplateDecl *Template) {
Mike Stump25cf7602009-09-09 15:08:12 +00004717 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor214d0462009-08-06 06:41:21 +00004718 Template);
4719}
4720
4721template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004722TemplateName
Douglas Gregor214d0462009-08-06 06:41:21 +00004723TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4724 bool TemplateKW,
4725 OverloadedFunctionDecl *Ovl) {
4726 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
4727}
4728
4729template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004730TemplateName
Douglas Gregor214d0462009-08-06 06:41:21 +00004731TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004732 const IdentifierInfo &II,
4733 QualType ObjectType) {
Douglas Gregor214d0462009-08-06 06:41:21 +00004734 CXXScopeSpec SS;
4735 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump25cf7602009-09-09 15:08:12 +00004736 SS.setScopeRep(Qualifier);
Douglas Gregorcc00fc02009-09-09 00:23:06 +00004737 return getSema().ActOnDependentTemplateName(
4738 /*FIXME:*/getDerived().getBaseLocation(),
4739 II,
4740 /*FIXME:*/getDerived().getBaseLocation(),
4741 SS,
4742 ObjectType.getAsOpaquePtr())
4743 .template getAsVal<TemplateName>();
Douglas Gregor214d0462009-08-06 06:41:21 +00004744}
Mike Stump25cf7602009-09-09 15:08:12 +00004745
Douglas Gregor9d879762009-08-11 05:31:07 +00004746template<typename Derived>
Mike Stump25cf7602009-09-09 15:08:12 +00004747Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00004748TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
4749 SourceLocation OpLoc,
4750 ExprArg Callee,
4751 ExprArg First,
4752 ExprArg Second) {
4753 Expr *FirstExpr = (Expr *)First.get();
4754 Expr *SecondExpr = (Expr *)Second.get();
4755 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump25cf7602009-09-09 15:08:12 +00004756
Douglas Gregor9d879762009-08-11 05:31:07 +00004757 // Determine whether this should be a builtin operation.
4758 if (SecondExpr == 0 || isPostIncDec) {
4759 if (!FirstExpr->getType()->isOverloadableType()) {
4760 // The argument is not of overloadable type, so try to create a
4761 // built-in unary operation.
Mike Stump25cf7602009-09-09 15:08:12 +00004762 UnaryOperator::Opcode Opc
Douglas Gregor9d879762009-08-11 05:31:07 +00004763 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump25cf7602009-09-09 15:08:12 +00004764
Douglas Gregor9d879762009-08-11 05:31:07 +00004765 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
4766 }
4767 } else {
Mike Stump25cf7602009-09-09 15:08:12 +00004768 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregor9d879762009-08-11 05:31:07 +00004769 !SecondExpr->getType()->isOverloadableType()) {
4770 // Neither of the arguments is an overloadable type, so try to
4771 // create a built-in binary operation.
4772 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump25cf7602009-09-09 15:08:12 +00004773 OwningExprResult Result
Douglas Gregor9d879762009-08-11 05:31:07 +00004774 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
4775 if (Result.isInvalid())
4776 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004777
Douglas Gregor9d879762009-08-11 05:31:07 +00004778 First.release();
4779 Second.release();
4780 return move(Result);
4781 }
4782 }
Mike Stump25cf7602009-09-09 15:08:12 +00004783
4784 // Compute the transformed set of functions (and function templates) to be
Douglas Gregor9d879762009-08-11 05:31:07 +00004785 // used during overload resolution.
4786 Sema::FunctionSet Functions;
Mike Stump25cf7602009-09-09 15:08:12 +00004787
4788 DeclRefExpr *DRE
Douglas Gregor23026c82009-09-01 16:58:52 +00004789 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Mike Stump25cf7602009-09-09 15:08:12 +00004790
Douglas Gregor9d879762009-08-11 05:31:07 +00004791 // FIXME: Do we have to check
4792 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor23026c82009-09-01 16:58:52 +00004793 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregor9d879762009-08-11 05:31:07 +00004794 Functions.insert(*F);
Mike Stump25cf7602009-09-09 15:08:12 +00004795
Douglas Gregor9d879762009-08-11 05:31:07 +00004796 // Add any functions found via argument-dependent lookup.
4797 Expr *Args[2] = { FirstExpr, SecondExpr };
4798 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump25cf7602009-09-09 15:08:12 +00004799 DeclarationName OpName
Douglas Gregor9d879762009-08-11 05:31:07 +00004800 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
4801 SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
Mike Stump25cf7602009-09-09 15:08:12 +00004802
Douglas Gregor9d879762009-08-11 05:31:07 +00004803 // Create the overloaded operator invocation for unary operators.
4804 if (NumArgs == 1 || isPostIncDec) {
Mike Stump25cf7602009-09-09 15:08:12 +00004805 UnaryOperator::Opcode Opc
Douglas Gregor9d879762009-08-11 05:31:07 +00004806 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4807 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
4808 }
Mike Stump25cf7602009-09-09 15:08:12 +00004809
Douglas Gregor9d879762009-08-11 05:31:07 +00004810 // Create the overloaded operator invocation for binary operators.
Mike Stump25cf7602009-09-09 15:08:12 +00004811 BinaryOperator::Opcode Opc =
Douglas Gregor9d879762009-08-11 05:31:07 +00004812 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump25cf7602009-09-09 15:08:12 +00004813 OwningExprResult Result
Douglas Gregor9d879762009-08-11 05:31:07 +00004814 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
4815 if (Result.isInvalid())
4816 return SemaRef.ExprError();
Mike Stump25cf7602009-09-09 15:08:12 +00004817
Douglas Gregor9d879762009-08-11 05:31:07 +00004818 First.release();
4819 Second.release();
Mike Stump25cf7602009-09-09 15:08:12 +00004820 return move(Result);
Douglas Gregor9d879762009-08-11 05:31:07 +00004821}
Mike Stump25cf7602009-09-09 15:08:12 +00004822
Douglas Gregor841324a2009-08-04 16:50:30 +00004823} // end namespace clang
4824
4825#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H