blob: cb7b69fc95d2d338581a1f0668eef0c0dabb405f [file] [log] [blame]
John McCall550e0c22009-10-21 00:40:46 +00001//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
Douglas Gregord6ff3322009-08-04 16:50:30 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements a semantic tree transformation that takes a given
10// AST and rebuilds it, possibly transforming some nodes in the process.
11//
12//===----------------------------------------------------------------------===/
13#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_SEMA_TREETRANSFORM_H
15
16#include "Sema.h"
Douglas Gregor1135c352009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregor2b6ca462009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor766b0bb2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregora16548e2009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregorebe10102009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
John McCall550e0c22009-10-21 00:40:46 +000025#include "clang/AST/TypeLocBuilder.h"
Douglas Gregora16548e2009-08-11 05:31:07 +000026#include "clang/Parse/Ownership.h"
27#include "clang/Parse/Designator.h"
28#include "clang/Lex/Preprocessor.h"
John McCall550e0c22009-10-21 00:40:46 +000029#include "llvm/Support/ErrorHandling.h"
Douglas Gregord6ff3322009-08-04 16:50:30 +000030#include <algorithm>
31
32namespace clang {
Mike Stump11289f42009-09-09 15:08:12 +000033
Douglas Gregord6ff3322009-08-04 16:50:30 +000034/// \brief A semantic tree transformation that allows one to transform one
35/// abstract syntax tree into another.
36///
Mike Stump11289f42009-09-09 15:08:12 +000037/// A new tree transformation is defined by creating a new subclass \c X of
38/// \c TreeTransform<X> and then overriding certain operations to provide
39/// behavior specific to that transformation. For example, template
Douglas Gregord6ff3322009-08-04 16:50:30 +000040/// instantiation is implemented as a tree transformation where the
41/// transformation of TemplateTypeParmType nodes involves substituting the
42/// template arguments for their corresponding template parameters; a similar
43/// transformation is performed for non-type template parameters and
44/// template template parameters.
45///
46/// This tree-transformation template uses static polymorphism to allow
Mike Stump11289f42009-09-09 15:08:12 +000047/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregord6ff3322009-08-04 16:50:30 +000048/// override any of the transformation or rebuild operators by providing an
49/// operation with the same signature as the default implementation. The
50/// overridding function should not be virtual.
51///
52/// Semantic tree transformations are split into two stages, either of which
53/// can be replaced by a subclass. The "transform" step transforms an AST node
54/// or the parts of an AST node using the various transformation functions,
55/// then passes the pieces on to the "rebuild" step, which constructs a new AST
56/// node of the appropriate kind from the pieces. The default transformation
57/// routines recursively transform the operands to composite AST nodes (e.g.,
58/// the pointee type of a PointerType node) and, if any of those operand nodes
59/// were changed by the transformation, invokes the rebuild operation to create
60/// a new AST node.
61///
Mike Stump11289f42009-09-09 15:08:12 +000062/// Subclasses can customize the transformation at various levels. The
Douglas Gregore922c772009-08-04 22:27:00 +000063/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregord6ff3322009-08-04 16:50:30 +000064/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
65/// TransformTemplateName(), or TransformTemplateArgument() with entirely
66/// new implementations.
67///
68/// For more fine-grained transformations, subclasses can replace any of the
69/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
Douglas Gregorebe10102009-08-20 07:17:43 +000070/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregord6ff3322009-08-04 16:50:30 +000071/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump11289f42009-09-09 15:08:12 +000072/// to substitute template arguments for their corresponding template
Douglas Gregord6ff3322009-08-04 16:50:30 +000073/// parameters. Additionally, subclasses can override the \c RebuildXXX
74/// functions to control how AST nodes are rebuilt when their operands change.
75/// By default, \c TreeTransform will invoke semantic analysis to rebuild
76/// AST nodes. However, certain other tree transformations (e.g, cloning) may
77/// be able to use more efficient rebuild steps.
78///
79/// There are a handful of other functions that can be overridden, allowing one
Mike Stump11289f42009-09-09 15:08:12 +000080/// to avoid traversing nodes that don't need any transformation
Douglas Gregord6ff3322009-08-04 16:50:30 +000081/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
82/// operands have not changed (\c AlwaysRebuild()), and customize the
83/// default locations and entity names used for type-checking
84/// (\c getBaseLocation(), \c getBaseEntity()).
Douglas Gregord6ff3322009-08-04 16:50:30 +000085template<typename Derived>
86class TreeTransform {
87protected:
88 Sema &SemaRef;
Mike Stump11289f42009-09-09 15:08:12 +000089
90public:
Douglas Gregora16548e2009-08-11 05:31:07 +000091 typedef Sema::OwningStmtResult OwningStmtResult;
92 typedef Sema::OwningExprResult OwningExprResult;
93 typedef Sema::StmtArg StmtArg;
94 typedef Sema::ExprArg ExprArg;
95 typedef Sema::MultiExprArg MultiExprArg;
Douglas Gregorebe10102009-08-20 07:17:43 +000096 typedef Sema::MultiStmtArg MultiStmtArg;
Mike Stump11289f42009-09-09 15:08:12 +000097
Douglas Gregord6ff3322009-08-04 16:50:30 +000098 /// \brief Initializes a new tree transformer.
99 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump11289f42009-09-09 15:08:12 +0000100
Douglas Gregord6ff3322009-08-04 16:50:30 +0000101 /// \brief Retrieves a reference to the derived class.
102 Derived &getDerived() { return static_cast<Derived&>(*this); }
103
104 /// \brief Retrieves a reference to the derived class.
Mike Stump11289f42009-09-09 15:08:12 +0000105 const Derived &getDerived() const {
106 return static_cast<const Derived&>(*this);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000107 }
108
109 /// \brief Retrieves a reference to the semantic analysis object used for
110 /// this tree transform.
111 Sema &getSema() const { return SemaRef; }
Mike Stump11289f42009-09-09 15:08:12 +0000112
Douglas Gregord6ff3322009-08-04 16:50:30 +0000113 /// \brief Whether the transformation should always rebuild AST nodes, even
114 /// if none of the children have changed.
115 ///
116 /// Subclasses may override this function to specify when the transformation
117 /// should rebuild all AST nodes.
118 bool AlwaysRebuild() { return false; }
Mike Stump11289f42009-09-09 15:08:12 +0000119
Douglas Gregord6ff3322009-08-04 16:50:30 +0000120 /// \brief Returns the location of the entity being transformed, if that
121 /// information was not available elsewhere in the AST.
122 ///
Mike Stump11289f42009-09-09 15:08:12 +0000123 /// By default, returns no source-location information. Subclasses can
Douglas Gregord6ff3322009-08-04 16:50:30 +0000124 /// provide an alternative implementation that provides better location
125 /// information.
126 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump11289f42009-09-09 15:08:12 +0000127
Douglas Gregord6ff3322009-08-04 16:50:30 +0000128 /// \brief Returns the name of the entity being transformed, if that
129 /// information was not available elsewhere in the AST.
130 ///
131 /// By default, returns an empty name. Subclasses can provide an alternative
132 /// implementation with a more precise name.
133 DeclarationName getBaseEntity() { return DeclarationName(); }
134
Douglas Gregora16548e2009-08-11 05:31:07 +0000135 /// \brief Sets the "base" location and entity when that
136 /// information is known based on another transformation.
137 ///
138 /// By default, the source location and entity are ignored. Subclasses can
139 /// override this function to provide a customized implementation.
140 void setBase(SourceLocation Loc, DeclarationName Entity) { }
Mike Stump11289f42009-09-09 15:08:12 +0000141
Douglas Gregora16548e2009-08-11 05:31:07 +0000142 /// \brief RAII object that temporarily sets the base location and entity
143 /// used for reporting diagnostics in types.
144 class TemporaryBase {
145 TreeTransform &Self;
146 SourceLocation OldLocation;
147 DeclarationName OldEntity;
Mike Stump11289f42009-09-09 15:08:12 +0000148
Douglas Gregora16548e2009-08-11 05:31:07 +0000149 public:
150 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump11289f42009-09-09 15:08:12 +0000151 DeclarationName Entity) : Self(Self) {
Douglas Gregora16548e2009-08-11 05:31:07 +0000152 OldLocation = Self.getDerived().getBaseLocation();
153 OldEntity = Self.getDerived().getBaseEntity();
154 Self.getDerived().setBase(Location, Entity);
155 }
Mike Stump11289f42009-09-09 15:08:12 +0000156
Douglas Gregora16548e2009-08-11 05:31:07 +0000157 ~TemporaryBase() {
158 Self.getDerived().setBase(OldLocation, OldEntity);
159 }
160 };
Mike Stump11289f42009-09-09 15:08:12 +0000161
162 /// \brief Determine whether the given type \p T has already been
Douglas Gregord6ff3322009-08-04 16:50:30 +0000163 /// transformed.
164 ///
165 /// Subclasses can provide an alternative implementation of this routine
Mike Stump11289f42009-09-09 15:08:12 +0000166 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregord6ff3322009-08-04 16:50:30 +0000167 /// not change. For example, template instantiation need not traverse
168 /// non-dependent types.
169 bool AlreadyTransformed(QualType T) {
170 return T.isNull();
171 }
172
173 /// \brief Transforms the given type into another type.
174 ///
John McCall550e0c22009-10-21 00:40:46 +0000175 /// By default, this routine transforms a type by creating a
176 /// DeclaratorInfo for it and delegating to the appropriate
177 /// function. This is expensive, but we don't mind, because
178 /// this method is deprecated anyway; all users should be
179 /// switched to storing DeclaratorInfos.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000180 ///
181 /// \returns the transformed type.
182 QualType TransformType(QualType T);
Mike Stump11289f42009-09-09 15:08:12 +0000183
John McCall550e0c22009-10-21 00:40:46 +0000184 /// \brief Transforms the given type-with-location into a new
185 /// type-with-location.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000186 ///
John McCall550e0c22009-10-21 00:40:46 +0000187 /// By default, this routine transforms a type by delegating to the
188 /// appropriate TransformXXXType to build a new type. Subclasses
189 /// may override this function (to take over all type
190 /// transformations) or some set of the TransformXXXType functions
191 /// to alter the transformation.
192 DeclaratorInfo *TransformType(DeclaratorInfo *DI);
193
194 /// \brief Transform the given type-with-location into a new
195 /// type, collecting location information in the given builder
196 /// as necessary.
197 ///
198 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
Mike Stump11289f42009-09-09 15:08:12 +0000199
Douglas Gregor766b0bb2009-08-06 22:17:10 +0000200 /// \brief Transform the given statement.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000201 ///
Mike Stump11289f42009-09-09 15:08:12 +0000202 /// By default, this routine transforms a statement by delegating to the
Douglas Gregorebe10102009-08-20 07:17:43 +0000203 /// appropriate TransformXXXStmt function to transform a specific kind of
204 /// statement or the TransformExpr() function to transform an expression.
205 /// Subclasses may override this function to transform statements using some
206 /// other mechanism.
207 ///
208 /// \returns the transformed statement.
Douglas Gregora16548e2009-08-11 05:31:07 +0000209 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump11289f42009-09-09 15:08:12 +0000210
Douglas Gregor766b0bb2009-08-06 22:17:10 +0000211 /// \brief Transform the given expression.
212 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000213 /// By default, this routine transforms an expression by delegating to the
214 /// appropriate TransformXXXExpr function to build a new expression.
215 /// Subclasses may override this function to transform expressions using some
216 /// other mechanism.
217 ///
218 /// \returns the transformed expression.
219 OwningExprResult TransformExpr(Expr *E) {
220 return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
221 }
222
223 /// \brief Transform the given expression.
224 ///
225 /// By default, this routine transforms an expression by delegating to the
226 /// appropriate TransformXXXExpr function to build a new expression.
227 /// Subclasses may override this function to transform expressions using some
228 /// other mechanism.
229 ///
230 /// \returns the transformed expression.
231 OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
Mike Stump11289f42009-09-09 15:08:12 +0000232
Douglas Gregord6ff3322009-08-04 16:50:30 +0000233 /// \brief Transform the given declaration, which is referenced from a type
234 /// or expression.
235 ///
Douglas Gregor1135c352009-08-06 05:28:30 +0000236 /// By default, acts as the identity function on declarations. Subclasses
237 /// may override this function to provide alternate behavior.
238 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregorebe10102009-08-20 07:17:43 +0000239
240 /// \brief Transform the definition of the given declaration.
241 ///
Mike Stump11289f42009-09-09 15:08:12 +0000242 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregorebe10102009-08-20 07:17:43 +0000243 /// Subclasses may override this function to provide alternate behavior.
244 Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
Mike Stump11289f42009-09-09 15:08:12 +0000245
Douglas Gregora5cb6da2009-10-20 05:58:46 +0000246 /// \brief Transform the given declaration, which was the first part of a
247 /// nested-name-specifier in a member access expression.
248 ///
249 /// This specific declaration transformation only applies to the first
250 /// identifier in a nested-name-specifier of a member access expression, e.g.,
251 /// the \c T in \c x->T::member
252 ///
253 /// By default, invokes TransformDecl() to transform the declaration.
254 /// Subclasses may override this function to provide alternate behavior.
255 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
256 return cast_or_null<NamedDecl>(getDerived().TransformDecl(D));
257 }
258
Douglas Gregord6ff3322009-08-04 16:50:30 +0000259 /// \brief Transform the given nested-name-specifier.
260 ///
Mike Stump11289f42009-09-09 15:08:12 +0000261 /// By default, transforms all of the types and declarations within the
Douglas Gregor1135c352009-08-06 05:28:30 +0000262 /// nested-name-specifier. Subclasses may override this function to provide
263 /// alternate behavior.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000264 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000265 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000266 QualType ObjectType = QualType(),
267 NamedDecl *FirstQualifierInScope = 0);
Mike Stump11289f42009-09-09 15:08:12 +0000268
Douglas Gregorf816bd72009-09-03 22:13:48 +0000269 /// \brief Transform the given declaration name.
270 ///
271 /// By default, transforms the types of conversion function, constructor,
272 /// and destructor names and then (if needed) rebuilds the declaration name.
273 /// Identifiers and selectors are returned unmodified. Sublcasses may
274 /// override this function to provide alternate behavior.
275 DeclarationName TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +0000276 SourceLocation Loc,
277 QualType ObjectType = QualType());
Mike Stump11289f42009-09-09 15:08:12 +0000278
Douglas Gregord6ff3322009-08-04 16:50:30 +0000279 /// \brief Transform the given template name.
Mike Stump11289f42009-09-09 15:08:12 +0000280 ///
Douglas Gregor71dc5092009-08-06 06:41:21 +0000281 /// By default, transforms the template name by transforming the declarations
Mike Stump11289f42009-09-09 15:08:12 +0000282 /// and nested-name-specifiers that occur within the template name.
Douglas Gregor71dc5092009-08-06 06:41:21 +0000283 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor308047d2009-09-09 00:23:06 +0000284 TemplateName TransformTemplateName(TemplateName Name,
285 QualType ObjectType = QualType());
Mike Stump11289f42009-09-09 15:08:12 +0000286
Douglas Gregord6ff3322009-08-04 16:50:30 +0000287 /// \brief Transform the given template argument.
288 ///
Mike Stump11289f42009-09-09 15:08:12 +0000289 /// By default, this operation transforms the type, expression, or
290 /// declaration stored within the template argument and constructs a
Douglas Gregore922c772009-08-04 22:27:00 +0000291 /// new template argument from the transformed result. Subclasses may
292 /// override this function to provide alternate behavior.
John McCall0ad16662009-10-29 08:12:44 +0000293 ///
294 /// Returns true if there was an error.
295 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
296 TemplateArgumentLoc &Output);
297
298 /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
299 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
300 TemplateArgumentLoc &ArgLoc);
301
302 /// \brief Fakes up a DeclaratorInfo for a type.
303 DeclaratorInfo *InventDeclaratorInfo(QualType T) {
304 return SemaRef.Context.getTrivialDeclaratorInfo(T,
305 getDerived().getBaseLocation());
306 }
Mike Stump11289f42009-09-09 15:08:12 +0000307
John McCall550e0c22009-10-21 00:40:46 +0000308#define ABSTRACT_TYPELOC(CLASS, PARENT)
309#define TYPELOC(CLASS, PARENT) \
310 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
311#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +0000312
Douglas Gregorc59e5612009-10-19 22:04:39 +0000313 QualType
314 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
315 QualType ObjectType);
John McCall0ad16662009-10-29 08:12:44 +0000316
317 QualType
318 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
319 TemplateSpecializationTypeLoc TL,
320 QualType ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +0000321
Douglas Gregorebe10102009-08-20 07:17:43 +0000322 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump11289f42009-09-09 15:08:12 +0000323
Douglas Gregorebe10102009-08-20 07:17:43 +0000324#define STMT(Node, Parent) \
325 OwningStmtResult Transform##Node(Node *S);
Douglas Gregora16548e2009-08-11 05:31:07 +0000326#define EXPR(Node, Parent) \
327 OwningExprResult Transform##Node(Node *E);
328#define ABSTRACT_EXPR(Node, Parent)
329#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +0000330
Douglas Gregord6ff3322009-08-04 16:50:30 +0000331 /// \brief Build a new pointer type given its pointee type.
332 ///
333 /// By default, performs semantic analysis when building the pointer type.
334 /// Subclasses may override this routine to provide different behavior.
335 QualType RebuildPointerType(QualType PointeeType);
336
337 /// \brief Build a new block pointer type given its pointee type.
338 ///
Mike Stump11289f42009-09-09 15:08:12 +0000339 /// By default, performs semantic analysis when building the block pointer
Douglas Gregord6ff3322009-08-04 16:50:30 +0000340 /// type. Subclasses may override this routine to provide different behavior.
341 QualType RebuildBlockPointerType(QualType PointeeType);
342
343 /// \brief Build a new lvalue reference type given the type it references.
344 ///
345 /// By default, performs semantic analysis when building the lvalue reference
346 /// type. Subclasses may override this routine to provide different behavior.
347 QualType RebuildLValueReferenceType(QualType ReferentType);
348
349 /// \brief Build a new rvalue reference type given the type it references.
350 ///
351 /// By default, performs semantic analysis when building the rvalue reference
352 /// type. Subclasses may override this routine to provide different behavior.
353 QualType RebuildRValueReferenceType(QualType ReferentType);
Mike Stump11289f42009-09-09 15:08:12 +0000354
Douglas Gregord6ff3322009-08-04 16:50:30 +0000355 /// \brief Build a new member pointer type given the pointee type and the
356 /// class type it refers into.
357 ///
358 /// By default, performs semantic analysis when building the member pointer
359 /// type. Subclasses may override this routine to provide different behavior.
360 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
Mike Stump11289f42009-09-09 15:08:12 +0000361
John McCall550e0c22009-10-21 00:40:46 +0000362 /// \brief Build a new Objective C object pointer type.
363 QualType RebuildObjCObjectPointerType(QualType PointeeType);
364
Douglas Gregord6ff3322009-08-04 16:50:30 +0000365 /// \brief Build a new array type given the element type, size
366 /// modifier, size of the array (if known), size expression, and index type
367 /// qualifiers.
368 ///
369 /// By default, performs semantic analysis when building the array type.
370 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000371 /// Also by default, all of the other Rebuild*Array
Douglas Gregord6ff3322009-08-04 16:50:30 +0000372 QualType RebuildArrayType(QualType ElementType,
373 ArrayType::ArraySizeModifier SizeMod,
374 const llvm::APInt *Size,
375 Expr *SizeExpr,
376 unsigned IndexTypeQuals,
377 SourceRange BracketsRange);
Mike Stump11289f42009-09-09 15:08:12 +0000378
Douglas Gregord6ff3322009-08-04 16:50:30 +0000379 /// \brief Build a new constant array type given the element type, size
380 /// modifier, (known) size of the array, and index type qualifiers.
381 ///
382 /// By default, performs semantic analysis when building the array type.
383 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000384 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000385 ArrayType::ArraySizeModifier SizeMod,
386 const llvm::APInt &Size,
387 unsigned IndexTypeQuals);
388
Douglas Gregord6ff3322009-08-04 16:50:30 +0000389 /// \brief Build a new incomplete array type given the element type, size
390 /// modifier, and index type qualifiers.
391 ///
392 /// By default, performs semantic analysis when building the array type.
393 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000394 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000395 ArrayType::ArraySizeModifier SizeMod,
396 unsigned IndexTypeQuals);
397
Mike Stump11289f42009-09-09 15:08:12 +0000398 /// \brief Build a new variable-length array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000399 /// size modifier, size expression, and index type qualifiers.
400 ///
401 /// By default, performs semantic analysis when building the array type.
402 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000403 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000404 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000405 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000406 unsigned IndexTypeQuals,
407 SourceRange BracketsRange);
408
Mike Stump11289f42009-09-09 15:08:12 +0000409 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000410 /// size modifier, size expression, and index type qualifiers.
411 ///
412 /// By default, performs semantic analysis when building the array type.
413 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000414 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000415 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000416 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000417 unsigned IndexTypeQuals,
418 SourceRange BracketsRange);
419
420 /// \brief Build a new vector type given the element type and
421 /// number of elements.
422 ///
423 /// By default, performs semantic analysis when building the vector type.
424 /// Subclasses may override this routine to provide different behavior.
425 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump11289f42009-09-09 15:08:12 +0000426
Douglas Gregord6ff3322009-08-04 16:50:30 +0000427 /// \brief Build a new extended vector type given the element type and
428 /// number of elements.
429 ///
430 /// By default, performs semantic analysis when building the vector type.
431 /// Subclasses may override this routine to provide different behavior.
432 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
433 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000434
435 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregord6ff3322009-08-04 16:50:30 +0000436 /// given the element type and number of elements.
437 ///
438 /// By default, performs semantic analysis when building the vector type.
439 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000440 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +0000441 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000442 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000443
Douglas Gregord6ff3322009-08-04 16:50:30 +0000444 /// \brief Build a new function type.
445 ///
446 /// By default, performs semantic analysis when building the function type.
447 /// Subclasses may override this routine to provide different behavior.
448 QualType RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +0000449 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000450 unsigned NumParamTypes,
451 bool Variadic, unsigned Quals);
Mike Stump11289f42009-09-09 15:08:12 +0000452
John McCall550e0c22009-10-21 00:40:46 +0000453 /// \brief Build a new unprototyped function type.
454 QualType RebuildFunctionNoProtoType(QualType ResultType);
455
Douglas Gregord6ff3322009-08-04 16:50:30 +0000456 /// \brief Build a new typedef type.
457 QualType RebuildTypedefType(TypedefDecl *Typedef) {
458 return SemaRef.Context.getTypeDeclType(Typedef);
459 }
460
461 /// \brief Build a new class/struct/union type.
462 QualType RebuildRecordType(RecordDecl *Record) {
463 return SemaRef.Context.getTypeDeclType(Record);
464 }
465
466 /// \brief Build a new Enum type.
467 QualType RebuildEnumType(EnumDecl *Enum) {
468 return SemaRef.Context.getTypeDeclType(Enum);
469 }
John McCallfcc33b02009-09-05 00:15:47 +0000470
471 /// \brief Build a new elaborated type.
472 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
473 return SemaRef.Context.getElaboratedType(T, Tag);
474 }
Mike Stump11289f42009-09-09 15:08:12 +0000475
476 /// \brief Build a new typeof(expr) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000477 ///
478 /// By default, performs semantic analysis when building the typeof type.
479 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000480 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000481
Mike Stump11289f42009-09-09 15:08:12 +0000482 /// \brief Build a new typeof(type) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000483 ///
484 /// By default, builds a new TypeOfType with the given underlying type.
485 QualType RebuildTypeOfType(QualType Underlying);
486
Mike Stump11289f42009-09-09 15:08:12 +0000487 /// \brief Build a new C++0x decltype type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000488 ///
489 /// By default, performs semantic analysis when building the decltype type.
490 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000491 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump11289f42009-09-09 15:08:12 +0000492
Douglas Gregord6ff3322009-08-04 16:50:30 +0000493 /// \brief Build a new template specialization type.
494 ///
495 /// By default, performs semantic analysis when building the template
496 /// specialization type. Subclasses may override this routine to provide
497 /// different behavior.
498 QualType RebuildTemplateSpecializationType(TemplateName Template,
John McCall0ad16662009-10-29 08:12:44 +0000499 SourceLocation TemplateLoc,
500 SourceLocation LAngleLoc,
501 const TemplateArgumentLoc *Args,
502 unsigned NumArgs,
503 SourceLocation RAngleLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000504
Douglas Gregord6ff3322009-08-04 16:50:30 +0000505 /// \brief Build a new qualified name type.
506 ///
Mike Stump11289f42009-09-09 15:08:12 +0000507 /// By default, builds a new QualifiedNameType type from the
508 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregord6ff3322009-08-04 16:50:30 +0000509 /// this routine to provide different behavior.
510 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
511 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump11289f42009-09-09 15:08:12 +0000512 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000513
514 /// \brief Build a new typename type that refers to a template-id.
515 ///
516 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump11289f42009-09-09 15:08:12 +0000517 /// and the given type. Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000518 /// different behavior.
519 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
520 if (NNS->isDependent())
Mike Stump11289f42009-09-09 15:08:12 +0000521 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000522 cast<TemplateSpecializationType>(T));
Mike Stump11289f42009-09-09 15:08:12 +0000523
Douglas Gregord6ff3322009-08-04 16:50:30 +0000524 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump11289f42009-09-09 15:08:12 +0000525 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000526
527 /// \brief Build a new typename type that refers to an identifier.
528 ///
529 /// By default, performs semantic analysis when building the typename type
Mike Stump11289f42009-09-09 15:08:12 +0000530 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000531 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000532 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall0ad16662009-10-29 08:12:44 +0000533 const IdentifierInfo *Id,
534 SourceRange SR) {
535 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregor1135c352009-08-06 05:28:30 +0000536 }
Mike Stump11289f42009-09-09 15:08:12 +0000537
Douglas Gregor1135c352009-08-06 05:28:30 +0000538 /// \brief Build a new nested-name-specifier given the prefix and an
539 /// identifier that names the next step in the nested-name-specifier.
540 ///
541 /// By default, performs semantic analysis when building the new
542 /// nested-name-specifier. Subclasses may override this routine to provide
543 /// different behavior.
544 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
545 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000546 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000547 QualType ObjectType,
548 NamedDecl *FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +0000549
550 /// \brief Build a new nested-name-specifier given the prefix and the
551 /// namespace named in the next step in the nested-name-specifier.
552 ///
553 /// By default, performs semantic analysis when building the new
554 /// nested-name-specifier. Subclasses may override this routine to provide
555 /// different behavior.
556 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
557 SourceRange Range,
558 NamespaceDecl *NS);
559
560 /// \brief Build a new nested-name-specifier given the prefix and the
561 /// type named in the next step in the nested-name-specifier.
562 ///
563 /// By default, performs semantic analysis when building the new
564 /// nested-name-specifier. Subclasses may override this routine to provide
565 /// different behavior.
566 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
567 SourceRange Range,
568 bool TemplateKW,
569 QualType T);
Douglas Gregor71dc5092009-08-06 06:41:21 +0000570
571 /// \brief Build a new template name given a nested name specifier, a flag
572 /// indicating whether the "template" keyword was provided, and the template
573 /// that the template name refers to.
574 ///
575 /// By default, builds the new template name directly. Subclasses may override
576 /// this routine to provide different behavior.
577 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
578 bool TemplateKW,
579 TemplateDecl *Template);
580
581 /// \brief Build a new template name given a nested name specifier, a flag
582 /// indicating whether the "template" keyword was provided, and a set of
583 /// overloaded function templates.
584 ///
585 /// By default, builds the new template name directly. Subclasses may override
586 /// this routine to provide different behavior.
587 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
588 bool TemplateKW,
589 OverloadedFunctionDecl *Ovl);
Mike Stump11289f42009-09-09 15:08:12 +0000590
Douglas Gregor71dc5092009-08-06 06:41:21 +0000591 /// \brief Build a new template name given a nested name specifier and the
592 /// name that is referred to as a template.
593 ///
594 /// By default, performs semantic analysis to determine whether the name can
595 /// be resolved to a specific template, then builds the appropriate kind of
596 /// template name. Subclasses may override this routine to provide different
597 /// behavior.
598 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +0000599 const IdentifierInfo &II,
600 QualType ObjectType);
Mike Stump11289f42009-09-09 15:08:12 +0000601
602
Douglas Gregorebe10102009-08-20 07:17:43 +0000603 /// \brief Build a new compound statement.
604 ///
605 /// By default, performs semantic analysis to build the new statement.
606 /// Subclasses may override this routine to provide different behavior.
607 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
608 MultiStmtArg Statements,
609 SourceLocation RBraceLoc,
610 bool IsStmtExpr) {
611 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
612 IsStmtExpr);
613 }
614
615 /// \brief Build a new case statement.
616 ///
617 /// By default, performs semantic analysis to build the new statement.
618 /// Subclasses may override this routine to provide different behavior.
619 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
620 ExprArg LHS,
621 SourceLocation EllipsisLoc,
622 ExprArg RHS,
623 SourceLocation ColonLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000624 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregorebe10102009-08-20 07:17:43 +0000625 ColonLoc);
626 }
Mike Stump11289f42009-09-09 15:08:12 +0000627
Douglas Gregorebe10102009-08-20 07:17:43 +0000628 /// \brief Attach the body to a new case statement.
629 ///
630 /// By default, performs semantic analysis to build the new statement.
631 /// Subclasses may override this routine to provide different behavior.
632 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
633 getSema().ActOnCaseStmtBody(S.get(), move(Body));
634 return move(S);
635 }
Mike Stump11289f42009-09-09 15:08:12 +0000636
Douglas Gregorebe10102009-08-20 07:17:43 +0000637 /// \brief Build a new default statement.
638 ///
639 /// By default, performs semantic analysis to build the new statement.
640 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000641 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000642 SourceLocation ColonLoc,
643 StmtArg SubStmt) {
Mike Stump11289f42009-09-09 15:08:12 +0000644 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregorebe10102009-08-20 07:17:43 +0000645 /*CurScope=*/0);
646 }
Mike Stump11289f42009-09-09 15:08:12 +0000647
Douglas Gregorebe10102009-08-20 07:17:43 +0000648 /// \brief Build a new label statement.
649 ///
650 /// By default, performs semantic analysis to build the new statement.
651 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000652 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000653 IdentifierInfo *Id,
654 SourceLocation ColonLoc,
655 StmtArg SubStmt) {
656 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
657 }
Mike Stump11289f42009-09-09 15:08:12 +0000658
Douglas Gregorebe10102009-08-20 07:17:43 +0000659 /// \brief Build a new "if" statement.
660 ///
661 /// By default, performs semantic analysis to build the new statement.
662 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000663 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
664 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000665 StmtArg Else) {
666 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
667 }
Mike Stump11289f42009-09-09 15:08:12 +0000668
Douglas Gregorebe10102009-08-20 07:17:43 +0000669 /// \brief Start building a new switch statement.
670 ///
671 /// By default, performs semantic analysis to build the new statement.
672 /// Subclasses may override this routine to provide different behavior.
673 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
674 return getSema().ActOnStartOfSwitchStmt(move(Cond));
675 }
Mike Stump11289f42009-09-09 15:08:12 +0000676
Douglas Gregorebe10102009-08-20 07:17:43 +0000677 /// \brief Attach the body to the switch statement.
678 ///
679 /// By default, performs semantic analysis to build the new statement.
680 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000681 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000682 StmtArg Switch, StmtArg Body) {
683 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
684 move(Body));
685 }
686
687 /// \brief Build a new while statement.
688 ///
689 /// By default, performs semantic analysis to build the new statement.
690 /// Subclasses may override this routine to provide different behavior.
691 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
692 Sema::FullExprArg Cond,
693 StmtArg Body) {
694 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
695 }
Mike Stump11289f42009-09-09 15:08:12 +0000696
Douglas Gregorebe10102009-08-20 07:17:43 +0000697 /// \brief Build a new do-while statement.
698 ///
699 /// By default, performs semantic analysis to build the new statement.
700 /// Subclasses may override this routine to provide different behavior.
701 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
702 SourceLocation WhileLoc,
703 SourceLocation LParenLoc,
704 ExprArg Cond,
705 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000706 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000707 move(Cond), RParenLoc);
708 }
709
710 /// \brief Build a new for statement.
711 ///
712 /// By default, performs semantic analysis to build the new statement.
713 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000714 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000715 SourceLocation LParenLoc,
716 StmtArg Init, ExprArg Cond, ExprArg Inc,
717 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump11289f42009-09-09 15:08:12 +0000718 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregorebe10102009-08-20 07:17:43 +0000719 move(Inc), RParenLoc, move(Body));
720 }
Mike Stump11289f42009-09-09 15:08:12 +0000721
Douglas Gregorebe10102009-08-20 07:17:43 +0000722 /// \brief Build a new goto statement.
723 ///
724 /// By default, performs semantic analysis to build the new statement.
725 /// Subclasses may override this routine to provide different behavior.
726 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
727 SourceLocation LabelLoc,
728 LabelStmt *Label) {
729 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
730 }
731
732 /// \brief Build a new indirect goto statement.
733 ///
734 /// By default, performs semantic analysis to build the new statement.
735 /// Subclasses may override this routine to provide different behavior.
736 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
737 SourceLocation StarLoc,
738 ExprArg Target) {
739 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
740 }
Mike Stump11289f42009-09-09 15:08:12 +0000741
Douglas Gregorebe10102009-08-20 07:17:43 +0000742 /// \brief Build a new return statement.
743 ///
744 /// By default, performs semantic analysis to build the new statement.
745 /// Subclasses may override this routine to provide different behavior.
746 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
747 ExprArg Result) {
Mike Stump11289f42009-09-09 15:08:12 +0000748
Douglas Gregorebe10102009-08-20 07:17:43 +0000749 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
750 }
Mike Stump11289f42009-09-09 15:08:12 +0000751
Douglas Gregorebe10102009-08-20 07:17:43 +0000752 /// \brief Build a new declaration statement.
753 ///
754 /// By default, performs semantic analysis to build the new statement.
755 /// Subclasses may override this routine to provide different behavior.
756 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump11289f42009-09-09 15:08:12 +0000757 SourceLocation StartLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000758 SourceLocation EndLoc) {
759 return getSema().Owned(
760 new (getSema().Context) DeclStmt(
761 DeclGroupRef::Create(getSema().Context,
762 Decls, NumDecls),
763 StartLoc, EndLoc));
764 }
Mike Stump11289f42009-09-09 15:08:12 +0000765
Douglas Gregorebe10102009-08-20 07:17:43 +0000766 /// \brief Build a new C++ exception declaration.
767 ///
768 /// By default, performs semantic analysis to build the new decaration.
769 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000770 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregorebe10102009-08-20 07:17:43 +0000771 DeclaratorInfo *Declarator,
772 IdentifierInfo *Name,
773 SourceLocation Loc,
774 SourceRange TypeRange) {
Mike Stump11289f42009-09-09 15:08:12 +0000775 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000776 TypeRange);
777 }
778
779 /// \brief Build a new C++ catch statement.
780 ///
781 /// By default, performs semantic analysis to build the new statement.
782 /// Subclasses may override this routine to provide different behavior.
783 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
784 VarDecl *ExceptionDecl,
785 StmtArg Handler) {
786 return getSema().Owned(
Mike Stump11289f42009-09-09 15:08:12 +0000787 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregorebe10102009-08-20 07:17:43 +0000788 Handler.takeAs<Stmt>()));
789 }
Mike Stump11289f42009-09-09 15:08:12 +0000790
Douglas Gregorebe10102009-08-20 07:17:43 +0000791 /// \brief Build a new C++ try statement.
792 ///
793 /// By default, performs semantic analysis to build the new statement.
794 /// Subclasses may override this routine to provide different behavior.
795 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
796 StmtArg TryBlock,
797 MultiStmtArg Handlers) {
798 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
799 }
Mike Stump11289f42009-09-09 15:08:12 +0000800
Douglas Gregora16548e2009-08-11 05:31:07 +0000801 /// \brief Build a new expression that references a declaration.
802 ///
803 /// By default, performs semantic analysis to build the new expression.
804 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000805 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
806 SourceRange QualifierRange,
807 NamedDecl *ND, SourceLocation Loc) {
808 CXXScopeSpec SS;
809 SS.setScopeRep(Qualifier);
810 SS.setRange(QualifierRange);
Douglas Gregora16548e2009-08-11 05:31:07 +0000811 return getSema().BuildDeclarationNameExpr(Loc, ND,
812 /*FIXME:*/false,
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000813 &SS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000814 /*FIXME:*/false);
815 }
Mike Stump11289f42009-09-09 15:08:12 +0000816
Douglas Gregora16548e2009-08-11 05:31:07 +0000817 /// \brief Build a new expression in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +0000818 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000819 /// By default, performs semantic analysis to build the new expression.
820 /// Subclasses may override this routine to provide different behavior.
821 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
822 SourceLocation RParen) {
823 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
824 }
825
Douglas Gregorad8a3362009-09-04 17:36:40 +0000826 /// \brief Build a new pseudo-destructor expression.
Mike Stump11289f42009-09-09 15:08:12 +0000827 ///
Douglas Gregorad8a3362009-09-04 17:36:40 +0000828 /// By default, performs semantic analysis to build the new expression.
829 /// Subclasses may override this routine to provide different behavior.
830 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
831 SourceLocation OperatorLoc,
832 bool isArrow,
833 SourceLocation DestroyedTypeLoc,
834 QualType DestroyedType,
835 NestedNameSpecifier *Qualifier,
836 SourceRange QualifierRange) {
837 CXXScopeSpec SS;
838 if (Qualifier) {
839 SS.setRange(QualifierRange);
840 SS.setScopeRep(Qualifier);
841 }
842
Mike Stump11289f42009-09-09 15:08:12 +0000843 DeclarationName Name
Douglas Gregorad8a3362009-09-04 17:36:40 +0000844 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
845 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump11289f42009-09-09 15:08:12 +0000846
847 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorad8a3362009-09-04 17:36:40 +0000848 OperatorLoc,
849 isArrow? tok::arrow : tok::period,
850 DestroyedTypeLoc,
851 Name,
852 Sema::DeclPtrTy::make((Decl *)0),
853 &SS);
Mike Stump11289f42009-09-09 15:08:12 +0000854 }
855
Douglas Gregora16548e2009-08-11 05:31:07 +0000856 /// \brief Build a new unary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000857 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000858 /// By default, performs semantic analysis to build the new expression.
859 /// Subclasses may override this routine to provide different behavior.
860 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
861 UnaryOperator::Opcode Opc,
862 ExprArg SubExpr) {
863 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
864 }
Mike Stump11289f42009-09-09 15:08:12 +0000865
Douglas Gregora16548e2009-08-11 05:31:07 +0000866 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump11289f42009-09-09 15:08:12 +0000867 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000868 /// By default, performs semantic analysis to build the new expression.
869 /// Subclasses may override this routine to provide different behavior.
870 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
871 bool isSizeOf, SourceRange R) {
872 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
873 }
874
Mike Stump11289f42009-09-09 15:08:12 +0000875 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000876 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000877 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000878 /// By default, performs semantic analysis to build the new expression.
879 /// Subclasses may override this routine to provide different behavior.
880 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
881 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000882 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000883 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
884 OpLoc, isSizeOf, R);
885 if (Result.isInvalid())
886 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000887
Douglas Gregora16548e2009-08-11 05:31:07 +0000888 SubExpr.release();
889 return move(Result);
890 }
Mike Stump11289f42009-09-09 15:08:12 +0000891
Douglas Gregora16548e2009-08-11 05:31:07 +0000892 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000893 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000894 /// By default, performs semantic analysis to build the new expression.
895 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000896 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000897 SourceLocation LBracketLoc,
898 ExprArg RHS,
899 SourceLocation RBracketLoc) {
900 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000901 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000902 RBracketLoc);
903 }
904
905 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000906 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000907 /// By default, performs semantic analysis to build the new expression.
908 /// Subclasses may override this routine to provide different behavior.
909 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
910 MultiExprArg Args,
911 SourceLocation *CommaLocs,
912 SourceLocation RParenLoc) {
913 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
914 move(Args), CommaLocs, RParenLoc);
915 }
916
917 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000918 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000919 /// By default, performs semantic analysis to build the new expression.
920 /// Subclasses may override this routine to provide different behavior.
921 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000922 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000923 NestedNameSpecifier *Qualifier,
924 SourceRange QualifierRange,
925 SourceLocation MemberLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000926 NamedDecl *Member) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000927 if (!Member->getDeclName()) {
928 // We have a reference to an unnamed field.
929 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000930
931 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000932 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
933 Member, MemberLoc,
934 cast<FieldDecl>(Member)->getType());
935 return getSema().Owned(ME);
936 }
Mike Stump11289f42009-09-09 15:08:12 +0000937
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000938 CXXScopeSpec SS;
939 if (Qualifier) {
940 SS.setRange(QualifierRange);
941 SS.setScopeRep(Qualifier);
942 }
943
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000944 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000945 isArrow? tok::arrow : tok::period,
946 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000947 Member->getDeclName(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000948 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
949 &SS);
Douglas Gregora16548e2009-08-11 05:31:07 +0000950 }
Mike Stump11289f42009-09-09 15:08:12 +0000951
Douglas Gregora16548e2009-08-11 05:31:07 +0000952 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000953 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000954 /// By default, performs semantic analysis to build the new expression.
955 /// Subclasses may override this routine to provide different behavior.
956 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
957 BinaryOperator::Opcode Opc,
958 ExprArg LHS, ExprArg RHS) {
959 OwningExprResult Result
Mike Stump11289f42009-09-09 15:08:12 +0000960 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +0000961 (Expr *)RHS.get());
962 if (Result.isInvalid())
963 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000964
Douglas Gregora16548e2009-08-11 05:31:07 +0000965 LHS.release();
966 RHS.release();
967 return move(Result);
968 }
969
970 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000971 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000972 /// By default, performs semantic analysis to build the new expression.
973 /// Subclasses may override this routine to provide different behavior.
974 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
975 SourceLocation QuestionLoc,
976 ExprArg LHS,
977 SourceLocation ColonLoc,
978 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +0000979 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +0000980 move(LHS), move(RHS));
981 }
982
983 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000984 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000985 /// By default, builds a new implicit cast without any semantic analysis.
986 /// Subclasses may override this routine to provide different behavior.
987 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
988 ExprArg SubExpr, bool isLvalue) {
989 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +0000990 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +0000991 (Expr *)SubExpr.release(),
992 isLvalue);
993 return getSema().Owned(ICE);
994 }
995
996 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000997 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000998 /// By default, performs semantic analysis to build the new expression.
999 /// Subclasses may override this routine to provide different behavior.
1000 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1001 QualType ExplicitTy,
1002 SourceLocation RParenLoc,
1003 ExprArg SubExpr) {
1004 return getSema().ActOnCastExpr(/*Scope=*/0,
1005 LParenLoc,
1006 ExplicitTy.getAsOpaquePtr(),
1007 RParenLoc,
1008 move(SubExpr));
1009 }
Mike Stump11289f42009-09-09 15:08:12 +00001010
Douglas Gregora16548e2009-08-11 05:31:07 +00001011 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +00001012 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001013 /// By default, performs semantic analysis to build the new expression.
1014 /// Subclasses may override this routine to provide different behavior.
1015 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1016 QualType T,
1017 SourceLocation RParenLoc,
1018 ExprArg Init) {
1019 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1020 RParenLoc, move(Init));
1021 }
Mike Stump11289f42009-09-09 15:08:12 +00001022
Douglas Gregora16548e2009-08-11 05:31:07 +00001023 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +00001024 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001025 /// By default, performs semantic analysis to build the new expression.
1026 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001027 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001028 SourceLocation OpLoc,
1029 SourceLocation AccessorLoc,
1030 IdentifierInfo &Accessor) {
1031 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
1032 tok::period, AccessorLoc,
1033 Accessor,
1034 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1035 }
Mike Stump11289f42009-09-09 15:08:12 +00001036
Douglas Gregora16548e2009-08-11 05:31:07 +00001037 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001038 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001039 /// By default, performs semantic analysis to build the new expression.
1040 /// Subclasses may override this routine to provide different behavior.
1041 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1042 MultiExprArg Inits,
1043 SourceLocation RBraceLoc) {
1044 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1045 }
Mike Stump11289f42009-09-09 15:08:12 +00001046
Douglas Gregora16548e2009-08-11 05:31:07 +00001047 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001048 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001049 /// By default, performs semantic analysis to build the new expression.
1050 /// Subclasses may override this routine to provide different behavior.
1051 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1052 MultiExprArg ArrayExprs,
1053 SourceLocation EqualOrColonLoc,
1054 bool GNUSyntax,
1055 ExprArg Init) {
1056 OwningExprResult Result
1057 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1058 move(Init));
1059 if (Result.isInvalid())
1060 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001061
Douglas Gregora16548e2009-08-11 05:31:07 +00001062 ArrayExprs.release();
1063 return move(Result);
1064 }
Mike Stump11289f42009-09-09 15:08:12 +00001065
Douglas Gregora16548e2009-08-11 05:31:07 +00001066 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001067 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001068 /// By default, builds the implicit value initialization without performing
1069 /// any semantic analysis. Subclasses may override this routine to provide
1070 /// different behavior.
1071 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1072 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1073 }
Mike Stump11289f42009-09-09 15:08:12 +00001074
Douglas Gregora16548e2009-08-11 05:31:07 +00001075 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001076 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001077 /// By default, performs semantic analysis to build the new expression.
1078 /// Subclasses may override this routine to provide different behavior.
1079 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1080 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001081 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001082 RParenLoc);
1083 }
1084
1085 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001086 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001087 /// By default, performs semantic analysis to build the new expression.
1088 /// Subclasses may override this routine to provide different behavior.
1089 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1090 MultiExprArg SubExprs,
1091 SourceLocation RParenLoc) {
1092 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1093 }
Mike Stump11289f42009-09-09 15:08:12 +00001094
Douglas Gregora16548e2009-08-11 05:31:07 +00001095 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001096 ///
1097 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001098 /// rather than attempting to map the label statement itself.
1099 /// Subclasses may override this routine to provide different behavior.
1100 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1101 SourceLocation LabelLoc,
1102 LabelStmt *Label) {
1103 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1104 }
Mike Stump11289f42009-09-09 15:08:12 +00001105
Douglas Gregora16548e2009-08-11 05:31:07 +00001106 /// \brief Build a new GNU statement expression.
Mike Stump11289f42009-09-09 15:08:12 +00001107 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001108 /// By default, performs semantic analysis to build the new expression.
1109 /// Subclasses may override this routine to provide different behavior.
1110 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1111 StmtArg SubStmt,
1112 SourceLocation RParenLoc) {
1113 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1114 }
Mike Stump11289f42009-09-09 15:08:12 +00001115
Douglas Gregora16548e2009-08-11 05:31:07 +00001116 /// \brief Build a new __builtin_types_compatible_p expression.
1117 ///
1118 /// By default, performs semantic analysis to build the new expression.
1119 /// Subclasses may override this routine to provide different behavior.
1120 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1121 QualType T1, QualType T2,
1122 SourceLocation RParenLoc) {
1123 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1124 T1.getAsOpaquePtr(),
1125 T2.getAsOpaquePtr(),
1126 RParenLoc);
1127 }
Mike Stump11289f42009-09-09 15:08:12 +00001128
Douglas Gregora16548e2009-08-11 05:31:07 +00001129 /// \brief Build a new __builtin_choose_expr expression.
1130 ///
1131 /// By default, performs semantic analysis to build the new expression.
1132 /// Subclasses may override this routine to provide different behavior.
1133 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1134 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1135 SourceLocation RParenLoc) {
1136 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1137 move(Cond), move(LHS), move(RHS),
1138 RParenLoc);
1139 }
Mike Stump11289f42009-09-09 15:08:12 +00001140
Douglas Gregora16548e2009-08-11 05:31:07 +00001141 /// \brief Build a new overloaded operator call expression.
1142 ///
1143 /// By default, performs semantic analysis to build the new expression.
1144 /// The semantic analysis provides the behavior of template instantiation,
1145 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001146 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001147 /// argument-dependent lookup, etc. Subclasses may override this routine to
1148 /// provide different behavior.
1149 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1150 SourceLocation OpLoc,
1151 ExprArg Callee,
1152 ExprArg First,
1153 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001154
1155 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001156 /// reinterpret_cast.
1157 ///
1158 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001159 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001160 /// Subclasses may override this routine to provide different behavior.
1161 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1162 Stmt::StmtClass Class,
1163 SourceLocation LAngleLoc,
1164 QualType T,
1165 SourceLocation RAngleLoc,
1166 SourceLocation LParenLoc,
1167 ExprArg SubExpr,
1168 SourceLocation RParenLoc) {
1169 switch (Class) {
1170 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001171 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1172 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001173 move(SubExpr), RParenLoc);
1174
1175 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001176 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1177 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001178 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001179
Douglas Gregora16548e2009-08-11 05:31:07 +00001180 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001181 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1182 RAngleLoc, LParenLoc,
1183 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001184 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001185
Douglas Gregora16548e2009-08-11 05:31:07 +00001186 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001187 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1188 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001189 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001190
Douglas Gregora16548e2009-08-11 05:31:07 +00001191 default:
1192 assert(false && "Invalid C++ named cast");
1193 break;
1194 }
Mike Stump11289f42009-09-09 15:08:12 +00001195
Douglas Gregora16548e2009-08-11 05:31:07 +00001196 return getSema().ExprError();
1197 }
Mike Stump11289f42009-09-09 15:08:12 +00001198
Douglas Gregora16548e2009-08-11 05:31:07 +00001199 /// \brief Build a new C++ static_cast expression.
1200 ///
1201 /// By default, performs semantic analysis to build the new expression.
1202 /// Subclasses may override this routine to provide different behavior.
1203 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1204 SourceLocation LAngleLoc,
1205 QualType T,
1206 SourceLocation RAngleLoc,
1207 SourceLocation LParenLoc,
1208 ExprArg SubExpr,
1209 SourceLocation RParenLoc) {
1210 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001211 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001212 LParenLoc, move(SubExpr), RParenLoc);
1213 }
1214
1215 /// \brief Build a new C++ dynamic_cast expression.
1216 ///
1217 /// By default, performs semantic analysis to build the new expression.
1218 /// Subclasses may override this routine to provide different behavior.
1219 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1220 SourceLocation LAngleLoc,
1221 QualType T,
1222 SourceLocation RAngleLoc,
1223 SourceLocation LParenLoc,
1224 ExprArg SubExpr,
1225 SourceLocation RParenLoc) {
1226 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001227 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001228 LParenLoc, move(SubExpr), RParenLoc);
1229 }
1230
1231 /// \brief Build a new C++ reinterpret_cast expression.
1232 ///
1233 /// By default, performs semantic analysis to build the new expression.
1234 /// Subclasses may override this routine to provide different behavior.
1235 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1236 SourceLocation LAngleLoc,
1237 QualType T,
1238 SourceLocation RAngleLoc,
1239 SourceLocation LParenLoc,
1240 ExprArg SubExpr,
1241 SourceLocation RParenLoc) {
1242 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1243 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1244 LParenLoc, move(SubExpr), RParenLoc);
1245 }
1246
1247 /// \brief Build a new C++ const_cast expression.
1248 ///
1249 /// By default, performs semantic analysis to build the new expression.
1250 /// Subclasses may override this routine to provide different behavior.
1251 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1252 SourceLocation LAngleLoc,
1253 QualType T,
1254 SourceLocation RAngleLoc,
1255 SourceLocation LParenLoc,
1256 ExprArg SubExpr,
1257 SourceLocation RParenLoc) {
1258 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001259 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001260 LParenLoc, move(SubExpr), RParenLoc);
1261 }
Mike Stump11289f42009-09-09 15:08:12 +00001262
Douglas Gregora16548e2009-08-11 05:31:07 +00001263 /// \brief Build a new C++ functional-style cast expression.
1264 ///
1265 /// By default, performs semantic analysis to build the new expression.
1266 /// Subclasses may override this routine to provide different behavior.
1267 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1268 QualType T,
1269 SourceLocation LParenLoc,
1270 ExprArg SubExpr,
1271 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001272 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001273 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1274 T.getAsOpaquePtr(),
1275 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001276 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001277 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001278 RParenLoc);
1279 }
Mike Stump11289f42009-09-09 15:08:12 +00001280
Douglas Gregora16548e2009-08-11 05:31:07 +00001281 /// \brief Build a new C++ typeid(type) expression.
1282 ///
1283 /// By default, performs semantic analysis to build the new expression.
1284 /// Subclasses may override this routine to provide different behavior.
1285 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1286 SourceLocation LParenLoc,
1287 QualType T,
1288 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001289 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001290 T.getAsOpaquePtr(), RParenLoc);
1291 }
Mike Stump11289f42009-09-09 15:08:12 +00001292
Douglas Gregora16548e2009-08-11 05:31:07 +00001293 /// \brief Build a new C++ typeid(expr) expression.
1294 ///
1295 /// By default, performs semantic analysis to build the new expression.
1296 /// Subclasses may override this routine to provide different behavior.
1297 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1298 SourceLocation LParenLoc,
1299 ExprArg Operand,
1300 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001301 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001302 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1303 RParenLoc);
1304 if (Result.isInvalid())
1305 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001306
Douglas Gregora16548e2009-08-11 05:31:07 +00001307 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1308 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001309 }
1310
Douglas Gregora16548e2009-08-11 05:31:07 +00001311 /// \brief Build a new C++ "this" expression.
1312 ///
1313 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001314 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001315 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001316 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001317 QualType ThisType) {
1318 return getSema().Owned(
1319 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1320 }
1321
1322 /// \brief Build a new C++ throw expression.
1323 ///
1324 /// By default, performs semantic analysis to build the new expression.
1325 /// Subclasses may override this routine to provide different behavior.
1326 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1327 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1328 }
1329
1330 /// \brief Build a new C++ default-argument expression.
1331 ///
1332 /// By default, builds a new default-argument expression, which does not
1333 /// require any semantic analysis. Subclasses may override this routine to
1334 /// provide different behavior.
1335 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001336 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001337 }
1338
1339 /// \brief Build a new C++ zero-initialization expression.
1340 ///
1341 /// By default, performs semantic analysis to build the new expression.
1342 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001343 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001344 SourceLocation LParenLoc,
1345 QualType T,
1346 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001347 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1348 T.getAsOpaquePtr(), LParenLoc,
1349 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001350 0, RParenLoc);
1351 }
Mike Stump11289f42009-09-09 15:08:12 +00001352
Douglas Gregora16548e2009-08-11 05:31:07 +00001353 /// \brief Build a new C++ conditional declaration expression.
1354 ///
1355 /// By default, performs semantic analysis to build the new expression.
1356 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001357 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001358 SourceLocation EqLoc,
1359 VarDecl *Var) {
1360 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1361 EqLoc,
1362 Var));
1363 }
Mike Stump11289f42009-09-09 15:08:12 +00001364
Douglas Gregora16548e2009-08-11 05:31:07 +00001365 /// \brief Build a new C++ "new" expression.
1366 ///
1367 /// By default, performs semantic analysis to build the new expression.
1368 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001369 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001370 bool UseGlobal,
1371 SourceLocation PlacementLParen,
1372 MultiExprArg PlacementArgs,
1373 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001374 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001375 QualType AllocType,
1376 SourceLocation TypeLoc,
1377 SourceRange TypeRange,
1378 ExprArg ArraySize,
1379 SourceLocation ConstructorLParen,
1380 MultiExprArg ConstructorArgs,
1381 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001382 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001383 PlacementLParen,
1384 move(PlacementArgs),
1385 PlacementRParen,
1386 ParenTypeId,
1387 AllocType,
1388 TypeLoc,
1389 TypeRange,
1390 move(ArraySize),
1391 ConstructorLParen,
1392 move(ConstructorArgs),
1393 ConstructorRParen);
1394 }
Mike Stump11289f42009-09-09 15:08:12 +00001395
Douglas Gregora16548e2009-08-11 05:31:07 +00001396 /// \brief Build a new C++ "delete" expression.
1397 ///
1398 /// By default, performs semantic analysis to build the new expression.
1399 /// Subclasses may override this routine to provide different behavior.
1400 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1401 bool IsGlobalDelete,
1402 bool IsArrayForm,
1403 ExprArg Operand) {
1404 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1405 move(Operand));
1406 }
Mike Stump11289f42009-09-09 15:08:12 +00001407
Douglas Gregora16548e2009-08-11 05:31:07 +00001408 /// \brief Build a new unary type trait expression.
1409 ///
1410 /// By default, performs semantic analysis to build the new expression.
1411 /// Subclasses may override this routine to provide different behavior.
1412 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1413 SourceLocation StartLoc,
1414 SourceLocation LParenLoc,
1415 QualType T,
1416 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001417 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001418 T.getAsOpaquePtr(), RParenLoc);
1419 }
1420
Mike Stump11289f42009-09-09 15:08:12 +00001421 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001422 /// expression.
1423 ///
1424 /// By default, performs semantic analysis to build the new expression.
1425 /// Subclasses may override this routine to provide different behavior.
1426 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1427 SourceRange QualifierRange,
1428 DeclarationName Name,
1429 SourceLocation Location,
1430 bool IsAddressOfOperand) {
1431 CXXScopeSpec SS;
1432 SS.setRange(QualifierRange);
1433 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001434 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001435 Location,
1436 Name,
1437 /*Trailing lparen=*/false,
1438 &SS,
1439 IsAddressOfOperand);
1440 }
1441
1442 /// \brief Build a new template-id expression.
1443 ///
1444 /// By default, performs semantic analysis to build the new expression.
1445 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001446 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1447 SourceRange QualifierRange,
1448 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001449 SourceLocation TemplateLoc,
1450 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001451 TemplateArgumentLoc *TemplateArgs,
Douglas Gregora16548e2009-08-11 05:31:07 +00001452 unsigned NumTemplateArgs,
1453 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001454 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1455 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001456 LAngleLoc,
1457 TemplateArgs, NumTemplateArgs,
1458 RAngleLoc);
1459 }
1460
1461 /// \brief Build a new object-construction expression.
1462 ///
1463 /// By default, performs semantic analysis to build the new expression.
1464 /// Subclasses may override this routine to provide different behavior.
1465 OwningExprResult RebuildCXXConstructExpr(QualType T,
1466 CXXConstructorDecl *Constructor,
1467 bool IsElidable,
1468 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001469 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1470 SourceLocation(),
1471 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001472 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001473 }
1474
1475 /// \brief Build a new object-construction expression.
1476 ///
1477 /// By default, performs semantic analysis to build the new expression.
1478 /// Subclasses may override this routine to provide different behavior.
1479 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1480 QualType T,
1481 SourceLocation LParenLoc,
1482 MultiExprArg Args,
1483 SourceLocation *Commas,
1484 SourceLocation RParenLoc) {
1485 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1486 T.getAsOpaquePtr(),
1487 LParenLoc,
1488 move(Args),
1489 Commas,
1490 RParenLoc);
1491 }
1492
1493 /// \brief Build a new object-construction expression.
1494 ///
1495 /// By default, performs semantic analysis to build the new expression.
1496 /// Subclasses may override this routine to provide different behavior.
1497 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1498 QualType T,
1499 SourceLocation LParenLoc,
1500 MultiExprArg Args,
1501 SourceLocation *Commas,
1502 SourceLocation RParenLoc) {
1503 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1504 /*FIXME*/LParenLoc),
1505 T.getAsOpaquePtr(),
1506 LParenLoc,
1507 move(Args),
1508 Commas,
1509 RParenLoc);
1510 }
Mike Stump11289f42009-09-09 15:08:12 +00001511
Douglas Gregora16548e2009-08-11 05:31:07 +00001512 /// \brief Build a new member reference expression.
1513 ///
1514 /// By default, performs semantic analysis to build the new expression.
1515 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001516 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001517 bool IsArrow,
1518 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001519 NestedNameSpecifier *Qualifier,
1520 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001521 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001522 SourceLocation MemberLoc,
1523 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001524 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001525 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001526
Douglas Gregora16548e2009-08-11 05:31:07 +00001527 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001528 SS.setRange(QualifierRange);
1529 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001530
Douglas Gregor308047d2009-09-09 00:23:06 +00001531 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001532 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001533 MemberLoc,
1534 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001535 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001536 &SS,
1537 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001538 }
1539
Douglas Gregor308047d2009-09-09 00:23:06 +00001540 /// \brief Build a new member reference expression with explicit template
1541 /// arguments.
1542 ///
1543 /// By default, performs semantic analysis to build the new expression.
1544 /// Subclasses may override this routine to provide different behavior.
1545 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1546 bool IsArrow,
1547 SourceLocation OperatorLoc,
1548 NestedNameSpecifier *Qualifier,
1549 SourceRange QualifierRange,
1550 TemplateName Template,
1551 SourceLocation TemplateNameLoc,
1552 NamedDecl *FirstQualifierInScope,
1553 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001554 const TemplateArgumentLoc *TemplateArgs,
Douglas Gregor308047d2009-09-09 00:23:06 +00001555 unsigned NumTemplateArgs,
1556 SourceLocation RAngleLoc) {
1557 OwningExprResult Base = move(BaseE);
1558 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001559
Douglas Gregor308047d2009-09-09 00:23:06 +00001560 CXXScopeSpec SS;
1561 SS.setRange(QualifierRange);
1562 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001563
Douglas Gregor308047d2009-09-09 00:23:06 +00001564 // FIXME: We're going to end up looking up the template based on its name,
1565 // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
1566 DeclarationName Name;
1567 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1568 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001569 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001570 = Template.getAsOverloadedFunctionDecl())
1571 Name = Ovl->getDeclName();
1572 else
1573 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump11289f42009-09-09 15:08:12 +00001574
1575 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001576 OperatorLoc, OpKind,
1577 TemplateNameLoc, Name, true,
1578 LAngleLoc, TemplateArgs,
1579 NumTemplateArgs, RAngleLoc,
1580 Sema::DeclPtrTy(), &SS);
1581 }
Mike Stump11289f42009-09-09 15:08:12 +00001582
Douglas Gregora16548e2009-08-11 05:31:07 +00001583 /// \brief Build a new Objective-C @encode expression.
1584 ///
1585 /// By default, performs semantic analysis to build the new expression.
1586 /// Subclasses may override this routine to provide different behavior.
1587 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1588 QualType T,
1589 SourceLocation RParenLoc) {
1590 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1591 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001592 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001593
1594 /// \brief Build a new Objective-C protocol expression.
1595 ///
1596 /// By default, performs semantic analysis to build the new expression.
1597 /// Subclasses may override this routine to provide different behavior.
1598 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1599 SourceLocation AtLoc,
1600 SourceLocation ProtoLoc,
1601 SourceLocation LParenLoc,
1602 SourceLocation RParenLoc) {
1603 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1604 Protocol->getIdentifier(),
1605 AtLoc,
1606 ProtoLoc,
1607 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001608 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001609 }
Mike Stump11289f42009-09-09 15:08:12 +00001610
Douglas Gregora16548e2009-08-11 05:31:07 +00001611 /// \brief Build a new shuffle vector expression.
1612 ///
1613 /// By default, performs semantic analysis to build the new expression.
1614 /// Subclasses may override this routine to provide different behavior.
1615 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1616 MultiExprArg SubExprs,
1617 SourceLocation RParenLoc) {
1618 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001619 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001620 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1621 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1622 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1623 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001624
Douglas Gregora16548e2009-08-11 05:31:07 +00001625 // Build a reference to the __builtin_shufflevector builtin
1626 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001627 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001628 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1629 BuiltinLoc, false, false);
1630 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001631
1632 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001633 unsigned NumSubExprs = SubExprs.size();
1634 Expr **Subs = (Expr **)SubExprs.release();
1635 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1636 Subs, NumSubExprs,
1637 Builtin->getResultType(),
1638 RParenLoc);
1639 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001640
Douglas Gregora16548e2009-08-11 05:31:07 +00001641 // Type-check the __builtin_shufflevector expression.
1642 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1643 if (Result.isInvalid())
1644 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001645
Douglas Gregora16548e2009-08-11 05:31:07 +00001646 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001647 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001648 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001649};
Douglas Gregora16548e2009-08-11 05:31:07 +00001650
Douglas Gregorebe10102009-08-20 07:17:43 +00001651template<typename Derived>
1652Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1653 if (!S)
1654 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001655
Douglas Gregorebe10102009-08-20 07:17:43 +00001656 switch (S->getStmtClass()) {
1657 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001658
Douglas Gregorebe10102009-08-20 07:17:43 +00001659 // Transform individual statement nodes
1660#define STMT(Node, Parent) \
1661 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1662#define EXPR(Node, Parent)
1663#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001664
Douglas Gregorebe10102009-08-20 07:17:43 +00001665 // Transform expressions by calling TransformExpr.
1666#define STMT(Node, Parent)
1667#define EXPR(Node, Parent) case Stmt::Node##Class:
1668#include "clang/AST/StmtNodes.def"
1669 {
1670 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1671 if (E.isInvalid())
1672 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001673
Douglas Gregorebe10102009-08-20 07:17:43 +00001674 return getSema().Owned(E.takeAs<Stmt>());
1675 }
Mike Stump11289f42009-09-09 15:08:12 +00001676 }
1677
Douglas Gregorebe10102009-08-20 07:17:43 +00001678 return SemaRef.Owned(S->Retain());
1679}
Mike Stump11289f42009-09-09 15:08:12 +00001680
1681
Douglas Gregore922c772009-08-04 22:27:00 +00001682template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001683Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1684 bool isAddressOfOperand) {
1685 if (!E)
1686 return SemaRef.Owned(E);
1687
1688 switch (E->getStmtClass()) {
1689 case Stmt::NoStmtClass: break;
1690#define STMT(Node, Parent) case Stmt::Node##Class: break;
1691#define EXPR(Node, Parent) \
1692 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1693#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001694 }
1695
Douglas Gregora16548e2009-08-11 05:31:07 +00001696 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001697}
1698
1699template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001700NestedNameSpecifier *
1701TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001702 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001703 QualType ObjectType,
1704 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001705 if (!NNS)
1706 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001707
Douglas Gregorebe10102009-08-20 07:17:43 +00001708 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001709 NestedNameSpecifier *Prefix = NNS->getPrefix();
1710 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001711 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001712 ObjectType,
1713 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001714 if (!Prefix)
1715 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001716
1717 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001718 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001719 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001720 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001721 }
Mike Stump11289f42009-09-09 15:08:12 +00001722
Douglas Gregor1135c352009-08-06 05:28:30 +00001723 switch (NNS->getKind()) {
1724 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001725 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001726 "Identifier nested-name-specifier with no prefix or object type");
1727 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1728 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001729 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001730
1731 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001732 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001733 ObjectType,
1734 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001735
Douglas Gregor1135c352009-08-06 05:28:30 +00001736 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001737 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001738 = cast_or_null<NamespaceDecl>(
1739 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001740 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001741 Prefix == NNS->getPrefix() &&
1742 NS == NNS->getAsNamespace())
1743 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001744
Douglas Gregor1135c352009-08-06 05:28:30 +00001745 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1746 }
Mike Stump11289f42009-09-09 15:08:12 +00001747
Douglas Gregor1135c352009-08-06 05:28:30 +00001748 case NestedNameSpecifier::Global:
1749 // There is no meaningful transformation that one could perform on the
1750 // global scope.
1751 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001752
Douglas Gregor1135c352009-08-06 05:28:30 +00001753 case NestedNameSpecifier::TypeSpecWithTemplate:
1754 case NestedNameSpecifier::TypeSpec: {
1755 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001756 if (T.isNull())
1757 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001758
Douglas Gregor1135c352009-08-06 05:28:30 +00001759 if (!getDerived().AlwaysRebuild() &&
1760 Prefix == NNS->getPrefix() &&
1761 T == QualType(NNS->getAsType(), 0))
1762 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001763
1764 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1765 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001766 T);
1767 }
1768 }
Mike Stump11289f42009-09-09 15:08:12 +00001769
Douglas Gregor1135c352009-08-06 05:28:30 +00001770 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001771 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001772}
1773
1774template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001775DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001776TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001777 SourceLocation Loc,
1778 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001779 if (!Name)
1780 return Name;
1781
1782 switch (Name.getNameKind()) {
1783 case DeclarationName::Identifier:
1784 case DeclarationName::ObjCZeroArgSelector:
1785 case DeclarationName::ObjCOneArgSelector:
1786 case DeclarationName::ObjCMultiArgSelector:
1787 case DeclarationName::CXXOperatorName:
1788 case DeclarationName::CXXUsingDirective:
1789 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001790
Douglas Gregorf816bd72009-09-03 22:13:48 +00001791 case DeclarationName::CXXConstructorName:
1792 case DeclarationName::CXXDestructorName:
1793 case DeclarationName::CXXConversionFunctionName: {
1794 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001795 QualType T;
1796 if (!ObjectType.isNull() &&
1797 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1798 TemplateSpecializationType *SpecType
1799 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1800 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1801 } else
1802 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001803 if (T.isNull())
1804 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001805
Douglas Gregorf816bd72009-09-03 22:13:48 +00001806 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001807 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001808 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001809 }
Mike Stump11289f42009-09-09 15:08:12 +00001810 }
1811
Douglas Gregorf816bd72009-09-03 22:13:48 +00001812 return DeclarationName();
1813}
1814
1815template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001816TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001817TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1818 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001819 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001820 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001821 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1822 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1823 if (!NNS)
1824 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001825
Douglas Gregor71dc5092009-08-06 06:41:21 +00001826 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001827 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001828 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1829 if (!TransTemplate)
1830 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001831
Douglas Gregor71dc5092009-08-06 06:41:21 +00001832 if (!getDerived().AlwaysRebuild() &&
1833 NNS == QTN->getQualifier() &&
1834 TransTemplate == Template)
1835 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001836
Douglas Gregor71dc5092009-08-06 06:41:21 +00001837 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1838 TransTemplate);
1839 }
Mike Stump11289f42009-09-09 15:08:12 +00001840
Douglas Gregor71dc5092009-08-06 06:41:21 +00001841 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1842 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001843 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001844 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1845 if (!TransOvl)
1846 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001847
Douglas Gregor71dc5092009-08-06 06:41:21 +00001848 if (!getDerived().AlwaysRebuild() &&
1849 NNS == QTN->getQualifier() &&
1850 TransOvl == Ovl)
1851 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001852
Douglas Gregor71dc5092009-08-06 06:41:21 +00001853 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1854 TransOvl);
1855 }
Mike Stump11289f42009-09-09 15:08:12 +00001856
Douglas Gregor71dc5092009-08-06 06:41:21 +00001857 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001858 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001859 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1860 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001861 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001862 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001863
Douglas Gregor71dc5092009-08-06 06:41:21 +00001864 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001865 NNS == DTN->getQualifier() &&
1866 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001867 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001868
Douglas Gregor308047d2009-09-09 00:23:06 +00001869 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001870 }
Mike Stump11289f42009-09-09 15:08:12 +00001871
Douglas Gregor71dc5092009-08-06 06:41:21 +00001872 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001873 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001874 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1875 if (!TransTemplate)
1876 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001877
Douglas Gregor71dc5092009-08-06 06:41:21 +00001878 if (!getDerived().AlwaysRebuild() &&
1879 TransTemplate == Template)
1880 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001881
Douglas Gregor71dc5092009-08-06 06:41:21 +00001882 return TemplateName(TransTemplate);
1883 }
Mike Stump11289f42009-09-09 15:08:12 +00001884
Douglas Gregor71dc5092009-08-06 06:41:21 +00001885 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1886 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001887 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001888 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1889 if (!TransOvl)
1890 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001891
Douglas Gregor71dc5092009-08-06 06:41:21 +00001892 if (!getDerived().AlwaysRebuild() &&
1893 TransOvl == Ovl)
1894 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001895
Douglas Gregor71dc5092009-08-06 06:41:21 +00001896 return TemplateName(TransOvl);
1897}
1898
1899template<typename Derived>
John McCall0ad16662009-10-29 08:12:44 +00001900void TreeTransform<Derived>::InventTemplateArgumentLoc(
1901 const TemplateArgument &Arg,
1902 TemplateArgumentLoc &Output) {
1903 SourceLocation Loc = getDerived().getBaseLocation();
1904 switch (Arg.getKind()) {
1905 case TemplateArgument::Null:
1906 llvm::llvm_unreachable("null template argument in TreeTransform");
1907 break;
1908
1909 case TemplateArgument::Type:
1910 Output = TemplateArgumentLoc(Arg,
1911 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1912
1913 break;
1914
1915 case TemplateArgument::Expression:
1916 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1917 break;
1918
1919 case TemplateArgument::Declaration:
1920 case TemplateArgument::Integral:
1921 case TemplateArgument::Pack:
1922 Output = TemplateArgumentLoc(Arg);
1923 break;
1924 }
1925}
1926
1927template<typename Derived>
1928bool TreeTransform<Derived>::TransformTemplateArgument(
1929 const TemplateArgumentLoc &Input,
1930 TemplateArgumentLoc &Output) {
1931 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregore922c772009-08-04 22:27:00 +00001932 switch (Arg.getKind()) {
1933 case TemplateArgument::Null:
1934 case TemplateArgument::Integral:
John McCall0ad16662009-10-29 08:12:44 +00001935 Output = Input;
1936 return false;
Mike Stump11289f42009-09-09 15:08:12 +00001937
Douglas Gregore922c772009-08-04 22:27:00 +00001938 case TemplateArgument::Type: {
John McCall0ad16662009-10-29 08:12:44 +00001939 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1940 if (DI == NULL)
1941 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1942
1943 DI = getDerived().TransformType(DI);
1944 if (!DI) return true;
1945
1946 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1947 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001948 }
Mike Stump11289f42009-09-09 15:08:12 +00001949
Douglas Gregore922c772009-08-04 22:27:00 +00001950 case TemplateArgument::Declaration: {
John McCall0ad16662009-10-29 08:12:44 +00001951 // FIXME: we should never have to transform one of these.
Douglas Gregoref6ab412009-10-27 06:26:26 +00001952 DeclarationName Name;
1953 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1954 Name = ND->getDeclName();
John McCall0ad16662009-10-29 08:12:44 +00001955 TemporaryBase Rebase(*this, SourceLocation(), Name);
Douglas Gregore922c772009-08-04 22:27:00 +00001956 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall0ad16662009-10-29 08:12:44 +00001957 if (!D) return true;
1958
1959 Output = TemplateArgumentLoc(TemplateArgument(D));
1960 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001961 }
Mike Stump11289f42009-09-09 15:08:12 +00001962
Douglas Gregore922c772009-08-04 22:27:00 +00001963 case TemplateArgument::Expression: {
1964 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00001965 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00001966 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00001967
John McCall0ad16662009-10-29 08:12:44 +00001968 Expr *InputExpr = Input.getSourceExpression();
1969 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
1970
1971 Sema::OwningExprResult E
1972 = getDerived().TransformExpr(InputExpr);
1973 if (E.isInvalid()) return true;
1974
1975 Expr *ETaken = E.takeAs<Expr>();
1976 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
1977 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001978 }
Mike Stump11289f42009-09-09 15:08:12 +00001979
Douglas Gregore922c772009-08-04 22:27:00 +00001980 case TemplateArgument::Pack: {
1981 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1982 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00001983 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00001984 AEnd = Arg.pack_end();
1985 A != AEnd; ++A) {
Mike Stump11289f42009-09-09 15:08:12 +00001986
John McCall0ad16662009-10-29 08:12:44 +00001987 // FIXME: preserve source information here when we start
1988 // caring about parameter packs.
1989
1990 TemplateArgumentLoc Input;
1991 TemplateArgumentLoc Output;
1992 getDerived().InventTemplateArgumentLoc(*A, Input);
1993 if (getDerived().TransformTemplateArgument(Input, Output))
1994 return true;
1995
1996 TransformedArgs.push_back(Output.getArgument());
Douglas Gregore922c772009-08-04 22:27:00 +00001997 }
1998 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00001999 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00002000 true);
John McCall0ad16662009-10-29 08:12:44 +00002001 Output = TemplateArgumentLoc(Result);
2002 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002003 }
2004 }
Mike Stump11289f42009-09-09 15:08:12 +00002005
Douglas Gregore922c772009-08-04 22:27:00 +00002006 // Work around bogus GCC warning
John McCall0ad16662009-10-29 08:12:44 +00002007 return true;
Douglas Gregore922c772009-08-04 22:27:00 +00002008}
2009
Douglas Gregord6ff3322009-08-04 16:50:30 +00002010//===----------------------------------------------------------------------===//
2011// Type transformation
2012//===----------------------------------------------------------------------===//
2013
2014template<typename Derived>
2015QualType TreeTransform<Derived>::TransformType(QualType T) {
2016 if (getDerived().AlreadyTransformed(T))
2017 return T;
Mike Stump11289f42009-09-09 15:08:12 +00002018
John McCall550e0c22009-10-21 00:40:46 +00002019 // Temporary workaround. All of these transformations should
2020 // eventually turn into transformations on TypeLocs.
2021 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00002022 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00002023
2024 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00002025
John McCall550e0c22009-10-21 00:40:46 +00002026 if (!NewDI)
2027 return QualType();
2028
2029 return NewDI->getType();
2030}
2031
2032template<typename Derived>
2033DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2034 if (getDerived().AlreadyTransformed(DI->getType()))
2035 return DI;
2036
2037 TypeLocBuilder TLB;
2038
2039 TypeLoc TL = DI->getTypeLoc();
2040 TLB.reserve(TL.getFullDataSize());
2041
2042 QualType Result = getDerived().TransformType(TLB, TL);
2043 if (Result.isNull())
2044 return 0;
2045
2046 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2047}
2048
2049template<typename Derived>
2050QualType
2051TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2052 switch (T.getTypeLocClass()) {
2053#define ABSTRACT_TYPELOC(CLASS, PARENT)
2054#define TYPELOC(CLASS, PARENT) \
2055 case TypeLoc::CLASS: \
2056 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2057#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00002058 }
Mike Stump11289f42009-09-09 15:08:12 +00002059
John McCall550e0c22009-10-21 00:40:46 +00002060 llvm::llvm_unreachable("unhandled type loc!");
2061 return QualType();
2062}
2063
2064/// FIXME: By default, this routine adds type qualifiers only to types
2065/// that can have qualifiers, and silently suppresses those qualifiers
2066/// that are not permitted (e.g., qualifiers on reference or function
2067/// types). This is the right thing for template instantiation, but
2068/// probably not for other clients.
2069template<typename Derived>
2070QualType
2071TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2072 QualifiedTypeLoc T) {
2073 Qualifiers Quals = T.getType().getQualifiers();
2074
2075 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2076 if (Result.isNull())
2077 return QualType();
2078
2079 // Silently suppress qualifiers if the result type can't be qualified.
2080 // FIXME: this is the right thing for template instantiation, but
2081 // probably not for other clients.
2082 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002083 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002084
John McCall550e0c22009-10-21 00:40:46 +00002085 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2086
2087 TLB.push<QualifiedTypeLoc>(Result);
2088
2089 // No location information to preserve.
2090
2091 return Result;
2092}
2093
2094template <class TyLoc> static inline
2095QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2096 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2097 NewT.setNameLoc(T.getNameLoc());
2098 return T.getType();
2099}
2100
2101// Ugly metaprogramming macros because I couldn't be bothered to make
2102// the equivalent template version work.
2103#define TransformPointerLikeType(TypeClass) do { \
2104 QualType PointeeType \
2105 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2106 if (PointeeType.isNull()) \
2107 return QualType(); \
2108 \
2109 QualType Result = TL.getType(); \
2110 if (getDerived().AlwaysRebuild() || \
2111 PointeeType != TL.getPointeeLoc().getType()) { \
2112 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2113 if (Result.isNull()) \
2114 return QualType(); \
2115 } \
2116 \
2117 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2118 NewT.setSigilLoc(TL.getSigilLoc()); \
2119 \
2120 return Result; \
2121} while(0)
2122
2123// Reference collapsing forces us to transform reference types
2124// differently from the other pointer-like types.
2125#define TransformReferenceType(TypeClass) do { \
2126 QualType PointeeType \
2127 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2128 if (PointeeType.isNull()) \
2129 return QualType(); \
2130 \
2131 QualType Result = TL.getType(); \
2132 if (getDerived().AlwaysRebuild() || \
2133 PointeeType != TL.getPointeeLoc().getType()) { \
2134 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2135 if (Result.isNull()) \
2136 return QualType(); \
2137 } \
2138 \
2139 /* Workaround: rebuild doesn't always change the type */ \
2140 /* FIXME: avoid losing this location information. */ \
2141 if (Result == PointeeType) \
2142 return Result; \
2143 ReferenceTypeLoc NewTL; \
2144 if (isa<LValueReferenceType>(Result)) \
2145 NewTL = TLB.push<LValueReferenceTypeLoc>(Result); \
2146 else \
2147 NewTL = TLB.push<RValueReferenceTypeLoc>(Result); \
2148 NewTL.setSigilLoc(TL.getSigilLoc()); \
2149 return Result; \
2150} while (0)
2151
2152template<typename Derived>
2153QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2154 BuiltinTypeLoc T) {
2155 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002156}
Mike Stump11289f42009-09-09 15:08:12 +00002157
Douglas Gregord6ff3322009-08-04 16:50:30 +00002158template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002159QualType
John McCall550e0c22009-10-21 00:40:46 +00002160TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2161 FixedWidthIntTypeLoc T) {
2162 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002163}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002164
Douglas Gregord6ff3322009-08-04 16:50:30 +00002165template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002166QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2167 ComplexTypeLoc T) {
2168 // FIXME: recurse?
2169 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002170}
Mike Stump11289f42009-09-09 15:08:12 +00002171
Douglas Gregord6ff3322009-08-04 16:50:30 +00002172template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002173QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2174 PointerTypeLoc TL) {
2175 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002176}
Mike Stump11289f42009-09-09 15:08:12 +00002177
2178template<typename Derived>
2179QualType
John McCall550e0c22009-10-21 00:40:46 +00002180TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2181 BlockPointerTypeLoc TL) {
2182 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002183}
2184
Mike Stump11289f42009-09-09 15:08:12 +00002185template<typename Derived>
2186QualType
John McCall550e0c22009-10-21 00:40:46 +00002187TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2188 LValueReferenceTypeLoc TL) {
2189 TransformReferenceType(LValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002190}
2191
Mike Stump11289f42009-09-09 15:08:12 +00002192template<typename Derived>
2193QualType
John McCall550e0c22009-10-21 00:40:46 +00002194TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2195 RValueReferenceTypeLoc TL) {
2196 TransformReferenceType(RValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002197}
Mike Stump11289f42009-09-09 15:08:12 +00002198
Douglas Gregord6ff3322009-08-04 16:50:30 +00002199template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002200QualType
John McCall550e0c22009-10-21 00:40:46 +00002201TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2202 MemberPointerTypeLoc TL) {
2203 MemberPointerType *T = TL.getTypePtr();
2204
2205 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002206 if (PointeeType.isNull())
2207 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002208
John McCall550e0c22009-10-21 00:40:46 +00002209 // TODO: preserve source information for this.
2210 QualType ClassType
2211 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002212 if (ClassType.isNull())
2213 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002214
John McCall550e0c22009-10-21 00:40:46 +00002215 QualType Result = TL.getType();
2216 if (getDerived().AlwaysRebuild() ||
2217 PointeeType != T->getPointeeType() ||
2218 ClassType != QualType(T->getClass(), 0)) {
2219 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2220 if (Result.isNull())
2221 return QualType();
2222 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002223
John McCall550e0c22009-10-21 00:40:46 +00002224 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2225 NewTL.setSigilLoc(TL.getSigilLoc());
2226
2227 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002228}
2229
Mike Stump11289f42009-09-09 15:08:12 +00002230template<typename Derived>
2231QualType
John McCall550e0c22009-10-21 00:40:46 +00002232TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2233 ConstantArrayTypeLoc TL) {
2234 ConstantArrayType *T = TL.getTypePtr();
2235 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002236 if (ElementType.isNull())
2237 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002238
John McCall550e0c22009-10-21 00:40:46 +00002239 QualType Result = TL.getType();
2240 if (getDerived().AlwaysRebuild() ||
2241 ElementType != T->getElementType()) {
2242 Result = getDerived().RebuildConstantArrayType(ElementType,
2243 T->getSizeModifier(),
2244 T->getSize(),
2245 T->getIndexTypeCVRQualifiers());
2246 if (Result.isNull())
2247 return QualType();
2248 }
2249
2250 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2251 NewTL.setLBracketLoc(TL.getLBracketLoc());
2252 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002253
John McCall550e0c22009-10-21 00:40:46 +00002254 Expr *Size = TL.getSizeExpr();
2255 if (Size) {
2256 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2257 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2258 }
2259 NewTL.setSizeExpr(Size);
2260
2261 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002262}
Mike Stump11289f42009-09-09 15:08:12 +00002263
Douglas Gregord6ff3322009-08-04 16:50:30 +00002264template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002265QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002266 TypeLocBuilder &TLB,
2267 IncompleteArrayTypeLoc TL) {
2268 IncompleteArrayType *T = TL.getTypePtr();
2269 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002270 if (ElementType.isNull())
2271 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002272
John McCall550e0c22009-10-21 00:40:46 +00002273 QualType Result = TL.getType();
2274 if (getDerived().AlwaysRebuild() ||
2275 ElementType != T->getElementType()) {
2276 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002277 T->getSizeModifier(),
John McCall550e0c22009-10-21 00:40:46 +00002278 T->getIndexTypeCVRQualifiers());
2279 if (Result.isNull())
2280 return QualType();
2281 }
2282
2283 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2284 NewTL.setLBracketLoc(TL.getLBracketLoc());
2285 NewTL.setRBracketLoc(TL.getRBracketLoc());
2286 NewTL.setSizeExpr(0);
2287
2288 return Result;
2289}
2290
2291template<typename Derived>
2292QualType
2293TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2294 VariableArrayTypeLoc TL) {
2295 VariableArrayType *T = TL.getTypePtr();
2296 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2297 if (ElementType.isNull())
2298 return QualType();
2299
2300 // Array bounds are not potentially evaluated contexts
2301 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2302
2303 Sema::OwningExprResult SizeResult
2304 = getDerived().TransformExpr(T->getSizeExpr());
2305 if (SizeResult.isInvalid())
2306 return QualType();
2307
2308 Expr *Size = static_cast<Expr*>(SizeResult.get());
2309
2310 QualType Result = TL.getType();
2311 if (getDerived().AlwaysRebuild() ||
2312 ElementType != T->getElementType() ||
2313 Size != T->getSizeExpr()) {
2314 Result = getDerived().RebuildVariableArrayType(ElementType,
2315 T->getSizeModifier(),
2316 move(SizeResult),
2317 T->getIndexTypeCVRQualifiers(),
2318 T->getBracketsRange());
2319 if (Result.isNull())
2320 return QualType();
2321 }
2322 else SizeResult.take();
2323
2324 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2325 NewTL.setLBracketLoc(TL.getLBracketLoc());
2326 NewTL.setRBracketLoc(TL.getRBracketLoc());
2327 NewTL.setSizeExpr(Size);
2328
2329 return Result;
2330}
2331
2332template<typename Derived>
2333QualType
2334TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2335 DependentSizedArrayTypeLoc TL) {
2336 DependentSizedArrayType *T = TL.getTypePtr();
2337 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2338 if (ElementType.isNull())
2339 return QualType();
2340
2341 // Array bounds are not potentially evaluated contexts
2342 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2343
2344 Sema::OwningExprResult SizeResult
2345 = getDerived().TransformExpr(T->getSizeExpr());
2346 if (SizeResult.isInvalid())
2347 return QualType();
2348
2349 Expr *Size = static_cast<Expr*>(SizeResult.get());
2350
2351 QualType Result = TL.getType();
2352 if (getDerived().AlwaysRebuild() ||
2353 ElementType != T->getElementType() ||
2354 Size != T->getSizeExpr()) {
2355 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2356 T->getSizeModifier(),
2357 move(SizeResult),
2358 T->getIndexTypeCVRQualifiers(),
2359 T->getBracketsRange());
2360 if (Result.isNull())
2361 return QualType();
2362 }
2363 else SizeResult.take();
2364
2365 // We might have any sort of array type now, but fortunately they
2366 // all have the same location layout.
2367 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2368 NewTL.setLBracketLoc(TL.getLBracketLoc());
2369 NewTL.setRBracketLoc(TL.getRBracketLoc());
2370 NewTL.setSizeExpr(Size);
2371
2372 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002373}
Mike Stump11289f42009-09-09 15:08:12 +00002374
2375template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002376QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002377 TypeLocBuilder &TLB,
2378 DependentSizedExtVectorTypeLoc TL) {
2379 DependentSizedExtVectorType *T = TL.getTypePtr();
2380
2381 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002382 QualType ElementType = getDerived().TransformType(T->getElementType());
2383 if (ElementType.isNull())
2384 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002385
Douglas Gregore922c772009-08-04 22:27:00 +00002386 // Vector sizes are not potentially evaluated contexts
2387 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2388
Douglas Gregord6ff3322009-08-04 16:50:30 +00002389 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2390 if (Size.isInvalid())
2391 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002392
John McCall550e0c22009-10-21 00:40:46 +00002393 QualType Result = TL.getType();
2394 if (getDerived().AlwaysRebuild() ||
John McCall24e7cb62009-10-23 17:55:45 +00002395 ElementType != T->getElementType() ||
2396 Size.get() != T->getSizeExpr()) {
John McCall550e0c22009-10-21 00:40:46 +00002397 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002398 move(Size),
2399 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002400 if (Result.isNull())
2401 return QualType();
2402 }
2403 else Size.take();
2404
2405 // Result might be dependent or not.
2406 if (isa<DependentSizedExtVectorType>(Result)) {
2407 DependentSizedExtVectorTypeLoc NewTL
2408 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2409 NewTL.setNameLoc(TL.getNameLoc());
2410 } else {
2411 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2412 NewTL.setNameLoc(TL.getNameLoc());
2413 }
2414
2415 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002416}
Mike Stump11289f42009-09-09 15:08:12 +00002417
2418template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002419QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2420 VectorTypeLoc TL) {
2421 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002422 QualType ElementType = getDerived().TransformType(T->getElementType());
2423 if (ElementType.isNull())
2424 return QualType();
2425
John McCall550e0c22009-10-21 00:40:46 +00002426 QualType Result = TL.getType();
2427 if (getDerived().AlwaysRebuild() ||
2428 ElementType != T->getElementType()) {
2429 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2430 if (Result.isNull())
2431 return QualType();
2432 }
2433
2434 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2435 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002436
John McCall550e0c22009-10-21 00:40:46 +00002437 return Result;
2438}
2439
2440template<typename Derived>
2441QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2442 ExtVectorTypeLoc TL) {
2443 VectorType *T = TL.getTypePtr();
2444 QualType ElementType = getDerived().TransformType(T->getElementType());
2445 if (ElementType.isNull())
2446 return QualType();
2447
2448 QualType Result = TL.getType();
2449 if (getDerived().AlwaysRebuild() ||
2450 ElementType != T->getElementType()) {
2451 Result = getDerived().RebuildExtVectorType(ElementType,
2452 T->getNumElements(),
2453 /*FIXME*/ SourceLocation());
2454 if (Result.isNull())
2455 return QualType();
2456 }
2457
2458 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2459 NewTL.setNameLoc(TL.getNameLoc());
2460
2461 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002462}
Mike Stump11289f42009-09-09 15:08:12 +00002463
2464template<typename Derived>
2465QualType
John McCall550e0c22009-10-21 00:40:46 +00002466TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2467 FunctionProtoTypeLoc TL) {
2468 FunctionProtoType *T = TL.getTypePtr();
2469 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002470 if (ResultType.isNull())
2471 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002472
John McCall550e0c22009-10-21 00:40:46 +00002473 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002474 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002475 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2476 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2477 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002478
John McCall550e0c22009-10-21 00:40:46 +00002479 QualType NewType;
2480 ParmVarDecl *NewParm;
2481
2482 if (OldParm) {
2483 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2484 assert(OldDI->getType() == T->getArgType(i));
2485
2486 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2487 if (!NewDI)
2488 return QualType();
2489
2490 if (NewDI == OldDI)
2491 NewParm = OldParm;
2492 else
2493 NewParm = ParmVarDecl::Create(SemaRef.Context,
2494 OldParm->getDeclContext(),
2495 OldParm->getLocation(),
2496 OldParm->getIdentifier(),
2497 NewDI->getType(),
2498 NewDI,
2499 OldParm->getStorageClass(),
2500 /* DefArg */ NULL);
2501 NewType = NewParm->getType();
2502
2503 // Deal with the possibility that we don't have a parameter
2504 // declaration for this parameter.
2505 } else {
2506 NewParm = 0;
2507
2508 QualType OldType = T->getArgType(i);
2509 NewType = getDerived().TransformType(OldType);
2510 if (NewType.isNull())
2511 return QualType();
2512 }
2513
2514 ParamTypes.push_back(NewType);
2515 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002516 }
Mike Stump11289f42009-09-09 15:08:12 +00002517
John McCall550e0c22009-10-21 00:40:46 +00002518 QualType Result = TL.getType();
2519 if (getDerived().AlwaysRebuild() ||
2520 ResultType != T->getResultType() ||
2521 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2522 Result = getDerived().RebuildFunctionProtoType(ResultType,
2523 ParamTypes.data(),
2524 ParamTypes.size(),
2525 T->isVariadic(),
2526 T->getTypeQuals());
2527 if (Result.isNull())
2528 return QualType();
2529 }
Mike Stump11289f42009-09-09 15:08:12 +00002530
John McCall550e0c22009-10-21 00:40:46 +00002531 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2532 NewTL.setLParenLoc(TL.getLParenLoc());
2533 NewTL.setRParenLoc(TL.getRParenLoc());
2534 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2535 NewTL.setArg(i, ParamDecls[i]);
2536
2537 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002538}
Mike Stump11289f42009-09-09 15:08:12 +00002539
Douglas Gregord6ff3322009-08-04 16:50:30 +00002540template<typename Derived>
2541QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002542 TypeLocBuilder &TLB,
2543 FunctionNoProtoTypeLoc TL) {
2544 FunctionNoProtoType *T = TL.getTypePtr();
2545 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2546 if (ResultType.isNull())
2547 return QualType();
2548
2549 QualType Result = TL.getType();
2550 if (getDerived().AlwaysRebuild() ||
2551 ResultType != T->getResultType())
2552 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2553
2554 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2555 NewTL.setLParenLoc(TL.getLParenLoc());
2556 NewTL.setRParenLoc(TL.getRParenLoc());
2557
2558 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002559}
Mike Stump11289f42009-09-09 15:08:12 +00002560
Douglas Gregord6ff3322009-08-04 16:50:30 +00002561template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002562QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2563 TypedefTypeLoc TL) {
2564 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002565 TypedefDecl *Typedef
2566 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2567 if (!Typedef)
2568 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002569
John McCall550e0c22009-10-21 00:40:46 +00002570 QualType Result = TL.getType();
2571 if (getDerived().AlwaysRebuild() ||
2572 Typedef != T->getDecl()) {
2573 Result = getDerived().RebuildTypedefType(Typedef);
2574 if (Result.isNull())
2575 return QualType();
2576 }
Mike Stump11289f42009-09-09 15:08:12 +00002577
John McCall550e0c22009-10-21 00:40:46 +00002578 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2579 NewTL.setNameLoc(TL.getNameLoc());
2580
2581 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002582}
Mike Stump11289f42009-09-09 15:08:12 +00002583
Douglas Gregord6ff3322009-08-04 16:50:30 +00002584template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002585QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2586 TypeOfExprTypeLoc TL) {
2587 TypeOfExprType *T = TL.getTypePtr();
2588
Douglas Gregore922c772009-08-04 22:27:00 +00002589 // typeof expressions are not potentially evaluated contexts
2590 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002591
Douglas Gregord6ff3322009-08-04 16:50:30 +00002592 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2593 if (E.isInvalid())
2594 return QualType();
2595
John McCall550e0c22009-10-21 00:40:46 +00002596 QualType Result = TL.getType();
2597 if (getDerived().AlwaysRebuild() ||
2598 E.get() != T->getUnderlyingExpr()) {
2599 Result = getDerived().RebuildTypeOfExprType(move(E));
2600 if (Result.isNull())
2601 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002602 }
John McCall550e0c22009-10-21 00:40:46 +00002603 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002604
John McCall550e0c22009-10-21 00:40:46 +00002605 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2606 NewTL.setNameLoc(TL.getNameLoc());
2607
2608 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002609}
Mike Stump11289f42009-09-09 15:08:12 +00002610
2611template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002612QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2613 TypeOfTypeLoc TL) {
2614 TypeOfType *T = TL.getTypePtr();
2615
2616 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002617 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2618 if (Underlying.isNull())
2619 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002620
John McCall550e0c22009-10-21 00:40:46 +00002621 QualType Result = TL.getType();
2622 if (getDerived().AlwaysRebuild() ||
2623 Underlying != T->getUnderlyingType()) {
2624 Result = getDerived().RebuildTypeOfType(Underlying);
2625 if (Result.isNull())
2626 return QualType();
2627 }
Mike Stump11289f42009-09-09 15:08:12 +00002628
John McCall550e0c22009-10-21 00:40:46 +00002629 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2630 NewTL.setNameLoc(TL.getNameLoc());
2631
2632 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002633}
Mike Stump11289f42009-09-09 15:08:12 +00002634
2635template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002636QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2637 DecltypeTypeLoc TL) {
2638 DecltypeType *T = TL.getTypePtr();
2639
Douglas Gregore922c772009-08-04 22:27:00 +00002640 // decltype expressions are not potentially evaluated contexts
2641 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002642
Douglas Gregord6ff3322009-08-04 16:50:30 +00002643 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2644 if (E.isInvalid())
2645 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002646
John McCall550e0c22009-10-21 00:40:46 +00002647 QualType Result = TL.getType();
2648 if (getDerived().AlwaysRebuild() ||
2649 E.get() != T->getUnderlyingExpr()) {
2650 Result = getDerived().RebuildDecltypeType(move(E));
2651 if (Result.isNull())
2652 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002653 }
John McCall550e0c22009-10-21 00:40:46 +00002654 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002655
John McCall550e0c22009-10-21 00:40:46 +00002656 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2657 NewTL.setNameLoc(TL.getNameLoc());
2658
2659 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002660}
2661
2662template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002663QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2664 RecordTypeLoc TL) {
2665 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002666 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002667 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002668 if (!Record)
2669 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002670
John McCall550e0c22009-10-21 00:40:46 +00002671 QualType Result = TL.getType();
2672 if (getDerived().AlwaysRebuild() ||
2673 Record != T->getDecl()) {
2674 Result = getDerived().RebuildRecordType(Record);
2675 if (Result.isNull())
2676 return QualType();
2677 }
Mike Stump11289f42009-09-09 15:08:12 +00002678
John McCall550e0c22009-10-21 00:40:46 +00002679 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2680 NewTL.setNameLoc(TL.getNameLoc());
2681
2682 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002683}
Mike Stump11289f42009-09-09 15:08:12 +00002684
2685template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002686QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2687 EnumTypeLoc TL) {
2688 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002689 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002690 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002691 if (!Enum)
2692 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002693
John McCall550e0c22009-10-21 00:40:46 +00002694 QualType Result = TL.getType();
2695 if (getDerived().AlwaysRebuild() ||
2696 Enum != T->getDecl()) {
2697 Result = getDerived().RebuildEnumType(Enum);
2698 if (Result.isNull())
2699 return QualType();
2700 }
Mike Stump11289f42009-09-09 15:08:12 +00002701
John McCall550e0c22009-10-21 00:40:46 +00002702 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2703 NewTL.setNameLoc(TL.getNameLoc());
2704
2705 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002706}
John McCallfcc33b02009-09-05 00:15:47 +00002707
2708template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002709QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2710 ElaboratedTypeLoc TL) {
2711 ElaboratedType *T = TL.getTypePtr();
2712
2713 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002714 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2715 if (Underlying.isNull())
2716 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002717
John McCall550e0c22009-10-21 00:40:46 +00002718 QualType Result = TL.getType();
2719 if (getDerived().AlwaysRebuild() ||
2720 Underlying != T->getUnderlyingType()) {
2721 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2722 if (Result.isNull())
2723 return QualType();
2724 }
Mike Stump11289f42009-09-09 15:08:12 +00002725
John McCall550e0c22009-10-21 00:40:46 +00002726 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2727 NewTL.setNameLoc(TL.getNameLoc());
2728
2729 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002730}
Mike Stump11289f42009-09-09 15:08:12 +00002731
2732
Douglas Gregord6ff3322009-08-04 16:50:30 +00002733template<typename Derived>
2734QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002735 TypeLocBuilder &TLB,
2736 TemplateTypeParmTypeLoc TL) {
2737 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002738}
2739
Mike Stump11289f42009-09-09 15:08:12 +00002740template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002741QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002742 TypeLocBuilder &TLB,
2743 SubstTemplateTypeParmTypeLoc TL) {
2744 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002745}
2746
2747template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002748inline QualType
2749TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002750 TypeLocBuilder &TLB,
2751 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002752 return TransformTemplateSpecializationType(TLB, TL, QualType());
2753}
John McCall550e0c22009-10-21 00:40:46 +00002754
John McCall0ad16662009-10-29 08:12:44 +00002755template<typename Derived>
2756QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2757 const TemplateSpecializationType *TST,
2758 QualType ObjectType) {
2759 // FIXME: this entire method is a temporary workaround; callers
2760 // should be rewritten to provide real type locs.
John McCall550e0c22009-10-21 00:40:46 +00002761
John McCall0ad16662009-10-29 08:12:44 +00002762 // Fake up a TemplateSpecializationTypeLoc.
2763 TypeLocBuilder TLB;
2764 TemplateSpecializationTypeLoc TL
2765 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2766
2767 TL.setTemplateNameLoc(getDerived().getBaseLocation());
2768 TL.setLAngleLoc(SourceLocation());
2769 TL.setRAngleLoc(SourceLocation());
2770 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2771 const TemplateArgument &TA = TST->getArg(i);
2772 TemplateArgumentLoc TAL;
2773 getDerived().InventTemplateArgumentLoc(TA, TAL);
2774 TL.setArgLocInfo(i, TAL.getLocInfo());
2775 }
2776
2777 TypeLocBuilder IgnoredTLB;
2778 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +00002779}
2780
2781template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002782QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00002783 TypeLocBuilder &TLB,
2784 TemplateSpecializationTypeLoc TL,
2785 QualType ObjectType) {
2786 const TemplateSpecializationType *T = TL.getTypePtr();
2787
Mike Stump11289f42009-09-09 15:08:12 +00002788 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002789 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002790 if (Template.isNull())
2791 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002792
John McCall0ad16662009-10-29 08:12:44 +00002793 llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
2794 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
2795 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
2796 NewTemplateArgs[i]))
Douglas Gregord6ff3322009-08-04 16:50:30 +00002797 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002798
John McCall0ad16662009-10-29 08:12:44 +00002799 // FIXME: maybe don't rebuild if all the template arguments are the same.
2800
2801 QualType Result =
2802 getDerived().RebuildTemplateSpecializationType(Template,
2803 TL.getTemplateNameLoc(),
2804 TL.getLAngleLoc(),
2805 NewTemplateArgs.data(),
2806 NewTemplateArgs.size(),
2807 TL.getRAngleLoc());
2808
2809 if (!Result.isNull()) {
2810 TemplateSpecializationTypeLoc NewTL
2811 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2812 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2813 NewTL.setLAngleLoc(TL.getLAngleLoc());
2814 NewTL.setRAngleLoc(TL.getRAngleLoc());
2815 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2816 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002817 }
Mike Stump11289f42009-09-09 15:08:12 +00002818
John McCall0ad16662009-10-29 08:12:44 +00002819 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002820}
Mike Stump11289f42009-09-09 15:08:12 +00002821
2822template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002823QualType
2824TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2825 QualifiedNameTypeLoc TL) {
2826 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002827 NestedNameSpecifier *NNS
2828 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2829 SourceRange());
2830 if (!NNS)
2831 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002832
Douglas Gregord6ff3322009-08-04 16:50:30 +00002833 QualType Named = getDerived().TransformType(T->getNamedType());
2834 if (Named.isNull())
2835 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002836
John McCall550e0c22009-10-21 00:40:46 +00002837 QualType Result = TL.getType();
2838 if (getDerived().AlwaysRebuild() ||
2839 NNS != T->getQualifier() ||
2840 Named != T->getNamedType()) {
2841 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2842 if (Result.isNull())
2843 return QualType();
2844 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002845
John McCall550e0c22009-10-21 00:40:46 +00002846 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2847 NewTL.setNameLoc(TL.getNameLoc());
2848
2849 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002850}
Mike Stump11289f42009-09-09 15:08:12 +00002851
2852template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002853QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2854 TypenameTypeLoc TL) {
2855 TypenameType *T = TL.getTypePtr();
John McCall0ad16662009-10-29 08:12:44 +00002856
2857 /* FIXME: preserve source information better than this */
2858 SourceRange SR(TL.getNameLoc());
2859
Douglas Gregord6ff3322009-08-04 16:50:30 +00002860 NestedNameSpecifier *NNS
John McCall0ad16662009-10-29 08:12:44 +00002861 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002862 if (!NNS)
2863 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002864
John McCall550e0c22009-10-21 00:40:46 +00002865 QualType Result;
2866
Douglas Gregord6ff3322009-08-04 16:50:30 +00002867 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002868 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002869 = getDerived().TransformType(QualType(TemplateId, 0));
2870 if (NewTemplateId.isNull())
2871 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002872
Douglas Gregord6ff3322009-08-04 16:50:30 +00002873 if (!getDerived().AlwaysRebuild() &&
2874 NNS == T->getQualifier() &&
2875 NewTemplateId == QualType(TemplateId, 0))
2876 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002877
John McCall550e0c22009-10-21 00:40:46 +00002878 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2879 } else {
John McCall0ad16662009-10-29 08:12:44 +00002880 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002881 }
John McCall550e0c22009-10-21 00:40:46 +00002882 if (Result.isNull())
2883 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002884
John McCall550e0c22009-10-21 00:40:46 +00002885 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2886 NewTL.setNameLoc(TL.getNameLoc());
2887
2888 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002889}
Mike Stump11289f42009-09-09 15:08:12 +00002890
Douglas Gregord6ff3322009-08-04 16:50:30 +00002891template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002892QualType
2893TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2894 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002895 assert(false && "TransformObjCInterfaceType unimplemented");
2896 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002897}
Mike Stump11289f42009-09-09 15:08:12 +00002898
2899template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002900QualType
2901TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2902 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002903 assert(false && "TransformObjCObjectPointerType unimplemented");
2904 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002905}
2906
Douglas Gregord6ff3322009-08-04 16:50:30 +00002907//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002908// Statement transformation
2909//===----------------------------------------------------------------------===//
2910template<typename Derived>
2911Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002912TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2913 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002914}
2915
2916template<typename Derived>
2917Sema::OwningStmtResult
2918TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2919 return getDerived().TransformCompoundStmt(S, false);
2920}
2921
2922template<typename Derived>
2923Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002924TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002925 bool IsStmtExpr) {
2926 bool SubStmtChanged = false;
2927 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2928 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2929 B != BEnd; ++B) {
2930 OwningStmtResult Result = getDerived().TransformStmt(*B);
2931 if (Result.isInvalid())
2932 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002933
Douglas Gregorebe10102009-08-20 07:17:43 +00002934 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2935 Statements.push_back(Result.takeAs<Stmt>());
2936 }
Mike Stump11289f42009-09-09 15:08:12 +00002937
Douglas Gregorebe10102009-08-20 07:17:43 +00002938 if (!getDerived().AlwaysRebuild() &&
2939 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00002940 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002941
2942 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2943 move_arg(Statements),
2944 S->getRBracLoc(),
2945 IsStmtExpr);
2946}
Mike Stump11289f42009-09-09 15:08:12 +00002947
Douglas Gregorebe10102009-08-20 07:17:43 +00002948template<typename Derived>
2949Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002950TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002951 // The case value expressions are not potentially evaluated.
2952 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002953
Douglas Gregorebe10102009-08-20 07:17:43 +00002954 // Transform the left-hand case value.
2955 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2956 if (LHS.isInvalid())
2957 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002958
Douglas Gregorebe10102009-08-20 07:17:43 +00002959 // Transform the right-hand case value (for the GNU case-range extension).
2960 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2961 if (RHS.isInvalid())
2962 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002963
Douglas Gregorebe10102009-08-20 07:17:43 +00002964 // Build the case statement.
2965 // Case statements are always rebuilt so that they will attached to their
2966 // transformed switch statement.
2967 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2968 move(LHS),
2969 S->getEllipsisLoc(),
2970 move(RHS),
2971 S->getColonLoc());
2972 if (Case.isInvalid())
2973 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002974
Douglas Gregorebe10102009-08-20 07:17:43 +00002975 // Transform the statement following the case
2976 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2977 if (SubStmt.isInvalid())
2978 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002979
Douglas Gregorebe10102009-08-20 07:17:43 +00002980 // Attach the body to the case statement
2981 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2982}
2983
2984template<typename Derived>
2985Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002986TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002987 // Transform the statement following the default case
2988 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2989 if (SubStmt.isInvalid())
2990 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002991
Douglas Gregorebe10102009-08-20 07:17:43 +00002992 // Default statements are always rebuilt
2993 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2994 move(SubStmt));
2995}
Mike Stump11289f42009-09-09 15:08:12 +00002996
Douglas Gregorebe10102009-08-20 07:17:43 +00002997template<typename Derived>
2998Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002999TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003000 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3001 if (SubStmt.isInvalid())
3002 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003003
Douglas Gregorebe10102009-08-20 07:17:43 +00003004 // FIXME: Pass the real colon location in.
3005 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3006 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3007 move(SubStmt));
3008}
Mike Stump11289f42009-09-09 15:08:12 +00003009
Douglas Gregorebe10102009-08-20 07:17:43 +00003010template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003011Sema::OwningStmtResult
3012TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003013 // Transform the condition
3014 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3015 if (Cond.isInvalid())
3016 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003017
Douglas Gregorebe10102009-08-20 07:17:43 +00003018 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003019
Douglas Gregorebe10102009-08-20 07:17:43 +00003020 // Transform the "then" branch.
3021 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3022 if (Then.isInvalid())
3023 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003024
Douglas Gregorebe10102009-08-20 07:17:43 +00003025 // Transform the "else" branch.
3026 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3027 if (Else.isInvalid())
3028 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003029
Douglas Gregorebe10102009-08-20 07:17:43 +00003030 if (!getDerived().AlwaysRebuild() &&
3031 FullCond->get() == S->getCond() &&
3032 Then.get() == S->getThen() &&
3033 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00003034 return SemaRef.Owned(S->Retain());
3035
Douglas Gregorebe10102009-08-20 07:17:43 +00003036 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00003037 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00003038}
3039
3040template<typename Derived>
3041Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003042TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003043 // Transform the condition.
3044 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3045 if (Cond.isInvalid())
3046 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003047
Douglas Gregorebe10102009-08-20 07:17:43 +00003048 // Rebuild the switch statement.
3049 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3050 if (Switch.isInvalid())
3051 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003052
Douglas Gregorebe10102009-08-20 07:17:43 +00003053 // Transform the body of the switch statement.
3054 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3055 if (Body.isInvalid())
3056 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003057
Douglas Gregorebe10102009-08-20 07:17:43 +00003058 // Complete the switch statement.
3059 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3060 move(Body));
3061}
Mike Stump11289f42009-09-09 15:08:12 +00003062
Douglas Gregorebe10102009-08-20 07:17:43 +00003063template<typename Derived>
3064Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003065TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003066 // Transform the condition
3067 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3068 if (Cond.isInvalid())
3069 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003070
Douglas Gregorebe10102009-08-20 07:17:43 +00003071 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003072
Douglas Gregorebe10102009-08-20 07:17:43 +00003073 // Transform the body
3074 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3075 if (Body.isInvalid())
3076 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003077
Douglas Gregorebe10102009-08-20 07:17:43 +00003078 if (!getDerived().AlwaysRebuild() &&
3079 FullCond->get() == S->getCond() &&
3080 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003081 return SemaRef.Owned(S->Retain());
3082
Douglas Gregorebe10102009-08-20 07:17:43 +00003083 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3084}
Mike Stump11289f42009-09-09 15:08:12 +00003085
Douglas Gregorebe10102009-08-20 07:17:43 +00003086template<typename Derived>
3087Sema::OwningStmtResult
3088TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3089 // Transform the condition
3090 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3091 if (Cond.isInvalid())
3092 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003093
Douglas Gregorebe10102009-08-20 07:17:43 +00003094 // Transform the body
3095 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3096 if (Body.isInvalid())
3097 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003098
Douglas Gregorebe10102009-08-20 07:17:43 +00003099 if (!getDerived().AlwaysRebuild() &&
3100 Cond.get() == S->getCond() &&
3101 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003102 return SemaRef.Owned(S->Retain());
3103
Douglas Gregorebe10102009-08-20 07:17:43 +00003104 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3105 /*FIXME:*/S->getWhileLoc(), move(Cond),
3106 S->getRParenLoc());
3107}
Mike Stump11289f42009-09-09 15:08:12 +00003108
Douglas Gregorebe10102009-08-20 07:17:43 +00003109template<typename Derived>
3110Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003111TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003112 // Transform the initialization statement
3113 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3114 if (Init.isInvalid())
3115 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003116
Douglas Gregorebe10102009-08-20 07:17:43 +00003117 // Transform the condition
3118 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3119 if (Cond.isInvalid())
3120 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003121
Douglas Gregorebe10102009-08-20 07:17:43 +00003122 // Transform the increment
3123 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3124 if (Inc.isInvalid())
3125 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003126
Douglas Gregorebe10102009-08-20 07:17:43 +00003127 // Transform the body
3128 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3129 if (Body.isInvalid())
3130 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003131
Douglas Gregorebe10102009-08-20 07:17:43 +00003132 if (!getDerived().AlwaysRebuild() &&
3133 Init.get() == S->getInit() &&
3134 Cond.get() == S->getCond() &&
3135 Inc.get() == S->getInc() &&
3136 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003137 return SemaRef.Owned(S->Retain());
3138
Douglas Gregorebe10102009-08-20 07:17:43 +00003139 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3140 move(Init), move(Cond), move(Inc),
3141 S->getRParenLoc(), move(Body));
3142}
3143
3144template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003145Sema::OwningStmtResult
3146TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003147 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003148 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003149 S->getLabel());
3150}
3151
3152template<typename Derived>
3153Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003154TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003155 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3156 if (Target.isInvalid())
3157 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003158
Douglas Gregorebe10102009-08-20 07:17:43 +00003159 if (!getDerived().AlwaysRebuild() &&
3160 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003161 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003162
3163 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3164 move(Target));
3165}
3166
3167template<typename Derived>
3168Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003169TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3170 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003171}
Mike Stump11289f42009-09-09 15:08:12 +00003172
Douglas Gregorebe10102009-08-20 07:17:43 +00003173template<typename Derived>
3174Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003175TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3176 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003177}
Mike Stump11289f42009-09-09 15:08:12 +00003178
Douglas Gregorebe10102009-08-20 07:17:43 +00003179template<typename Derived>
3180Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003181TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003182 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3183 if (Result.isInvalid())
3184 return SemaRef.StmtError();
3185
Mike Stump11289f42009-09-09 15:08:12 +00003186 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003187 // to tell whether the return type of the function has changed.
3188 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3189}
Mike Stump11289f42009-09-09 15:08:12 +00003190
Douglas Gregorebe10102009-08-20 07:17:43 +00003191template<typename Derived>
3192Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003193TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003194 bool DeclChanged = false;
3195 llvm::SmallVector<Decl *, 4> Decls;
3196 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3197 D != DEnd; ++D) {
3198 Decl *Transformed = getDerived().TransformDefinition(*D);
3199 if (!Transformed)
3200 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003201
Douglas Gregorebe10102009-08-20 07:17:43 +00003202 if (Transformed != *D)
3203 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003204
Douglas Gregorebe10102009-08-20 07:17:43 +00003205 Decls.push_back(Transformed);
3206 }
Mike Stump11289f42009-09-09 15:08:12 +00003207
Douglas Gregorebe10102009-08-20 07:17:43 +00003208 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003209 return SemaRef.Owned(S->Retain());
3210
3211 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003212 S->getStartLoc(), S->getEndLoc());
3213}
Mike Stump11289f42009-09-09 15:08:12 +00003214
Douglas Gregorebe10102009-08-20 07:17:43 +00003215template<typename Derived>
3216Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003217TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003218 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003219 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003220}
3221
3222template<typename Derived>
3223Sema::OwningStmtResult
3224TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3225 // FIXME: Implement!
3226 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003227 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003228}
3229
3230
3231template<typename Derived>
3232Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003233TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003234 // FIXME: Implement this
3235 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003236 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003237}
Mike Stump11289f42009-09-09 15:08:12 +00003238
Douglas Gregorebe10102009-08-20 07:17:43 +00003239template<typename Derived>
3240Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003241TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003242 // FIXME: Implement this
3243 assert(false && "Cannot transform an Objective-C @catch statement");
3244 return SemaRef.Owned(S->Retain());
3245}
Mike Stump11289f42009-09-09 15:08:12 +00003246
Douglas Gregorebe10102009-08-20 07:17:43 +00003247template<typename Derived>
3248Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003249TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003250 // FIXME: Implement this
3251 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003252 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003253}
Mike Stump11289f42009-09-09 15:08:12 +00003254
Douglas Gregorebe10102009-08-20 07:17:43 +00003255template<typename Derived>
3256Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003257TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003258 // FIXME: Implement this
3259 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003260 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003261}
Mike Stump11289f42009-09-09 15:08:12 +00003262
Douglas Gregorebe10102009-08-20 07:17:43 +00003263template<typename Derived>
3264Sema::OwningStmtResult
3265TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003266 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003267 // FIXME: Implement this
3268 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003269 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003270}
3271
3272template<typename Derived>
3273Sema::OwningStmtResult
3274TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003275 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003276 // FIXME: Implement this
3277 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003278 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003279}
3280
3281
3282template<typename Derived>
3283Sema::OwningStmtResult
3284TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3285 // Transform the exception declaration, if any.
3286 VarDecl *Var = 0;
3287 if (S->getExceptionDecl()) {
3288 VarDecl *ExceptionDecl = S->getExceptionDecl();
3289 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3290 ExceptionDecl->getDeclName());
3291
3292 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3293 if (T.isNull())
3294 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003295
Douglas Gregorebe10102009-08-20 07:17:43 +00003296 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3297 T,
3298 ExceptionDecl->getDeclaratorInfo(),
3299 ExceptionDecl->getIdentifier(),
3300 ExceptionDecl->getLocation(),
3301 /*FIXME: Inaccurate*/
3302 SourceRange(ExceptionDecl->getLocation()));
3303 if (!Var || Var->isInvalidDecl()) {
3304 if (Var)
3305 Var->Destroy(SemaRef.Context);
3306 return SemaRef.StmtError();
3307 }
3308 }
Mike Stump11289f42009-09-09 15:08:12 +00003309
Douglas Gregorebe10102009-08-20 07:17:43 +00003310 // Transform the actual exception handler.
3311 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3312 if (Handler.isInvalid()) {
3313 if (Var)
3314 Var->Destroy(SemaRef.Context);
3315 return SemaRef.StmtError();
3316 }
Mike Stump11289f42009-09-09 15:08:12 +00003317
Douglas Gregorebe10102009-08-20 07:17:43 +00003318 if (!getDerived().AlwaysRebuild() &&
3319 !Var &&
3320 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003321 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003322
3323 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3324 Var,
3325 move(Handler));
3326}
Mike Stump11289f42009-09-09 15:08:12 +00003327
Douglas Gregorebe10102009-08-20 07:17:43 +00003328template<typename Derived>
3329Sema::OwningStmtResult
3330TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3331 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003332 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003333 = getDerived().TransformCompoundStmt(S->getTryBlock());
3334 if (TryBlock.isInvalid())
3335 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003336
Douglas Gregorebe10102009-08-20 07:17:43 +00003337 // Transform the handlers.
3338 bool HandlerChanged = false;
3339 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3340 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003341 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003342 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3343 if (Handler.isInvalid())
3344 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003345
Douglas Gregorebe10102009-08-20 07:17:43 +00003346 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3347 Handlers.push_back(Handler.takeAs<Stmt>());
3348 }
Mike Stump11289f42009-09-09 15:08:12 +00003349
Douglas Gregorebe10102009-08-20 07:17:43 +00003350 if (!getDerived().AlwaysRebuild() &&
3351 TryBlock.get() == S->getTryBlock() &&
3352 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003353 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003354
3355 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003356 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003357}
Mike Stump11289f42009-09-09 15:08:12 +00003358
Douglas Gregorebe10102009-08-20 07:17:43 +00003359//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003360// Expression transformation
3361//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003362template<typename Derived>
3363Sema::OwningExprResult
3364TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
3365 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003366}
Mike Stump11289f42009-09-09 15:08:12 +00003367
3368template<typename Derived>
3369Sema::OwningExprResult
3370TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003371 NestedNameSpecifier *Qualifier = 0;
3372 if (E->getQualifier()) {
3373 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3374 E->getQualifierRange());
3375 if (!Qualifier)
3376 return SemaRef.ExprError();
3377 }
3378
Mike Stump11289f42009-09-09 15:08:12 +00003379 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003380 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3381 if (!ND)
3382 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003383
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003384 if (!getDerived().AlwaysRebuild() &&
3385 Qualifier == E->getQualifier() &&
3386 ND == E->getDecl() &&
3387 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003388 return SemaRef.Owned(E->Retain());
3389
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003390 // FIXME: We're losing the explicit template arguments in this transformation.
3391
John McCall0ad16662009-10-29 08:12:44 +00003392 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003393 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00003394 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3395 TransArgs[I]))
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003396 return SemaRef.ExprError();
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003397 }
3398
3399 // FIXME: Pass the qualifier/qualifier range along.
3400 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
3401 ND, E->getLocation());
Douglas Gregora16548e2009-08-11 05:31:07 +00003402}
Mike Stump11289f42009-09-09 15:08:12 +00003403
Douglas Gregora16548e2009-08-11 05:31:07 +00003404template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003405Sema::OwningExprResult
3406TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
3407 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003408}
Mike Stump11289f42009-09-09 15:08:12 +00003409
Douglas Gregora16548e2009-08-11 05:31:07 +00003410template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003411Sema::OwningExprResult
3412TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
3413 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003414}
Mike Stump11289f42009-09-09 15:08:12 +00003415
Douglas Gregora16548e2009-08-11 05:31:07 +00003416template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003417Sema::OwningExprResult
3418TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
3419 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003420}
Mike Stump11289f42009-09-09 15:08:12 +00003421
Douglas Gregora16548e2009-08-11 05:31:07 +00003422template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003423Sema::OwningExprResult
3424TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
3425 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003426}
Mike Stump11289f42009-09-09 15:08:12 +00003427
Douglas Gregora16548e2009-08-11 05:31:07 +00003428template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003429Sema::OwningExprResult
3430TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
3431 return SemaRef.Owned(E->Retain());
3432}
3433
3434template<typename Derived>
3435Sema::OwningExprResult
3436TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003437 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3438 if (SubExpr.isInvalid())
3439 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003440
Douglas Gregora16548e2009-08-11 05:31:07 +00003441 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003442 return SemaRef.Owned(E->Retain());
3443
3444 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003445 E->getRParen());
3446}
3447
Mike Stump11289f42009-09-09 15:08:12 +00003448template<typename Derived>
3449Sema::OwningExprResult
3450TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003451 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3452 if (SubExpr.isInvalid())
3453 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003454
Douglas Gregora16548e2009-08-11 05:31:07 +00003455 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003456 return SemaRef.Owned(E->Retain());
3457
Douglas Gregora16548e2009-08-11 05:31:07 +00003458 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3459 E->getOpcode(),
3460 move(SubExpr));
3461}
Mike Stump11289f42009-09-09 15:08:12 +00003462
Douglas Gregora16548e2009-08-11 05:31:07 +00003463template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003464Sema::OwningExprResult
3465TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003466 if (E->isArgumentType()) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003467 TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
3468
Douglas Gregora16548e2009-08-11 05:31:07 +00003469 QualType T = getDerived().TransformType(E->getArgumentType());
3470 if (T.isNull())
3471 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003472
Douglas Gregora16548e2009-08-11 05:31:07 +00003473 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3474 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003475
3476 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3477 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003478 E->getSourceRange());
3479 }
Mike Stump11289f42009-09-09 15:08:12 +00003480
Douglas Gregora16548e2009-08-11 05:31:07 +00003481 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003482 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003483 // C++0x [expr.sizeof]p1:
3484 // The operand is either an expression, which is an unevaluated operand
3485 // [...]
3486 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003487
Douglas Gregora16548e2009-08-11 05:31:07 +00003488 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3489 if (SubExpr.isInvalid())
3490 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003491
Douglas Gregora16548e2009-08-11 05:31:07 +00003492 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3493 return SemaRef.Owned(E->Retain());
3494 }
Mike Stump11289f42009-09-09 15:08:12 +00003495
Douglas Gregora16548e2009-08-11 05:31:07 +00003496 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3497 E->isSizeOf(),
3498 E->getSourceRange());
3499}
Mike Stump11289f42009-09-09 15:08:12 +00003500
Douglas Gregora16548e2009-08-11 05:31:07 +00003501template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003502Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003503TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3504 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3505 if (LHS.isInvalid())
3506 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003507
Douglas Gregora16548e2009-08-11 05:31:07 +00003508 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3509 if (RHS.isInvalid())
3510 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003511
3512
Douglas Gregora16548e2009-08-11 05:31:07 +00003513 if (!getDerived().AlwaysRebuild() &&
3514 LHS.get() == E->getLHS() &&
3515 RHS.get() == E->getRHS())
3516 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003517
Douglas Gregora16548e2009-08-11 05:31:07 +00003518 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3519 /*FIXME:*/E->getLHS()->getLocStart(),
3520 move(RHS),
3521 E->getRBracketLoc());
3522}
Mike Stump11289f42009-09-09 15:08:12 +00003523
3524template<typename Derived>
3525Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003526TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3527 // Transform the callee.
3528 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3529 if (Callee.isInvalid())
3530 return SemaRef.ExprError();
3531
3532 // Transform arguments.
3533 bool ArgChanged = false;
3534 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3535 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3536 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3537 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3538 if (Arg.isInvalid())
3539 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003540
Douglas Gregora16548e2009-08-11 05:31:07 +00003541 // FIXME: Wrong source location information for the ','.
3542 FakeCommaLocs.push_back(
3543 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003544
3545 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003546 Args.push_back(Arg.takeAs<Expr>());
3547 }
Mike Stump11289f42009-09-09 15:08:12 +00003548
Douglas Gregora16548e2009-08-11 05:31:07 +00003549 if (!getDerived().AlwaysRebuild() &&
3550 Callee.get() == E->getCallee() &&
3551 !ArgChanged)
3552 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003553
Douglas Gregora16548e2009-08-11 05:31:07 +00003554 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003555 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003556 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3557 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3558 move_arg(Args),
3559 FakeCommaLocs.data(),
3560 E->getRParenLoc());
3561}
Mike Stump11289f42009-09-09 15:08:12 +00003562
3563template<typename Derived>
3564Sema::OwningExprResult
3565TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003566 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3567 if (Base.isInvalid())
3568 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003569
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003570 NestedNameSpecifier *Qualifier = 0;
3571 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003572 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003573 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3574 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003575 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003576 return SemaRef.ExprError();
3577 }
Mike Stump11289f42009-09-09 15:08:12 +00003578
3579 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003580 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3581 if (!Member)
3582 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003583
Douglas Gregora16548e2009-08-11 05:31:07 +00003584 if (!getDerived().AlwaysRebuild() &&
3585 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003586 Qualifier == E->getQualifier() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00003587 Member == E->getMemberDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003588 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003589
3590 // FIXME: Bogus source location for the operator
3591 SourceLocation FakeOperatorLoc
3592 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3593
3594 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3595 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003596 Qualifier,
3597 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003598 E->getMemberLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003599 Member);
Douglas Gregora16548e2009-08-11 05:31:07 +00003600}
Mike Stump11289f42009-09-09 15:08:12 +00003601
Douglas Gregora16548e2009-08-11 05:31:07 +00003602template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003603Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003604TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3605 assert(false && "Cannot transform abstract class");
3606 return SemaRef.Owned(E->Retain());
3607}
3608
3609template<typename Derived>
3610Sema::OwningExprResult
3611TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003612 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3613 if (LHS.isInvalid())
3614 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003615
Douglas Gregora16548e2009-08-11 05:31:07 +00003616 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3617 if (RHS.isInvalid())
3618 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003619
Douglas Gregora16548e2009-08-11 05:31:07 +00003620 if (!getDerived().AlwaysRebuild() &&
3621 LHS.get() == E->getLHS() &&
3622 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003623 return SemaRef.Owned(E->Retain());
3624
Douglas Gregora16548e2009-08-11 05:31:07 +00003625 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3626 move(LHS), move(RHS));
3627}
3628
Mike Stump11289f42009-09-09 15:08:12 +00003629template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003630Sema::OwningExprResult
3631TreeTransform<Derived>::TransformCompoundAssignOperator(
3632 CompoundAssignOperator *E) {
3633 return getDerived().TransformBinaryOperator(E);
3634}
Mike Stump11289f42009-09-09 15:08:12 +00003635
Douglas Gregora16548e2009-08-11 05:31:07 +00003636template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003637Sema::OwningExprResult
3638TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003639 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3640 if (Cond.isInvalid())
3641 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003642
Douglas Gregora16548e2009-08-11 05:31:07 +00003643 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3644 if (LHS.isInvalid())
3645 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003646
Douglas Gregora16548e2009-08-11 05:31:07 +00003647 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3648 if (RHS.isInvalid())
3649 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003650
Douglas Gregora16548e2009-08-11 05:31:07 +00003651 if (!getDerived().AlwaysRebuild() &&
3652 Cond.get() == E->getCond() &&
3653 LHS.get() == E->getLHS() &&
3654 RHS.get() == E->getRHS())
3655 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003656
3657 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003658 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003659 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003660 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003661 move(RHS));
3662}
Mike Stump11289f42009-09-09 15:08:12 +00003663
3664template<typename Derived>
3665Sema::OwningExprResult
3666TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003667 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3668
3669 // FIXME: Will we ever have type information here? It seems like we won't,
3670 // so do we even need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003671 QualType T = getDerived().TransformType(E->getType());
3672 if (T.isNull())
3673 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003674
Douglas Gregora16548e2009-08-11 05:31:07 +00003675 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3676 if (SubExpr.isInvalid())
3677 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003678
Douglas Gregora16548e2009-08-11 05:31:07 +00003679 if (!getDerived().AlwaysRebuild() &&
3680 T == E->getType() &&
3681 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003682 return SemaRef.Owned(E->Retain());
3683
Douglas Gregora16548e2009-08-11 05:31:07 +00003684 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003685 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003686 E->isLvalueCast());
3687}
Mike Stump11289f42009-09-09 15:08:12 +00003688
Douglas Gregora16548e2009-08-11 05:31:07 +00003689template<typename Derived>
3690Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003691TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3692 assert(false && "Cannot transform abstract class");
3693 return SemaRef.Owned(E->Retain());
3694}
3695
3696template<typename Derived>
3697Sema::OwningExprResult
3698TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003699 QualType T;
3700 {
3701 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003702 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003703 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3704 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003705
Douglas Gregora16548e2009-08-11 05:31:07 +00003706 T = getDerived().TransformType(E->getTypeAsWritten());
3707 if (T.isNull())
3708 return SemaRef.ExprError();
3709 }
Mike Stump11289f42009-09-09 15:08:12 +00003710
Douglas Gregora16548e2009-08-11 05:31:07 +00003711 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3712 if (SubExpr.isInvalid())
3713 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003714
Douglas Gregora16548e2009-08-11 05:31:07 +00003715 if (!getDerived().AlwaysRebuild() &&
3716 T == E->getTypeAsWritten() &&
3717 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003718 return SemaRef.Owned(E->Retain());
3719
Douglas Gregora16548e2009-08-11 05:31:07 +00003720 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3721 E->getRParenLoc(),
3722 move(SubExpr));
3723}
Mike Stump11289f42009-09-09 15:08:12 +00003724
Douglas Gregora16548e2009-08-11 05:31:07 +00003725template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003726Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003727TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3728 QualType T;
3729 {
3730 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003731 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003732 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3733 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003734
Douglas Gregora16548e2009-08-11 05:31:07 +00003735 T = getDerived().TransformType(E->getType());
3736 if (T.isNull())
3737 return SemaRef.ExprError();
3738 }
Mike Stump11289f42009-09-09 15:08:12 +00003739
Douglas Gregora16548e2009-08-11 05:31:07 +00003740 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3741 if (Init.isInvalid())
3742 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003743
Douglas Gregora16548e2009-08-11 05:31:07 +00003744 if (!getDerived().AlwaysRebuild() &&
3745 T == E->getType() &&
3746 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003747 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003748
3749 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3750 /*FIXME:*/E->getInitializer()->getLocEnd(),
3751 move(Init));
3752}
Mike Stump11289f42009-09-09 15:08:12 +00003753
Douglas Gregora16548e2009-08-11 05:31:07 +00003754template<typename Derived>
3755Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003756TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003757 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3758 if (Base.isInvalid())
3759 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003760
Douglas Gregora16548e2009-08-11 05:31:07 +00003761 if (!getDerived().AlwaysRebuild() &&
3762 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003763 return SemaRef.Owned(E->Retain());
3764
Douglas Gregora16548e2009-08-11 05:31:07 +00003765 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003766 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003767 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3768 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3769 E->getAccessorLoc(),
3770 E->getAccessor());
3771}
Mike Stump11289f42009-09-09 15:08:12 +00003772
Douglas Gregora16548e2009-08-11 05:31:07 +00003773template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003774Sema::OwningExprResult
3775TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003776 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003777
Douglas Gregora16548e2009-08-11 05:31:07 +00003778 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3779 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3780 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3781 if (Init.isInvalid())
3782 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003783
Douglas Gregora16548e2009-08-11 05:31:07 +00003784 InitChanged = InitChanged || Init.get() != E->getInit(I);
3785 Inits.push_back(Init.takeAs<Expr>());
3786 }
Mike Stump11289f42009-09-09 15:08:12 +00003787
Douglas Gregora16548e2009-08-11 05:31:07 +00003788 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003789 return SemaRef.Owned(E->Retain());
3790
Douglas Gregora16548e2009-08-11 05:31:07 +00003791 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3792 E->getRBraceLoc());
3793}
Mike Stump11289f42009-09-09 15:08:12 +00003794
Douglas Gregora16548e2009-08-11 05:31:07 +00003795template<typename Derived>
3796Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003797TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003798 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003799
Douglas Gregorebe10102009-08-20 07:17:43 +00003800 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003801 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3802 if (Init.isInvalid())
3803 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003804
Douglas Gregorebe10102009-08-20 07:17:43 +00003805 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003806 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3807 bool ExprChanged = false;
3808 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3809 DEnd = E->designators_end();
3810 D != DEnd; ++D) {
3811 if (D->isFieldDesignator()) {
3812 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3813 D->getDotLoc(),
3814 D->getFieldLoc()));
3815 continue;
3816 }
Mike Stump11289f42009-09-09 15:08:12 +00003817
Douglas Gregora16548e2009-08-11 05:31:07 +00003818 if (D->isArrayDesignator()) {
3819 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3820 if (Index.isInvalid())
3821 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003822
3823 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003824 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003825
Douglas Gregora16548e2009-08-11 05:31:07 +00003826 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3827 ArrayExprs.push_back(Index.release());
3828 continue;
3829 }
Mike Stump11289f42009-09-09 15:08:12 +00003830
Douglas Gregora16548e2009-08-11 05:31:07 +00003831 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003832 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003833 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3834 if (Start.isInvalid())
3835 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003836
Douglas Gregora16548e2009-08-11 05:31:07 +00003837 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3838 if (End.isInvalid())
3839 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003840
3841 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003842 End.get(),
3843 D->getLBracketLoc(),
3844 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003845
Douglas Gregora16548e2009-08-11 05:31:07 +00003846 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3847 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003848
Douglas Gregora16548e2009-08-11 05:31:07 +00003849 ArrayExprs.push_back(Start.release());
3850 ArrayExprs.push_back(End.release());
3851 }
Mike Stump11289f42009-09-09 15:08:12 +00003852
Douglas Gregora16548e2009-08-11 05:31:07 +00003853 if (!getDerived().AlwaysRebuild() &&
3854 Init.get() == E->getInit() &&
3855 !ExprChanged)
3856 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003857
Douglas Gregora16548e2009-08-11 05:31:07 +00003858 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3859 E->getEqualOrColonLoc(),
3860 E->usesGNUSyntax(), move(Init));
3861}
Mike Stump11289f42009-09-09 15:08:12 +00003862
Douglas Gregora16548e2009-08-11 05:31:07 +00003863template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003864Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003865TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003866 ImplicitValueInitExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003867 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3868
3869 // FIXME: Will we ever have proper type location here? Will we actually
3870 // need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003871 QualType T = getDerived().TransformType(E->getType());
3872 if (T.isNull())
3873 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003874
Douglas Gregora16548e2009-08-11 05:31:07 +00003875 if (!getDerived().AlwaysRebuild() &&
3876 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003877 return SemaRef.Owned(E->Retain());
3878
Douglas Gregora16548e2009-08-11 05:31:07 +00003879 return getDerived().RebuildImplicitValueInitExpr(T);
3880}
Mike Stump11289f42009-09-09 15:08:12 +00003881
Douglas Gregora16548e2009-08-11 05:31:07 +00003882template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003883Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003884TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3885 // FIXME: Do we want the type as written?
3886 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003887
Douglas Gregora16548e2009-08-11 05:31:07 +00003888 {
3889 // FIXME: Source location isn't quite accurate.
3890 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3891 T = getDerived().TransformType(E->getType());
3892 if (T.isNull())
3893 return SemaRef.ExprError();
3894 }
Mike Stump11289f42009-09-09 15:08:12 +00003895
Douglas Gregora16548e2009-08-11 05:31:07 +00003896 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3897 if (SubExpr.isInvalid())
3898 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003899
Douglas Gregora16548e2009-08-11 05:31:07 +00003900 if (!getDerived().AlwaysRebuild() &&
3901 T == E->getType() &&
3902 SubExpr.get() == E->getSubExpr())
3903 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003904
Douglas Gregora16548e2009-08-11 05:31:07 +00003905 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3906 T, E->getRParenLoc());
3907}
3908
3909template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003910Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003911TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3912 bool ArgumentChanged = false;
3913 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3914 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3915 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3916 if (Init.isInvalid())
3917 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003918
Douglas Gregora16548e2009-08-11 05:31:07 +00003919 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3920 Inits.push_back(Init.takeAs<Expr>());
3921 }
Mike Stump11289f42009-09-09 15:08:12 +00003922
Douglas Gregora16548e2009-08-11 05:31:07 +00003923 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3924 move_arg(Inits),
3925 E->getRParenLoc());
3926}
Mike Stump11289f42009-09-09 15:08:12 +00003927
Douglas Gregora16548e2009-08-11 05:31:07 +00003928/// \brief Transform an address-of-label expression.
3929///
3930/// By default, the transformation of an address-of-label expression always
3931/// rebuilds the expression, so that the label identifier can be resolved to
3932/// the corresponding label statement by semantic analysis.
3933template<typename Derived>
3934Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003935TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003936 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3937 E->getLabel());
3938}
Mike Stump11289f42009-09-09 15:08:12 +00003939
3940template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003941Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00003942 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00003943 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3944 if (SubStmt.isInvalid())
3945 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003946
Douglas Gregora16548e2009-08-11 05:31:07 +00003947 if (!getDerived().AlwaysRebuild() &&
3948 SubStmt.get() == E->getSubStmt())
3949 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003950
3951 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003952 move(SubStmt),
3953 E->getRParenLoc());
3954}
Mike Stump11289f42009-09-09 15:08:12 +00003955
Douglas Gregora16548e2009-08-11 05:31:07 +00003956template<typename Derived>
3957Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003958TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003959 QualType T1, T2;
3960 {
3961 // FIXME: Source location isn't quite accurate.
3962 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003963
Douglas Gregora16548e2009-08-11 05:31:07 +00003964 T1 = getDerived().TransformType(E->getArgType1());
3965 if (T1.isNull())
3966 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003967
Douglas Gregora16548e2009-08-11 05:31:07 +00003968 T2 = getDerived().TransformType(E->getArgType2());
3969 if (T2.isNull())
3970 return SemaRef.ExprError();
3971 }
3972
3973 if (!getDerived().AlwaysRebuild() &&
3974 T1 == E->getArgType1() &&
3975 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00003976 return SemaRef.Owned(E->Retain());
3977
Douglas Gregora16548e2009-08-11 05:31:07 +00003978 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3979 T1, T2, E->getRParenLoc());
3980}
Mike Stump11289f42009-09-09 15:08:12 +00003981
Douglas Gregora16548e2009-08-11 05:31:07 +00003982template<typename Derived>
3983Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003984TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003985 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3986 if (Cond.isInvalid())
3987 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003988
Douglas Gregora16548e2009-08-11 05:31:07 +00003989 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3990 if (LHS.isInvalid())
3991 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003992
Douglas Gregora16548e2009-08-11 05:31:07 +00003993 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3994 if (RHS.isInvalid())
3995 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003996
Douglas Gregora16548e2009-08-11 05:31:07 +00003997 if (!getDerived().AlwaysRebuild() &&
3998 Cond.get() == E->getCond() &&
3999 LHS.get() == E->getLHS() &&
4000 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00004001 return SemaRef.Owned(E->Retain());
4002
Douglas Gregora16548e2009-08-11 05:31:07 +00004003 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4004 move(Cond), move(LHS), move(RHS),
4005 E->getRParenLoc());
4006}
Mike Stump11289f42009-09-09 15:08:12 +00004007
Douglas Gregora16548e2009-08-11 05:31:07 +00004008template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004009Sema::OwningExprResult
4010TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
4011 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004012}
4013
4014template<typename Derived>
4015Sema::OwningExprResult
4016TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
4017 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4018 if (Callee.isInvalid())
4019 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004020
Douglas Gregora16548e2009-08-11 05:31:07 +00004021 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
4022 if (First.isInvalid())
4023 return SemaRef.ExprError();
4024
4025 OwningExprResult Second(SemaRef);
4026 if (E->getNumArgs() == 2) {
4027 Second = getDerived().TransformExpr(E->getArg(1));
4028 if (Second.isInvalid())
4029 return SemaRef.ExprError();
4030 }
Mike Stump11289f42009-09-09 15:08:12 +00004031
Douglas Gregora16548e2009-08-11 05:31:07 +00004032 if (!getDerived().AlwaysRebuild() &&
4033 Callee.get() == E->getCallee() &&
4034 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00004035 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4036 return SemaRef.Owned(E->Retain());
4037
Douglas Gregora16548e2009-08-11 05:31:07 +00004038 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4039 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004040 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00004041 move(First),
4042 move(Second));
4043}
Mike Stump11289f42009-09-09 15:08:12 +00004044
Douglas Gregora16548e2009-08-11 05:31:07 +00004045template<typename Derived>
4046Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004047TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004048 return getDerived().TransformCallExpr(E);
4049}
Mike Stump11289f42009-09-09 15:08:12 +00004050
Douglas Gregora16548e2009-08-11 05:31:07 +00004051template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004052Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004053TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
4054 QualType ExplicitTy;
4055 {
4056 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00004057 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004058 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4059 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004060
Douglas Gregora16548e2009-08-11 05:31:07 +00004061 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4062 if (ExplicitTy.isNull())
4063 return SemaRef.ExprError();
4064 }
Mike Stump11289f42009-09-09 15:08:12 +00004065
Douglas Gregora16548e2009-08-11 05:31:07 +00004066 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4067 if (SubExpr.isInvalid())
4068 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004069
Douglas Gregora16548e2009-08-11 05:31:07 +00004070 if (!getDerived().AlwaysRebuild() &&
4071 ExplicitTy == E->getTypeAsWritten() &&
4072 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004073 return SemaRef.Owned(E->Retain());
4074
Douglas Gregora16548e2009-08-11 05:31:07 +00004075 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00004076 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004077 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4078 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4079 SourceLocation FakeRParenLoc
4080 = SemaRef.PP.getLocForEndOfToken(
4081 E->getSubExpr()->getSourceRange().getEnd());
4082 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004083 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004084 FakeLAngleLoc,
4085 ExplicitTy,
4086 FakeRAngleLoc,
4087 FakeRAngleLoc,
4088 move(SubExpr),
4089 FakeRParenLoc);
4090}
Mike Stump11289f42009-09-09 15:08:12 +00004091
Douglas Gregora16548e2009-08-11 05:31:07 +00004092template<typename Derived>
4093Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004094TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004095 return getDerived().TransformCXXNamedCastExpr(E);
4096}
Mike Stump11289f42009-09-09 15:08:12 +00004097
4098template<typename Derived>
4099Sema::OwningExprResult
4100TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
4101 return getDerived().TransformCXXNamedCastExpr(E);
4102}
4103
Douglas Gregora16548e2009-08-11 05:31:07 +00004104template<typename Derived>
4105Sema::OwningExprResult
4106TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004107 CXXReinterpretCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004108 return getDerived().TransformCXXNamedCastExpr(E);
4109}
Mike Stump11289f42009-09-09 15:08:12 +00004110
Douglas Gregora16548e2009-08-11 05:31:07 +00004111template<typename Derived>
4112Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004113TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004114 return getDerived().TransformCXXNamedCastExpr(E);
4115}
Mike Stump11289f42009-09-09 15:08:12 +00004116
Douglas Gregora16548e2009-08-11 05:31:07 +00004117template<typename Derived>
4118Sema::OwningExprResult
4119TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004120 CXXFunctionalCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004121 QualType ExplicitTy;
4122 {
4123 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004124
Douglas Gregora16548e2009-08-11 05:31:07 +00004125 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4126 if (ExplicitTy.isNull())
4127 return SemaRef.ExprError();
4128 }
Mike Stump11289f42009-09-09 15:08:12 +00004129
Douglas Gregora16548e2009-08-11 05:31:07 +00004130 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4131 if (SubExpr.isInvalid())
4132 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004133
Douglas Gregora16548e2009-08-11 05:31:07 +00004134 if (!getDerived().AlwaysRebuild() &&
4135 ExplicitTy == E->getTypeAsWritten() &&
4136 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004137 return SemaRef.Owned(E->Retain());
4138
Douglas Gregora16548e2009-08-11 05:31:07 +00004139 // FIXME: The end of the type's source range is wrong
4140 return getDerived().RebuildCXXFunctionalCastExpr(
4141 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4142 ExplicitTy,
4143 /*FIXME:*/E->getSubExpr()->getLocStart(),
4144 move(SubExpr),
4145 E->getRParenLoc());
4146}
Mike Stump11289f42009-09-09 15:08:12 +00004147
Douglas Gregora16548e2009-08-11 05:31:07 +00004148template<typename Derived>
4149Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004150TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004151 if (E->isTypeOperand()) {
4152 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004153
Douglas Gregora16548e2009-08-11 05:31:07 +00004154 QualType T = getDerived().TransformType(E->getTypeOperand());
4155 if (T.isNull())
4156 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004157
Douglas Gregora16548e2009-08-11 05:31:07 +00004158 if (!getDerived().AlwaysRebuild() &&
4159 T == E->getTypeOperand())
4160 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004161
Douglas Gregora16548e2009-08-11 05:31:07 +00004162 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4163 /*FIXME:*/E->getLocStart(),
4164 T,
4165 E->getLocEnd());
4166 }
Mike Stump11289f42009-09-09 15:08:12 +00004167
Douglas Gregora16548e2009-08-11 05:31:07 +00004168 // We don't know whether the expression is potentially evaluated until
4169 // after we perform semantic analysis, so the expression is potentially
4170 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004171 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004172 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004173
Douglas Gregora16548e2009-08-11 05:31:07 +00004174 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4175 if (SubExpr.isInvalid())
4176 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004177
Douglas Gregora16548e2009-08-11 05:31:07 +00004178 if (!getDerived().AlwaysRebuild() &&
4179 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004180 return SemaRef.Owned(E->Retain());
4181
Douglas Gregora16548e2009-08-11 05:31:07 +00004182 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4183 /*FIXME:*/E->getLocStart(),
4184 move(SubExpr),
4185 E->getLocEnd());
4186}
4187
4188template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004189Sema::OwningExprResult
4190TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
4191 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004192}
Mike Stump11289f42009-09-09 15:08:12 +00004193
Douglas Gregora16548e2009-08-11 05:31:07 +00004194template<typename Derived>
4195Sema::OwningExprResult
4196TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004197 CXXNullPtrLiteralExpr *E) {
4198 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004199}
Mike Stump11289f42009-09-09 15:08:12 +00004200
Douglas Gregora16548e2009-08-11 05:31:07 +00004201template<typename Derived>
4202Sema::OwningExprResult
4203TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
4204 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004205
Douglas Gregora16548e2009-08-11 05:31:07 +00004206 QualType T = getDerived().TransformType(E->getType());
4207 if (T.isNull())
4208 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004209
Douglas Gregora16548e2009-08-11 05:31:07 +00004210 if (!getDerived().AlwaysRebuild() &&
4211 T == E->getType())
4212 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004213
Douglas Gregora16548e2009-08-11 05:31:07 +00004214 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4215}
Mike Stump11289f42009-09-09 15:08:12 +00004216
Douglas Gregora16548e2009-08-11 05:31:07 +00004217template<typename Derived>
4218Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004219TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004220 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4221 if (SubExpr.isInvalid())
4222 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004223
Douglas Gregora16548e2009-08-11 05:31:07 +00004224 if (!getDerived().AlwaysRebuild() &&
4225 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004226 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004227
4228 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4229}
Mike Stump11289f42009-09-09 15:08:12 +00004230
Douglas Gregora16548e2009-08-11 05:31:07 +00004231template<typename Derived>
4232Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004233TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
4234 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004235 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4236 if (!Param)
4237 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004238
Douglas Gregora16548e2009-08-11 05:31:07 +00004239 if (getDerived().AlwaysRebuild() &&
4240 Param == E->getParam())
4241 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004242
Douglas Gregora16548e2009-08-11 05:31:07 +00004243 return getDerived().RebuildCXXDefaultArgExpr(Param);
4244}
Mike Stump11289f42009-09-09 15:08:12 +00004245
Douglas Gregora16548e2009-08-11 05:31:07 +00004246template<typename Derived>
4247Sema::OwningExprResult
4248TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
4249 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4250
4251 QualType T = getDerived().TransformType(E->getType());
4252 if (T.isNull())
4253 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004254
Douglas Gregora16548e2009-08-11 05:31:07 +00004255 if (!getDerived().AlwaysRebuild() &&
4256 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004257 return SemaRef.Owned(E->Retain());
4258
4259 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004260 /*FIXME:*/E->getTypeBeginLoc(),
4261 T,
4262 E->getRParenLoc());
4263}
Mike Stump11289f42009-09-09 15:08:12 +00004264
Douglas Gregora16548e2009-08-11 05:31:07 +00004265template<typename Derived>
4266Sema::OwningExprResult
4267TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00004268 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004269 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004270 if (!Var)
4271 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004272
Douglas Gregora16548e2009-08-11 05:31:07 +00004273 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004274 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004275 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004276
4277 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004278 /*FIXME:*/E->getStartLoc(),
4279 Var);
4280}
Mike Stump11289f42009-09-09 15:08:12 +00004281
Douglas Gregora16548e2009-08-11 05:31:07 +00004282template<typename Derived>
4283Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004284TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004285 // Transform the type that we're allocating
4286 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4287 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4288 if (AllocType.isNull())
4289 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004290
Douglas Gregora16548e2009-08-11 05:31:07 +00004291 // Transform the size of the array we're allocating (if any).
4292 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4293 if (ArraySize.isInvalid())
4294 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004295
Douglas Gregora16548e2009-08-11 05:31:07 +00004296 // Transform the placement arguments (if any).
4297 bool ArgumentChanged = false;
4298 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4299 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4300 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4301 if (Arg.isInvalid())
4302 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004303
Douglas Gregora16548e2009-08-11 05:31:07 +00004304 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4305 PlacementArgs.push_back(Arg.take());
4306 }
Mike Stump11289f42009-09-09 15:08:12 +00004307
Douglas Gregorebe10102009-08-20 07:17:43 +00004308 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004309 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4310 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4311 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4312 if (Arg.isInvalid())
4313 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004314
Douglas Gregora16548e2009-08-11 05:31:07 +00004315 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4316 ConstructorArgs.push_back(Arg.take());
4317 }
Mike Stump11289f42009-09-09 15:08:12 +00004318
Douglas Gregora16548e2009-08-11 05:31:07 +00004319 if (!getDerived().AlwaysRebuild() &&
4320 AllocType == E->getAllocatedType() &&
4321 ArraySize.get() == E->getArraySize() &&
4322 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004323 return SemaRef.Owned(E->Retain());
4324
Douglas Gregora16548e2009-08-11 05:31:07 +00004325 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4326 E->isGlobalNew(),
4327 /*FIXME:*/E->getLocStart(),
4328 move_arg(PlacementArgs),
4329 /*FIXME:*/E->getLocStart(),
4330 E->isParenTypeId(),
4331 AllocType,
4332 /*FIXME:*/E->getLocStart(),
4333 /*FIXME:*/SourceRange(),
4334 move(ArraySize),
4335 /*FIXME:*/E->getLocStart(),
4336 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004337 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004338}
Mike Stump11289f42009-09-09 15:08:12 +00004339
Douglas Gregora16548e2009-08-11 05:31:07 +00004340template<typename Derived>
4341Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004342TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004343 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4344 if (Operand.isInvalid())
4345 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004346
Douglas Gregora16548e2009-08-11 05:31:07 +00004347 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004348 Operand.get() == E->getArgument())
4349 return SemaRef.Owned(E->Retain());
4350
Douglas Gregora16548e2009-08-11 05:31:07 +00004351 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4352 E->isGlobalDelete(),
4353 E->isArrayForm(),
4354 move(Operand));
4355}
Mike Stump11289f42009-09-09 15:08:12 +00004356
Douglas Gregora16548e2009-08-11 05:31:07 +00004357template<typename Derived>
4358Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004359TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
4360 CXXPseudoDestructorExpr *E) {
4361 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4362 if (Base.isInvalid())
4363 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004364
Douglas Gregorad8a3362009-09-04 17:36:40 +00004365 NestedNameSpecifier *Qualifier
4366 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4367 E->getQualifierRange());
4368 if (E->getQualifier() && !Qualifier)
4369 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004370
Douglas Gregorad8a3362009-09-04 17:36:40 +00004371 QualType DestroyedType;
4372 {
4373 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4374 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4375 if (DestroyedType.isNull())
4376 return SemaRef.ExprError();
4377 }
Mike Stump11289f42009-09-09 15:08:12 +00004378
Douglas Gregorad8a3362009-09-04 17:36:40 +00004379 if (!getDerived().AlwaysRebuild() &&
4380 Base.get() == E->getBase() &&
4381 Qualifier == E->getQualifier() &&
4382 DestroyedType == E->getDestroyedType())
4383 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004384
Douglas Gregorad8a3362009-09-04 17:36:40 +00004385 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4386 E->getOperatorLoc(),
4387 E->isArrow(),
4388 E->getDestroyedTypeLoc(),
4389 DestroyedType,
4390 Qualifier,
4391 E->getQualifierRange());
4392}
Mike Stump11289f42009-09-09 15:08:12 +00004393
Douglas Gregorad8a3362009-09-04 17:36:40 +00004394template<typename Derived>
4395Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004396TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004397 UnresolvedFunctionNameExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004398 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004399 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004400}
Mike Stump11289f42009-09-09 15:08:12 +00004401
Douglas Gregora16548e2009-08-11 05:31:07 +00004402template<typename Derived>
4403Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004404TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004405 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004406
Douglas Gregora16548e2009-08-11 05:31:07 +00004407 QualType T = getDerived().TransformType(E->getQueriedType());
4408 if (T.isNull())
4409 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004410
Douglas Gregora16548e2009-08-11 05:31:07 +00004411 if (!getDerived().AlwaysRebuild() &&
4412 T == E->getQueriedType())
4413 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004414
Douglas Gregora16548e2009-08-11 05:31:07 +00004415 // FIXME: Bad location information
4416 SourceLocation FakeLParenLoc
4417 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004418
4419 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004420 E->getLocStart(),
4421 /*FIXME:*/FakeLParenLoc,
4422 T,
4423 E->getLocEnd());
4424}
Mike Stump11289f42009-09-09 15:08:12 +00004425
Douglas Gregora16548e2009-08-11 05:31:07 +00004426template<typename Derived>
4427Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004428TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004429 UnresolvedDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004430 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004431 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4432 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004433 if (!NNS)
4434 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004435
4436 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004437 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4438 if (!Name)
4439 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004440
4441 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004442 NNS == E->getQualifier() &&
4443 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004444 return SemaRef.Owned(E->Retain());
4445
4446 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004447 E->getQualifierRange(),
4448 Name,
4449 E->getLocation(),
4450 /*FIXME:*/false);
4451}
4452
4453template<typename Derived>
4454Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004455TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
Douglas Gregorba91b892009-10-29 17:56:10 +00004456 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4457
Mike Stump11289f42009-09-09 15:08:12 +00004458 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004459 = getDerived().TransformTemplateName(E->getTemplateName());
4460 if (Template.isNull())
4461 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004462
Douglas Gregord019ff62009-10-22 17:20:55 +00004463 NestedNameSpecifier *Qualifier = 0;
4464 if (E->getQualifier()) {
4465 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4466 E->getQualifierRange());
4467 if (!Qualifier)
4468 return SemaRef.ExprError();
4469 }
4470
John McCall0ad16662009-10-29 08:12:44 +00004471 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora16548e2009-08-11 05:31:07 +00004472 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004473 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4474 TransArgs[I]))
Douglas Gregora16548e2009-08-11 05:31:07 +00004475 return SemaRef.ExprError();
Douglas Gregora16548e2009-08-11 05:31:07 +00004476 }
4477
4478 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4479 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004480
4481 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004482 // actually refers to a type, in which case the caller is actually dealing
4483 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004484 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4485 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004486 E->getLAngleLoc(),
4487 TransArgs.data(),
4488 TransArgs.size(),
4489 E->getRAngleLoc());
4490}
4491
4492template<typename Derived>
4493Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004494TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004495 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4496
4497 QualType T = getDerived().TransformType(E->getType());
4498 if (T.isNull())
4499 return SemaRef.ExprError();
4500
4501 CXXConstructorDecl *Constructor
4502 = cast_or_null<CXXConstructorDecl>(
4503 getDerived().TransformDecl(E->getConstructor()));
4504 if (!Constructor)
4505 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004506
Douglas Gregora16548e2009-08-11 05:31:07 +00004507 bool ArgumentChanged = false;
4508 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004509 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004510 ArgEnd = E->arg_end();
4511 Arg != ArgEnd; ++Arg) {
4512 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4513 if (TransArg.isInvalid())
4514 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004515
Douglas Gregora16548e2009-08-11 05:31:07 +00004516 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4517 Args.push_back(TransArg.takeAs<Expr>());
4518 }
4519
4520 if (!getDerived().AlwaysRebuild() &&
4521 T == E->getType() &&
4522 Constructor == E->getConstructor() &&
4523 !ArgumentChanged)
4524 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004525
Douglas Gregora16548e2009-08-11 05:31:07 +00004526 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4527 move_arg(Args));
4528}
Mike Stump11289f42009-09-09 15:08:12 +00004529
Douglas Gregora16548e2009-08-11 05:31:07 +00004530/// \brief Transform a C++ temporary-binding expression.
4531///
Mike Stump11289f42009-09-09 15:08:12 +00004532/// The transformation of a temporary-binding expression always attempts to
4533/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004534/// subexpression itself did not change, because the temporary variable itself
4535/// must be unique.
4536template<typename Derived>
4537Sema::OwningExprResult
4538TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4539 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4540 if (SubExpr.isInvalid())
4541 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004542
Douglas Gregora16548e2009-08-11 05:31:07 +00004543 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4544}
Mike Stump11289f42009-09-09 15:08:12 +00004545
4546/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004547/// be destroyed after the expression is evaluated.
4548///
Mike Stump11289f42009-09-09 15:08:12 +00004549/// The transformation of a full expression always attempts to build a new
4550/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004551/// subexpression itself did not change, because it will need to capture the
4552/// the new temporary variables introduced in the subexpression.
4553template<typename Derived>
4554Sema::OwningExprResult
4555TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump11289f42009-09-09 15:08:12 +00004556 CXXExprWithTemporaries *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004557 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4558 if (SubExpr.isInvalid())
4559 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004560
Douglas Gregora16548e2009-08-11 05:31:07 +00004561 return SemaRef.Owned(
4562 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4563 E->shouldDestroyTemporaries()));
4564}
Mike Stump11289f42009-09-09 15:08:12 +00004565
Douglas Gregora16548e2009-08-11 05:31:07 +00004566template<typename Derived>
4567Sema::OwningExprResult
4568TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004569 CXXTemporaryObjectExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004570 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4571 QualType T = getDerived().TransformType(E->getType());
4572 if (T.isNull())
4573 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004574
Douglas Gregora16548e2009-08-11 05:31:07 +00004575 CXXConstructorDecl *Constructor
4576 = cast_or_null<CXXConstructorDecl>(
4577 getDerived().TransformDecl(E->getConstructor()));
4578 if (!Constructor)
4579 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004580
Douglas Gregora16548e2009-08-11 05:31:07 +00004581 bool ArgumentChanged = false;
4582 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4583 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004584 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004585 ArgEnd = E->arg_end();
4586 Arg != ArgEnd; ++Arg) {
4587 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4588 if (TransArg.isInvalid())
4589 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004590
Douglas Gregora16548e2009-08-11 05:31:07 +00004591 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4592 Args.push_back((Expr *)TransArg.release());
4593 }
Mike Stump11289f42009-09-09 15:08:12 +00004594
Douglas Gregora16548e2009-08-11 05:31:07 +00004595 if (!getDerived().AlwaysRebuild() &&
4596 T == E->getType() &&
4597 Constructor == E->getConstructor() &&
4598 !ArgumentChanged)
4599 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004600
Douglas Gregora16548e2009-08-11 05:31:07 +00004601 // FIXME: Bogus location information
4602 SourceLocation CommaLoc;
4603 if (Args.size() > 1) {
4604 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004605 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004606 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4607 }
4608 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4609 T,
4610 /*FIXME:*/E->getTypeBeginLoc(),
4611 move_arg(Args),
4612 &CommaLoc,
4613 E->getLocEnd());
4614}
Mike Stump11289f42009-09-09 15:08:12 +00004615
Douglas Gregora16548e2009-08-11 05:31:07 +00004616template<typename Derived>
4617Sema::OwningExprResult
4618TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004619 CXXUnresolvedConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004620 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4621 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4622 if (T.isNull())
4623 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004624
Douglas Gregora16548e2009-08-11 05:31:07 +00004625 bool ArgumentChanged = false;
4626 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4627 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4628 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4629 ArgEnd = E->arg_end();
4630 Arg != ArgEnd; ++Arg) {
4631 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4632 if (TransArg.isInvalid())
4633 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004634
Douglas Gregora16548e2009-08-11 05:31:07 +00004635 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4636 FakeCommaLocs.push_back(
4637 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4638 Args.push_back(TransArg.takeAs<Expr>());
4639 }
Mike Stump11289f42009-09-09 15:08:12 +00004640
Douglas Gregora16548e2009-08-11 05:31:07 +00004641 if (!getDerived().AlwaysRebuild() &&
4642 T == E->getTypeAsWritten() &&
4643 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004644 return SemaRef.Owned(E->Retain());
4645
Douglas Gregora16548e2009-08-11 05:31:07 +00004646 // FIXME: we're faking the locations of the commas
4647 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4648 T,
4649 E->getLParenLoc(),
4650 move_arg(Args),
4651 FakeCommaLocs.data(),
4652 E->getRParenLoc());
4653}
Mike Stump11289f42009-09-09 15:08:12 +00004654
Douglas Gregora16548e2009-08-11 05:31:07 +00004655template<typename Derived>
4656Sema::OwningExprResult
4657TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004658 CXXUnresolvedMemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004659 // Transform the base of the expression.
4660 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4661 if (Base.isInvalid())
4662 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004663
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004664 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004665 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004666 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004667 E->getOperatorLoc(),
4668 E->isArrow()? tok::arrow : tok::period,
4669 ObjectType);
4670 if (Base.isInvalid())
4671 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004672
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004673 // Transform the first part of the nested-name-specifier that qualifies
4674 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004675 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004676 = getDerived().TransformFirstQualifierInScope(
4677 E->getFirstQualifierFoundInScope(),
4678 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004679
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004680 NestedNameSpecifier *Qualifier = 0;
4681 if (E->getQualifier()) {
4682 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4683 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004684 QualType::getFromOpaquePtr(ObjectType),
4685 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004686 if (!Qualifier)
4687 return SemaRef.ExprError();
4688 }
Mike Stump11289f42009-09-09 15:08:12 +00004689
4690 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004691 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4692 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004693 if (!Name)
4694 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004695
Douglas Gregor308047d2009-09-09 00:23:06 +00004696 if (!E->hasExplicitTemplateArgumentList()) {
4697 // This is a reference to a member without an explicitly-specified
4698 // template argument list. Optimize for this common case.
4699 if (!getDerived().AlwaysRebuild() &&
4700 Base.get() == E->getBase() &&
4701 Qualifier == E->getQualifier() &&
4702 Name == E->getMember() &&
4703 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004704 return SemaRef.Owned(E->Retain());
4705
Douglas Gregor308047d2009-09-09 00:23:06 +00004706 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4707 E->isArrow(),
4708 E->getOperatorLoc(),
4709 Qualifier,
4710 E->getQualifierRange(),
4711 Name,
4712 E->getMemberLoc(),
4713 FirstQualifierInScope);
4714 }
4715
4716 // FIXME: This is an ugly hack, which forces the same template name to
4717 // be looked up multiple times. Yuck!
4718 // FIXME: This also won't work for, e.g., x->template operator+<int>
4719 TemplateName OrigTemplateName
4720 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump11289f42009-09-09 15:08:12 +00004721
4722 TemplateName Template
4723 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004724 QualType::getFromOpaquePtr(ObjectType));
4725 if (Template.isNull())
4726 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004727
John McCall0ad16662009-10-29 08:12:44 +00004728 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor308047d2009-09-09 00:23:06 +00004729 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004730 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4731 TransArgs[I]))
Douglas Gregor308047d2009-09-09 00:23:06 +00004732 return SemaRef.ExprError();
Douglas Gregor308047d2009-09-09 00:23:06 +00004733 }
Mike Stump11289f42009-09-09 15:08:12 +00004734
Douglas Gregora16548e2009-08-11 05:31:07 +00004735 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4736 E->isArrow(),
4737 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004738 Qualifier,
4739 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004740 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004741 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004742 FirstQualifierInScope,
4743 E->getLAngleLoc(),
4744 TransArgs.data(),
4745 TransArgs.size(),
4746 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004747}
4748
4749template<typename Derived>
4750Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004751TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4752 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004753}
4754
Mike Stump11289f42009-09-09 15:08:12 +00004755template<typename Derived>
4756Sema::OwningExprResult
4757TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004758 // FIXME: poor source location
4759 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4760 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4761 if (EncodedType.isNull())
4762 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004763
Douglas Gregora16548e2009-08-11 05:31:07 +00004764 if (!getDerived().AlwaysRebuild() &&
4765 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004766 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004767
4768 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4769 EncodedType,
4770 E->getRParenLoc());
4771}
Mike Stump11289f42009-09-09 15:08:12 +00004772
Douglas Gregora16548e2009-08-11 05:31:07 +00004773template<typename Derived>
4774Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004775TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004776 // FIXME: Implement this!
4777 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004778 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004779}
4780
Mike Stump11289f42009-09-09 15:08:12 +00004781template<typename Derived>
4782Sema::OwningExprResult
4783TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4784 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004785}
4786
Mike Stump11289f42009-09-09 15:08:12 +00004787template<typename Derived>
4788Sema::OwningExprResult
4789TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4790 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004791 = cast_or_null<ObjCProtocolDecl>(
4792 getDerived().TransformDecl(E->getProtocol()));
4793 if (!Protocol)
4794 return SemaRef.ExprError();
4795
4796 if (!getDerived().AlwaysRebuild() &&
4797 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004798 return SemaRef.Owned(E->Retain());
4799
Douglas Gregora16548e2009-08-11 05:31:07 +00004800 return getDerived().RebuildObjCProtocolExpr(Protocol,
4801 E->getAtLoc(),
4802 /*FIXME:*/E->getAtLoc(),
4803 /*FIXME:*/E->getAtLoc(),
4804 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004805
Douglas Gregora16548e2009-08-11 05:31:07 +00004806}
4807
Mike Stump11289f42009-09-09 15:08:12 +00004808template<typename Derived>
4809Sema::OwningExprResult
4810TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004811 // FIXME: Implement this!
4812 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004813 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004814}
4815
Mike Stump11289f42009-09-09 15:08:12 +00004816template<typename Derived>
4817Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004818TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4819 // FIXME: Implement this!
4820 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004821 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004822}
4823
Mike Stump11289f42009-09-09 15:08:12 +00004824template<typename Derived>
4825Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004826TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004827 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004828 // FIXME: Implement this!
4829 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004830 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004831}
4832
Mike Stump11289f42009-09-09 15:08:12 +00004833template<typename Derived>
4834Sema::OwningExprResult
4835TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004836 // FIXME: Implement this!
4837 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004838 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004839}
4840
Mike Stump11289f42009-09-09 15:08:12 +00004841template<typename Derived>
4842Sema::OwningExprResult
4843TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004844 // FIXME: Implement this!
4845 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004846 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004847}
4848
Mike Stump11289f42009-09-09 15:08:12 +00004849template<typename Derived>
4850Sema::OwningExprResult
4851TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004852 bool ArgumentChanged = false;
4853 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4854 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4855 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4856 if (SubExpr.isInvalid())
4857 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004858
Douglas Gregora16548e2009-08-11 05:31:07 +00004859 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4860 SubExprs.push_back(SubExpr.takeAs<Expr>());
4861 }
Mike Stump11289f42009-09-09 15:08:12 +00004862
Douglas Gregora16548e2009-08-11 05:31:07 +00004863 if (!getDerived().AlwaysRebuild() &&
4864 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004865 return SemaRef.Owned(E->Retain());
4866
Douglas Gregora16548e2009-08-11 05:31:07 +00004867 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4868 move_arg(SubExprs),
4869 E->getRParenLoc());
4870}
4871
Mike Stump11289f42009-09-09 15:08:12 +00004872template<typename Derived>
4873Sema::OwningExprResult
4874TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004875 // FIXME: Implement this!
4876 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004877 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004878}
4879
Mike Stump11289f42009-09-09 15:08:12 +00004880template<typename Derived>
4881Sema::OwningExprResult
4882TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004883 // FIXME: Implement this!
4884 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004885 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004886}
Mike Stump11289f42009-09-09 15:08:12 +00004887
Douglas Gregora16548e2009-08-11 05:31:07 +00004888//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00004889// Type reconstruction
4890//===----------------------------------------------------------------------===//
4891
Mike Stump11289f42009-09-09 15:08:12 +00004892template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004893QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004894 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004895 getDerived().getBaseLocation(),
4896 getDerived().getBaseEntity());
4897}
4898
Mike Stump11289f42009-09-09 15:08:12 +00004899template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004900QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004901 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004902 getDerived().getBaseLocation(),
4903 getDerived().getBaseEntity());
4904}
4905
Mike Stump11289f42009-09-09 15:08:12 +00004906template<typename Derived>
4907QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004908TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004909 return SemaRef.BuildReferenceType(ReferentType, true, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004910 getDerived().getBaseLocation(),
4911 getDerived().getBaseEntity());
4912}
4913
4914template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004915QualType
4916TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004917 return SemaRef.BuildReferenceType(ReferentType, false, Qualifiers(),
Mike Stump11289f42009-09-09 15:08:12 +00004918 getDerived().getBaseLocation(),
4919 getDerived().getBaseEntity());
4920}
4921
4922template<typename Derived>
4923QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004924 QualType ClassType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004925 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004926 getDerived().getBaseLocation(),
4927 getDerived().getBaseEntity());
4928}
4929
4930template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004931QualType
John McCall550e0c22009-10-21 00:40:46 +00004932TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType) {
4933 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
4934 getDerived().getBaseLocation(),
4935 getDerived().getBaseEntity());
4936}
4937
4938template<typename Derived>
4939QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004940TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4941 ArrayType::ArraySizeModifier SizeMod,
4942 const llvm::APInt *Size,
4943 Expr *SizeExpr,
4944 unsigned IndexTypeQuals,
4945 SourceRange BracketsRange) {
4946 if (SizeExpr || !Size)
4947 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4948 IndexTypeQuals, BracketsRange,
4949 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00004950
4951 QualType Types[] = {
4952 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4953 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4954 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00004955 };
4956 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4957 QualType SizeType;
4958 for (unsigned I = 0; I != NumTypes; ++I)
4959 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4960 SizeType = Types[I];
4961 break;
4962 }
Mike Stump11289f42009-09-09 15:08:12 +00004963
Douglas Gregord6ff3322009-08-04 16:50:30 +00004964 if (SizeType.isNull())
4965 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00004966
Douglas Gregord6ff3322009-08-04 16:50:30 +00004967 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004968 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004969 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00004970 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004971}
Mike Stump11289f42009-09-09 15:08:12 +00004972
Douglas Gregord6ff3322009-08-04 16:50:30 +00004973template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004974QualType
4975TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004976 ArrayType::ArraySizeModifier SizeMod,
4977 const llvm::APInt &Size,
4978 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004979 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004980 IndexTypeQuals, SourceRange());
4981}
4982
4983template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004984QualType
Mike Stump11289f42009-09-09 15:08:12 +00004985TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004986 ArrayType::ArraySizeModifier SizeMod,
4987 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004988 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004989 IndexTypeQuals, SourceRange());
4990}
Mike Stump11289f42009-09-09 15:08:12 +00004991
Douglas Gregord6ff3322009-08-04 16:50:30 +00004992template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004993QualType
4994TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004995 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00004996 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004997 unsigned IndexTypeQuals,
4998 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00004999 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005000 SizeExpr.takeAs<Expr>(),
5001 IndexTypeQuals, BracketsRange);
5002}
5003
5004template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005005QualType
5006TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005007 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005008 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005009 unsigned IndexTypeQuals,
5010 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005011 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005012 SizeExpr.takeAs<Expr>(),
5013 IndexTypeQuals, BracketsRange);
5014}
5015
5016template<typename Derived>
5017QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5018 unsigned NumElements) {
5019 // FIXME: semantic checking!
5020 return SemaRef.Context.getVectorType(ElementType, NumElements);
5021}
Mike Stump11289f42009-09-09 15:08:12 +00005022
Douglas Gregord6ff3322009-08-04 16:50:30 +00005023template<typename Derived>
5024QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5025 unsigned NumElements,
5026 SourceLocation AttributeLoc) {
5027 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5028 NumElements, true);
5029 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00005030 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005031 AttributeLoc);
5032 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5033 AttributeLoc);
5034}
Mike Stump11289f42009-09-09 15:08:12 +00005035
Douglas Gregord6ff3322009-08-04 16:50:30 +00005036template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005037QualType
5038TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00005039 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005040 SourceLocation AttributeLoc) {
5041 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5042}
Mike Stump11289f42009-09-09 15:08:12 +00005043
Douglas Gregord6ff3322009-08-04 16:50:30 +00005044template<typename Derived>
5045QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00005046 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005047 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00005048 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005049 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00005050 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005051 Quals,
5052 getDerived().getBaseLocation(),
5053 getDerived().getBaseEntity());
5054}
Mike Stump11289f42009-09-09 15:08:12 +00005055
Douglas Gregord6ff3322009-08-04 16:50:30 +00005056template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00005057QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5058 return SemaRef.Context.getFunctionNoProtoType(T);
5059}
5060
5061template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005062QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005063 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5064}
5065
5066template<typename Derived>
5067QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5068 return SemaRef.Context.getTypeOfType(Underlying);
5069}
5070
5071template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005072QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005073 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5074}
5075
5076template<typename Derived>
5077QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00005078 TemplateName Template,
5079 SourceLocation TemplateNameLoc,
5080 SourceLocation LAngleLoc,
5081 const TemplateArgumentLoc *Args,
5082 unsigned NumArgs,
5083 SourceLocation RAngleLoc) {
5084 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
5085 Args, NumArgs, RAngleLoc);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005086}
Mike Stump11289f42009-09-09 15:08:12 +00005087
Douglas Gregor1135c352009-08-06 05:28:30 +00005088template<typename Derived>
5089NestedNameSpecifier *
5090TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5091 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00005092 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005093 QualType ObjectType,
5094 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00005095 CXXScopeSpec SS;
5096 // FIXME: The source location information is all wrong.
5097 SS.setRange(Range);
5098 SS.setScopeRep(Prefix);
5099 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005100 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005101 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005102 ObjectType,
5103 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005104 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005105}
5106
5107template<typename Derived>
5108NestedNameSpecifier *
5109TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5110 SourceRange Range,
5111 NamespaceDecl *NS) {
5112 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5113}
5114
5115template<typename Derived>
5116NestedNameSpecifier *
5117TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5118 SourceRange Range,
5119 bool TemplateKW,
5120 QualType T) {
5121 if (T->isDependentType() || T->isRecordType() ||
5122 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005123 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005124 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5125 T.getTypePtr());
5126 }
Mike Stump11289f42009-09-09 15:08:12 +00005127
Douglas Gregor1135c352009-08-06 05:28:30 +00005128 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5129 return 0;
5130}
Mike Stump11289f42009-09-09 15:08:12 +00005131
Douglas Gregor71dc5092009-08-06 06:41:21 +00005132template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005133TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005134TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5135 bool TemplateKW,
5136 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005137 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005138 Template);
5139}
5140
5141template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005142TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005143TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5144 bool TemplateKW,
5145 OverloadedFunctionDecl *Ovl) {
5146 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5147}
5148
5149template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005150TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005151TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005152 const IdentifierInfo &II,
5153 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005154 CXXScopeSpec SS;
5155 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005156 SS.setScopeRep(Qualifier);
Douglas Gregor308047d2009-09-09 00:23:06 +00005157 return getSema().ActOnDependentTemplateName(
5158 /*FIXME:*/getDerived().getBaseLocation(),
5159 II,
5160 /*FIXME:*/getDerived().getBaseLocation(),
5161 SS,
5162 ObjectType.getAsOpaquePtr())
5163 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005164}
Mike Stump11289f42009-09-09 15:08:12 +00005165
Douglas Gregora16548e2009-08-11 05:31:07 +00005166template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005167Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005168TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5169 SourceLocation OpLoc,
5170 ExprArg Callee,
5171 ExprArg First,
5172 ExprArg Second) {
5173 Expr *FirstExpr = (Expr *)First.get();
5174 Expr *SecondExpr = (Expr *)Second.get();
5175 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005176
Douglas Gregora16548e2009-08-11 05:31:07 +00005177 // Determine whether this should be a builtin operation.
5178 if (SecondExpr == 0 || isPostIncDec) {
5179 if (!FirstExpr->getType()->isOverloadableType()) {
5180 // The argument is not of overloadable type, so try to create a
5181 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005182 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005183 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005184
Douglas Gregora16548e2009-08-11 05:31:07 +00005185 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5186 }
5187 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005188 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005189 !SecondExpr->getType()->isOverloadableType()) {
5190 // Neither of the arguments is an overloadable type, so try to
5191 // create a built-in binary operation.
5192 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005193 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005194 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5195 if (Result.isInvalid())
5196 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005197
Douglas Gregora16548e2009-08-11 05:31:07 +00005198 First.release();
5199 Second.release();
5200 return move(Result);
5201 }
5202 }
Mike Stump11289f42009-09-09 15:08:12 +00005203
5204 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005205 // used during overload resolution.
5206 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005207
5208 DeclRefExpr *DRE
Douglas Gregor32e2c842009-09-01 16:58:52 +00005209 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Mike Stump11289f42009-09-09 15:08:12 +00005210
Douglas Gregora16548e2009-08-11 05:31:07 +00005211 // FIXME: Do we have to check
5212 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005213 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005214 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005215
Douglas Gregora16548e2009-08-11 05:31:07 +00005216 // Add any functions found via argument-dependent lookup.
5217 Expr *Args[2] = { FirstExpr, SecondExpr };
5218 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005219 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005220 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redlc057f422009-10-23 19:23:15 +00005221 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5222 Functions);
Mike Stump11289f42009-09-09 15:08:12 +00005223
Douglas Gregora16548e2009-08-11 05:31:07 +00005224 // Create the overloaded operator invocation for unary operators.
5225 if (NumArgs == 1 || isPostIncDec) {
Mike Stump11289f42009-09-09 15:08:12 +00005226 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005227 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5228 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5229 }
Mike Stump11289f42009-09-09 15:08:12 +00005230
Douglas Gregora16548e2009-08-11 05:31:07 +00005231 // Create the overloaded operator invocation for binary operators.
Mike Stump11289f42009-09-09 15:08:12 +00005232 BinaryOperator::Opcode Opc =
Douglas Gregora16548e2009-08-11 05:31:07 +00005233 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005234 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005235 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5236 if (Result.isInvalid())
5237 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005238
Douglas Gregora16548e2009-08-11 05:31:07 +00005239 First.release();
5240 Second.release();
Mike Stump11289f42009-09-09 15:08:12 +00005241 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00005242}
Mike Stump11289f42009-09-09 15:08:12 +00005243
Douglas Gregord6ff3322009-08-04 16:50:30 +00005244} // end namespace clang
5245
5246#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H