blob: d3f46694f31be47afb64f0ba563eaa96a4237d86 [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
John McCall70dd5f62009-10-30 00:06:24 +0000313 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
314
Douglas Gregorc59e5612009-10-19 22:04:39 +0000315 QualType
316 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
317 QualType ObjectType);
John McCall0ad16662009-10-29 08:12:44 +0000318
319 QualType
320 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
321 TemplateSpecializationTypeLoc TL,
322 QualType ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +0000323
Douglas Gregorebe10102009-08-20 07:17:43 +0000324 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump11289f42009-09-09 15:08:12 +0000325
Douglas Gregorebe10102009-08-20 07:17:43 +0000326#define STMT(Node, Parent) \
327 OwningStmtResult Transform##Node(Node *S);
Douglas Gregora16548e2009-08-11 05:31:07 +0000328#define EXPR(Node, Parent) \
329 OwningExprResult Transform##Node(Node *E);
330#define ABSTRACT_EXPR(Node, Parent)
331#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +0000332
Douglas Gregord6ff3322009-08-04 16:50:30 +0000333 /// \brief Build a new pointer type given its pointee type.
334 ///
335 /// By default, performs semantic analysis when building the pointer type.
336 /// Subclasses may override this routine to provide different behavior.
John McCall70dd5f62009-10-30 00:06:24 +0000337 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000338
339 /// \brief Build a new block pointer type given its pointee type.
340 ///
Mike Stump11289f42009-09-09 15:08:12 +0000341 /// By default, performs semantic analysis when building the block pointer
Douglas Gregord6ff3322009-08-04 16:50:30 +0000342 /// type. Subclasses may override this routine to provide different behavior.
John McCall70dd5f62009-10-30 00:06:24 +0000343 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000344
John McCall70dd5f62009-10-30 00:06:24 +0000345 /// \brief Build a new reference type given the type it references.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000346 ///
John McCall70dd5f62009-10-30 00:06:24 +0000347 /// By default, performs semantic analysis when building the
348 /// reference type. Subclasses may override this routine to provide
349 /// different behavior.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000350 ///
John McCall70dd5f62009-10-30 00:06:24 +0000351 /// \param LValue whether the type was written with an lvalue sigil
352 /// or an rvalue sigil.
353 QualType RebuildReferenceType(QualType ReferentType,
354 bool LValue,
355 SourceLocation Sigil);
Mike Stump11289f42009-09-09 15:08:12 +0000356
Douglas Gregord6ff3322009-08-04 16:50:30 +0000357 /// \brief Build a new member pointer type given the pointee type and the
358 /// class type it refers into.
359 ///
360 /// By default, performs semantic analysis when building the member pointer
361 /// type. Subclasses may override this routine to provide different behavior.
John McCall70dd5f62009-10-30 00:06:24 +0000362 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
363 SourceLocation Sigil);
Mike Stump11289f42009-09-09 15:08:12 +0000364
John McCall550e0c22009-10-21 00:40:46 +0000365 /// \brief Build a new Objective C object pointer type.
John McCall70dd5f62009-10-30 00:06:24 +0000366 QualType RebuildObjCObjectPointerType(QualType PointeeType,
367 SourceLocation Sigil);
John McCall550e0c22009-10-21 00:40:46 +0000368
Douglas Gregord6ff3322009-08-04 16:50:30 +0000369 /// \brief Build a new array type given the element type, size
370 /// modifier, size of the array (if known), size expression, and index type
371 /// qualifiers.
372 ///
373 /// By default, performs semantic analysis when building the array type.
374 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000375 /// Also by default, all of the other Rebuild*Array
Douglas Gregord6ff3322009-08-04 16:50:30 +0000376 QualType RebuildArrayType(QualType ElementType,
377 ArrayType::ArraySizeModifier SizeMod,
378 const llvm::APInt *Size,
379 Expr *SizeExpr,
380 unsigned IndexTypeQuals,
381 SourceRange BracketsRange);
Mike Stump11289f42009-09-09 15:08:12 +0000382
Douglas Gregord6ff3322009-08-04 16:50:30 +0000383 /// \brief Build a new constant array type given the element type, size
384 /// modifier, (known) size of the array, and index type qualifiers.
385 ///
386 /// By default, performs semantic analysis when building the array type.
387 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000388 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000389 ArrayType::ArraySizeModifier SizeMod,
390 const llvm::APInt &Size,
John McCall70dd5f62009-10-30 00:06:24 +0000391 unsigned IndexTypeQuals,
392 SourceRange BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000393
Douglas Gregord6ff3322009-08-04 16:50:30 +0000394 /// \brief Build a new incomplete array type given the element type, size
395 /// modifier, and index type qualifiers.
396 ///
397 /// By default, performs semantic analysis when building the array type.
398 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000399 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000400 ArrayType::ArraySizeModifier SizeMod,
John McCall70dd5f62009-10-30 00:06:24 +0000401 unsigned IndexTypeQuals,
402 SourceRange BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000403
Mike Stump11289f42009-09-09 15:08:12 +0000404 /// \brief Build a new variable-length array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000405 /// size modifier, size expression, and index type qualifiers.
406 ///
407 /// By default, performs semantic analysis when building the array type.
408 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000409 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000410 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000411 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000412 unsigned IndexTypeQuals,
413 SourceRange BracketsRange);
414
Mike Stump11289f42009-09-09 15:08:12 +0000415 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000416 /// size modifier, size expression, and index type qualifiers.
417 ///
418 /// By default, performs semantic analysis when building the array type.
419 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000420 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000421 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000422 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000423 unsigned IndexTypeQuals,
424 SourceRange BracketsRange);
425
426 /// \brief Build a new vector type given the element type and
427 /// number of elements.
428 ///
429 /// By default, performs semantic analysis when building the vector type.
430 /// Subclasses may override this routine to provide different behavior.
431 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump11289f42009-09-09 15:08:12 +0000432
Douglas Gregord6ff3322009-08-04 16:50:30 +0000433 /// \brief Build a new extended vector type given the element type and
434 /// number of elements.
435 ///
436 /// By default, performs semantic analysis when building the vector type.
437 /// Subclasses may override this routine to provide different behavior.
438 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
439 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000440
441 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregord6ff3322009-08-04 16:50:30 +0000442 /// given the element type and number of elements.
443 ///
444 /// By default, performs semantic analysis when building the vector type.
445 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000446 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +0000447 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000448 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000449
Douglas Gregord6ff3322009-08-04 16:50:30 +0000450 /// \brief Build a new function type.
451 ///
452 /// By default, performs semantic analysis when building the function type.
453 /// Subclasses may override this routine to provide different behavior.
454 QualType RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +0000455 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000456 unsigned NumParamTypes,
457 bool Variadic, unsigned Quals);
Mike Stump11289f42009-09-09 15:08:12 +0000458
John McCall550e0c22009-10-21 00:40:46 +0000459 /// \brief Build a new unprototyped function type.
460 QualType RebuildFunctionNoProtoType(QualType ResultType);
461
Douglas Gregord6ff3322009-08-04 16:50:30 +0000462 /// \brief Build a new typedef type.
463 QualType RebuildTypedefType(TypedefDecl *Typedef) {
464 return SemaRef.Context.getTypeDeclType(Typedef);
465 }
466
467 /// \brief Build a new class/struct/union type.
468 QualType RebuildRecordType(RecordDecl *Record) {
469 return SemaRef.Context.getTypeDeclType(Record);
470 }
471
472 /// \brief Build a new Enum type.
473 QualType RebuildEnumType(EnumDecl *Enum) {
474 return SemaRef.Context.getTypeDeclType(Enum);
475 }
John McCallfcc33b02009-09-05 00:15:47 +0000476
477 /// \brief Build a new elaborated type.
478 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
479 return SemaRef.Context.getElaboratedType(T, Tag);
480 }
Mike Stump11289f42009-09-09 15:08:12 +0000481
482 /// \brief Build a new typeof(expr) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000483 ///
484 /// By default, performs semantic analysis when building the typeof type.
485 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000486 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000487
Mike Stump11289f42009-09-09 15:08:12 +0000488 /// \brief Build a new typeof(type) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000489 ///
490 /// By default, builds a new TypeOfType with the given underlying type.
491 QualType RebuildTypeOfType(QualType Underlying);
492
Mike Stump11289f42009-09-09 15:08:12 +0000493 /// \brief Build a new C++0x decltype type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000494 ///
495 /// By default, performs semantic analysis when building the decltype type.
496 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000497 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump11289f42009-09-09 15:08:12 +0000498
Douglas Gregord6ff3322009-08-04 16:50:30 +0000499 /// \brief Build a new template specialization type.
500 ///
501 /// By default, performs semantic analysis when building the template
502 /// specialization type. Subclasses may override this routine to provide
503 /// different behavior.
504 QualType RebuildTemplateSpecializationType(TemplateName Template,
John McCall0ad16662009-10-29 08:12:44 +0000505 SourceLocation TemplateLoc,
506 SourceLocation LAngleLoc,
507 const TemplateArgumentLoc *Args,
508 unsigned NumArgs,
509 SourceLocation RAngleLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000510
Douglas Gregord6ff3322009-08-04 16:50:30 +0000511 /// \brief Build a new qualified name type.
512 ///
Mike Stump11289f42009-09-09 15:08:12 +0000513 /// By default, builds a new QualifiedNameType type from the
514 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregord6ff3322009-08-04 16:50:30 +0000515 /// this routine to provide different behavior.
516 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
517 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump11289f42009-09-09 15:08:12 +0000518 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000519
520 /// \brief Build a new typename type that refers to a template-id.
521 ///
522 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump11289f42009-09-09 15:08:12 +0000523 /// and the given type. Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000524 /// different behavior.
525 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
526 if (NNS->isDependent())
Mike Stump11289f42009-09-09 15:08:12 +0000527 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000528 cast<TemplateSpecializationType>(T));
Mike Stump11289f42009-09-09 15:08:12 +0000529
Douglas Gregord6ff3322009-08-04 16:50:30 +0000530 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump11289f42009-09-09 15:08:12 +0000531 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000532
533 /// \brief Build a new typename type that refers to an identifier.
534 ///
535 /// By default, performs semantic analysis when building the typename type
Mike Stump11289f42009-09-09 15:08:12 +0000536 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000537 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000538 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall0ad16662009-10-29 08:12:44 +0000539 const IdentifierInfo *Id,
540 SourceRange SR) {
541 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregor1135c352009-08-06 05:28:30 +0000542 }
Mike Stump11289f42009-09-09 15:08:12 +0000543
Douglas Gregor1135c352009-08-06 05:28:30 +0000544 /// \brief Build a new nested-name-specifier given the prefix and an
545 /// identifier that names the next step in the nested-name-specifier.
546 ///
547 /// By default, performs semantic analysis when building the new
548 /// nested-name-specifier. Subclasses may override this routine to provide
549 /// different behavior.
550 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
551 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000552 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000553 QualType ObjectType,
554 NamedDecl *FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +0000555
556 /// \brief Build a new nested-name-specifier given the prefix and the
557 /// namespace named in the next step in the nested-name-specifier.
558 ///
559 /// By default, performs semantic analysis when building the new
560 /// nested-name-specifier. Subclasses may override this routine to provide
561 /// different behavior.
562 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
563 SourceRange Range,
564 NamespaceDecl *NS);
565
566 /// \brief Build a new nested-name-specifier given the prefix and the
567 /// type named in the next step in the nested-name-specifier.
568 ///
569 /// By default, performs semantic analysis when building the new
570 /// nested-name-specifier. Subclasses may override this routine to provide
571 /// different behavior.
572 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
573 SourceRange Range,
574 bool TemplateKW,
575 QualType T);
Douglas Gregor71dc5092009-08-06 06:41:21 +0000576
577 /// \brief Build a new template name given a nested name specifier, a flag
578 /// indicating whether the "template" keyword was provided, and the template
579 /// that the template name refers to.
580 ///
581 /// By default, builds the new template name directly. Subclasses may override
582 /// this routine to provide different behavior.
583 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
584 bool TemplateKW,
585 TemplateDecl *Template);
586
587 /// \brief Build a new template name given a nested name specifier, a flag
588 /// indicating whether the "template" keyword was provided, and a set of
589 /// overloaded function templates.
590 ///
591 /// By default, builds the new template name directly. Subclasses may override
592 /// this routine to provide different behavior.
593 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
594 bool TemplateKW,
595 OverloadedFunctionDecl *Ovl);
Mike Stump11289f42009-09-09 15:08:12 +0000596
Douglas Gregor71dc5092009-08-06 06:41:21 +0000597 /// \brief Build a new template name given a nested name specifier and the
598 /// name that is referred to as a template.
599 ///
600 /// By default, performs semantic analysis to determine whether the name can
601 /// be resolved to a specific template, then builds the appropriate kind of
602 /// template name. Subclasses may override this routine to provide different
603 /// behavior.
604 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +0000605 const IdentifierInfo &II,
606 QualType ObjectType);
Mike Stump11289f42009-09-09 15:08:12 +0000607
608
Douglas Gregorebe10102009-08-20 07:17:43 +0000609 /// \brief Build a new compound statement.
610 ///
611 /// By default, performs semantic analysis to build the new statement.
612 /// Subclasses may override this routine to provide different behavior.
613 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
614 MultiStmtArg Statements,
615 SourceLocation RBraceLoc,
616 bool IsStmtExpr) {
617 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
618 IsStmtExpr);
619 }
620
621 /// \brief Build a new case statement.
622 ///
623 /// By default, performs semantic analysis to build the new statement.
624 /// Subclasses may override this routine to provide different behavior.
625 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
626 ExprArg LHS,
627 SourceLocation EllipsisLoc,
628 ExprArg RHS,
629 SourceLocation ColonLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000630 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregorebe10102009-08-20 07:17:43 +0000631 ColonLoc);
632 }
Mike Stump11289f42009-09-09 15:08:12 +0000633
Douglas Gregorebe10102009-08-20 07:17:43 +0000634 /// \brief Attach the body to a new case statement.
635 ///
636 /// By default, performs semantic analysis to build the new statement.
637 /// Subclasses may override this routine to provide different behavior.
638 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
639 getSema().ActOnCaseStmtBody(S.get(), move(Body));
640 return move(S);
641 }
Mike Stump11289f42009-09-09 15:08:12 +0000642
Douglas Gregorebe10102009-08-20 07:17:43 +0000643 /// \brief Build a new default statement.
644 ///
645 /// By default, performs semantic analysis to build the new statement.
646 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000647 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000648 SourceLocation ColonLoc,
649 StmtArg SubStmt) {
Mike Stump11289f42009-09-09 15:08:12 +0000650 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregorebe10102009-08-20 07:17:43 +0000651 /*CurScope=*/0);
652 }
Mike Stump11289f42009-09-09 15:08:12 +0000653
Douglas Gregorebe10102009-08-20 07:17:43 +0000654 /// \brief Build a new label statement.
655 ///
656 /// By default, performs semantic analysis to build the new statement.
657 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000658 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000659 IdentifierInfo *Id,
660 SourceLocation ColonLoc,
661 StmtArg SubStmt) {
662 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
663 }
Mike Stump11289f42009-09-09 15:08:12 +0000664
Douglas Gregorebe10102009-08-20 07:17:43 +0000665 /// \brief Build a new "if" statement.
666 ///
667 /// By default, performs semantic analysis to build the new statement.
668 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000669 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
670 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000671 StmtArg Else) {
672 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
673 }
Mike Stump11289f42009-09-09 15:08:12 +0000674
Douglas Gregorebe10102009-08-20 07:17:43 +0000675 /// \brief Start building a new switch statement.
676 ///
677 /// By default, performs semantic analysis to build the new statement.
678 /// Subclasses may override this routine to provide different behavior.
679 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
680 return getSema().ActOnStartOfSwitchStmt(move(Cond));
681 }
Mike Stump11289f42009-09-09 15:08:12 +0000682
Douglas Gregorebe10102009-08-20 07:17:43 +0000683 /// \brief Attach the body to the switch statement.
684 ///
685 /// By default, performs semantic analysis to build the new statement.
686 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000687 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000688 StmtArg Switch, StmtArg Body) {
689 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
690 move(Body));
691 }
692
693 /// \brief Build a new while statement.
694 ///
695 /// By default, performs semantic analysis to build the new statement.
696 /// Subclasses may override this routine to provide different behavior.
697 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
698 Sema::FullExprArg Cond,
699 StmtArg Body) {
700 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
701 }
Mike Stump11289f42009-09-09 15:08:12 +0000702
Douglas Gregorebe10102009-08-20 07:17:43 +0000703 /// \brief Build a new do-while statement.
704 ///
705 /// By default, performs semantic analysis to build the new statement.
706 /// Subclasses may override this routine to provide different behavior.
707 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
708 SourceLocation WhileLoc,
709 SourceLocation LParenLoc,
710 ExprArg Cond,
711 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000712 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000713 move(Cond), RParenLoc);
714 }
715
716 /// \brief Build a new for statement.
717 ///
718 /// By default, performs semantic analysis to build the new statement.
719 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000720 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000721 SourceLocation LParenLoc,
722 StmtArg Init, ExprArg Cond, ExprArg Inc,
723 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump11289f42009-09-09 15:08:12 +0000724 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregorebe10102009-08-20 07:17:43 +0000725 move(Inc), RParenLoc, move(Body));
726 }
Mike Stump11289f42009-09-09 15:08:12 +0000727
Douglas Gregorebe10102009-08-20 07:17:43 +0000728 /// \brief Build a new goto statement.
729 ///
730 /// By default, performs semantic analysis to build the new statement.
731 /// Subclasses may override this routine to provide different behavior.
732 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
733 SourceLocation LabelLoc,
734 LabelStmt *Label) {
735 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
736 }
737
738 /// \brief Build a new indirect goto statement.
739 ///
740 /// By default, performs semantic analysis to build the new statement.
741 /// Subclasses may override this routine to provide different behavior.
742 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
743 SourceLocation StarLoc,
744 ExprArg Target) {
745 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
746 }
Mike Stump11289f42009-09-09 15:08:12 +0000747
Douglas Gregorebe10102009-08-20 07:17:43 +0000748 /// \brief Build a new return statement.
749 ///
750 /// By default, performs semantic analysis to build the new statement.
751 /// Subclasses may override this routine to provide different behavior.
752 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
753 ExprArg Result) {
Mike Stump11289f42009-09-09 15:08:12 +0000754
Douglas Gregorebe10102009-08-20 07:17:43 +0000755 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
756 }
Mike Stump11289f42009-09-09 15:08:12 +0000757
Douglas Gregorebe10102009-08-20 07:17:43 +0000758 /// \brief Build a new declaration statement.
759 ///
760 /// By default, performs semantic analysis to build the new statement.
761 /// Subclasses may override this routine to provide different behavior.
762 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump11289f42009-09-09 15:08:12 +0000763 SourceLocation StartLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000764 SourceLocation EndLoc) {
765 return getSema().Owned(
766 new (getSema().Context) DeclStmt(
767 DeclGroupRef::Create(getSema().Context,
768 Decls, NumDecls),
769 StartLoc, EndLoc));
770 }
Mike Stump11289f42009-09-09 15:08:12 +0000771
Douglas Gregorebe10102009-08-20 07:17:43 +0000772 /// \brief Build a new C++ exception declaration.
773 ///
774 /// By default, performs semantic analysis to build the new decaration.
775 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000776 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregorebe10102009-08-20 07:17:43 +0000777 DeclaratorInfo *Declarator,
778 IdentifierInfo *Name,
779 SourceLocation Loc,
780 SourceRange TypeRange) {
Mike Stump11289f42009-09-09 15:08:12 +0000781 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000782 TypeRange);
783 }
784
785 /// \brief Build a new C++ catch statement.
786 ///
787 /// By default, performs semantic analysis to build the new statement.
788 /// Subclasses may override this routine to provide different behavior.
789 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
790 VarDecl *ExceptionDecl,
791 StmtArg Handler) {
792 return getSema().Owned(
Mike Stump11289f42009-09-09 15:08:12 +0000793 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregorebe10102009-08-20 07:17:43 +0000794 Handler.takeAs<Stmt>()));
795 }
Mike Stump11289f42009-09-09 15:08:12 +0000796
Douglas Gregorebe10102009-08-20 07:17:43 +0000797 /// \brief Build a new C++ try statement.
798 ///
799 /// By default, performs semantic analysis to build the new statement.
800 /// Subclasses may override this routine to provide different behavior.
801 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
802 StmtArg TryBlock,
803 MultiStmtArg Handlers) {
804 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
805 }
Mike Stump11289f42009-09-09 15:08:12 +0000806
Douglas Gregora16548e2009-08-11 05:31:07 +0000807 /// \brief Build a new expression that references a declaration.
808 ///
809 /// By default, performs semantic analysis to build the new expression.
810 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000811 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
812 SourceRange QualifierRange,
813 NamedDecl *ND, SourceLocation Loc) {
814 CXXScopeSpec SS;
815 SS.setScopeRep(Qualifier);
816 SS.setRange(QualifierRange);
Douglas Gregora16548e2009-08-11 05:31:07 +0000817 return getSema().BuildDeclarationNameExpr(Loc, ND,
818 /*FIXME:*/false,
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000819 &SS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000820 /*FIXME:*/false);
821 }
Mike Stump11289f42009-09-09 15:08:12 +0000822
Douglas Gregora16548e2009-08-11 05:31:07 +0000823 /// \brief Build a new expression in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +0000824 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000825 /// By default, performs semantic analysis to build the new expression.
826 /// Subclasses may override this routine to provide different behavior.
827 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
828 SourceLocation RParen) {
829 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
830 }
831
Douglas Gregorad8a3362009-09-04 17:36:40 +0000832 /// \brief Build a new pseudo-destructor expression.
Mike Stump11289f42009-09-09 15:08:12 +0000833 ///
Douglas Gregorad8a3362009-09-04 17:36:40 +0000834 /// By default, performs semantic analysis to build the new expression.
835 /// Subclasses may override this routine to provide different behavior.
836 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
837 SourceLocation OperatorLoc,
838 bool isArrow,
839 SourceLocation DestroyedTypeLoc,
840 QualType DestroyedType,
841 NestedNameSpecifier *Qualifier,
842 SourceRange QualifierRange) {
843 CXXScopeSpec SS;
844 if (Qualifier) {
845 SS.setRange(QualifierRange);
846 SS.setScopeRep(Qualifier);
847 }
848
Mike Stump11289f42009-09-09 15:08:12 +0000849 DeclarationName Name
Douglas Gregorad8a3362009-09-04 17:36:40 +0000850 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
851 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump11289f42009-09-09 15:08:12 +0000852
853 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorad8a3362009-09-04 17:36:40 +0000854 OperatorLoc,
855 isArrow? tok::arrow : tok::period,
856 DestroyedTypeLoc,
857 Name,
858 Sema::DeclPtrTy::make((Decl *)0),
859 &SS);
Mike Stump11289f42009-09-09 15:08:12 +0000860 }
861
Douglas Gregora16548e2009-08-11 05:31:07 +0000862 /// \brief Build a new unary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000863 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000864 /// By default, performs semantic analysis to build the new expression.
865 /// Subclasses may override this routine to provide different behavior.
866 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
867 UnaryOperator::Opcode Opc,
868 ExprArg SubExpr) {
869 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
870 }
Mike Stump11289f42009-09-09 15:08:12 +0000871
Douglas Gregora16548e2009-08-11 05:31:07 +0000872 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump11289f42009-09-09 15:08:12 +0000873 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000874 /// By default, performs semantic analysis to build the new expression.
875 /// Subclasses may override this routine to provide different behavior.
876 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
877 bool isSizeOf, SourceRange R) {
878 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
879 }
880
Mike Stump11289f42009-09-09 15:08:12 +0000881 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000882 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000883 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000884 /// By default, performs semantic analysis to build the new expression.
885 /// Subclasses may override this routine to provide different behavior.
886 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
887 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000888 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000889 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
890 OpLoc, isSizeOf, R);
891 if (Result.isInvalid())
892 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000893
Douglas Gregora16548e2009-08-11 05:31:07 +0000894 SubExpr.release();
895 return move(Result);
896 }
Mike Stump11289f42009-09-09 15:08:12 +0000897
Douglas Gregora16548e2009-08-11 05:31:07 +0000898 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000899 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000900 /// By default, performs semantic analysis to build the new expression.
901 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000902 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000903 SourceLocation LBracketLoc,
904 ExprArg RHS,
905 SourceLocation RBracketLoc) {
906 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000907 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000908 RBracketLoc);
909 }
910
911 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000912 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000913 /// By default, performs semantic analysis to build the new expression.
914 /// Subclasses may override this routine to provide different behavior.
915 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
916 MultiExprArg Args,
917 SourceLocation *CommaLocs,
918 SourceLocation RParenLoc) {
919 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
920 move(Args), CommaLocs, RParenLoc);
921 }
922
923 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000924 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000925 /// By default, performs semantic analysis to build the new expression.
926 /// Subclasses may override this routine to provide different behavior.
927 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000928 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000929 NestedNameSpecifier *Qualifier,
930 SourceRange QualifierRange,
931 SourceLocation MemberLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000932 NamedDecl *Member) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000933 if (!Member->getDeclName()) {
934 // We have a reference to an unnamed field.
935 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000936
937 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000938 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
939 Member, MemberLoc,
940 cast<FieldDecl>(Member)->getType());
941 return getSema().Owned(ME);
942 }
Mike Stump11289f42009-09-09 15:08:12 +0000943
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000944 CXXScopeSpec SS;
945 if (Qualifier) {
946 SS.setRange(QualifierRange);
947 SS.setScopeRep(Qualifier);
948 }
949
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000950 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000951 isArrow? tok::arrow : tok::period,
952 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000953 Member->getDeclName(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000954 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
955 &SS);
Douglas Gregora16548e2009-08-11 05:31:07 +0000956 }
Mike Stump11289f42009-09-09 15:08:12 +0000957
Douglas Gregora16548e2009-08-11 05:31:07 +0000958 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000959 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000960 /// By default, performs semantic analysis to build the new expression.
961 /// Subclasses may override this routine to provide different behavior.
962 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
963 BinaryOperator::Opcode Opc,
964 ExprArg LHS, ExprArg RHS) {
965 OwningExprResult Result
Mike Stump11289f42009-09-09 15:08:12 +0000966 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +0000967 (Expr *)RHS.get());
968 if (Result.isInvalid())
969 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000970
Douglas Gregora16548e2009-08-11 05:31:07 +0000971 LHS.release();
972 RHS.release();
973 return move(Result);
974 }
975
976 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000977 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000978 /// By default, performs semantic analysis to build the new expression.
979 /// Subclasses may override this routine to provide different behavior.
980 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
981 SourceLocation QuestionLoc,
982 ExprArg LHS,
983 SourceLocation ColonLoc,
984 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +0000985 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +0000986 move(LHS), move(RHS));
987 }
988
989 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000990 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000991 /// By default, builds a new implicit cast without any semantic analysis.
992 /// Subclasses may override this routine to provide different behavior.
993 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
994 ExprArg SubExpr, bool isLvalue) {
995 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +0000996 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +0000997 (Expr *)SubExpr.release(),
998 isLvalue);
999 return getSema().Owned(ICE);
1000 }
1001
1002 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +00001003 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001004 /// By default, performs semantic analysis to build the new expression.
1005 /// Subclasses may override this routine to provide different behavior.
1006 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1007 QualType ExplicitTy,
1008 SourceLocation RParenLoc,
1009 ExprArg SubExpr) {
1010 return getSema().ActOnCastExpr(/*Scope=*/0,
1011 LParenLoc,
1012 ExplicitTy.getAsOpaquePtr(),
1013 RParenLoc,
1014 move(SubExpr));
1015 }
Mike Stump11289f42009-09-09 15:08:12 +00001016
Douglas Gregora16548e2009-08-11 05:31:07 +00001017 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +00001018 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001019 /// By default, performs semantic analysis to build the new expression.
1020 /// Subclasses may override this routine to provide different behavior.
1021 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1022 QualType T,
1023 SourceLocation RParenLoc,
1024 ExprArg Init) {
1025 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1026 RParenLoc, move(Init));
1027 }
Mike Stump11289f42009-09-09 15:08:12 +00001028
Douglas Gregora16548e2009-08-11 05:31:07 +00001029 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +00001030 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001031 /// By default, performs semantic analysis to build the new expression.
1032 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001033 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001034 SourceLocation OpLoc,
1035 SourceLocation AccessorLoc,
1036 IdentifierInfo &Accessor) {
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001037 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001038 tok::period, AccessorLoc,
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001039 DeclarationName(&Accessor),
Douglas Gregora16548e2009-08-11 05:31:07 +00001040 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1041 }
Mike Stump11289f42009-09-09 15:08:12 +00001042
Douglas Gregora16548e2009-08-11 05:31:07 +00001043 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001044 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001045 /// By default, performs semantic analysis to build the new expression.
1046 /// Subclasses may override this routine to provide different behavior.
1047 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1048 MultiExprArg Inits,
1049 SourceLocation RBraceLoc) {
1050 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1051 }
Mike Stump11289f42009-09-09 15:08:12 +00001052
Douglas Gregora16548e2009-08-11 05:31:07 +00001053 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001054 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001055 /// By default, performs semantic analysis to build the new expression.
1056 /// Subclasses may override this routine to provide different behavior.
1057 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1058 MultiExprArg ArrayExprs,
1059 SourceLocation EqualOrColonLoc,
1060 bool GNUSyntax,
1061 ExprArg Init) {
1062 OwningExprResult Result
1063 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1064 move(Init));
1065 if (Result.isInvalid())
1066 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001067
Douglas Gregora16548e2009-08-11 05:31:07 +00001068 ArrayExprs.release();
1069 return move(Result);
1070 }
Mike Stump11289f42009-09-09 15:08:12 +00001071
Douglas Gregora16548e2009-08-11 05:31:07 +00001072 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001073 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001074 /// By default, builds the implicit value initialization without performing
1075 /// any semantic analysis. Subclasses may override this routine to provide
1076 /// different behavior.
1077 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1078 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1079 }
Mike Stump11289f42009-09-09 15:08:12 +00001080
Douglas Gregora16548e2009-08-11 05:31:07 +00001081 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001082 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001083 /// By default, performs semantic analysis to build the new expression.
1084 /// Subclasses may override this routine to provide different behavior.
1085 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1086 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001087 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001088 RParenLoc);
1089 }
1090
1091 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001092 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001093 /// By default, performs semantic analysis to build the new expression.
1094 /// Subclasses may override this routine to provide different behavior.
1095 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1096 MultiExprArg SubExprs,
1097 SourceLocation RParenLoc) {
1098 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1099 }
Mike Stump11289f42009-09-09 15:08:12 +00001100
Douglas Gregora16548e2009-08-11 05:31:07 +00001101 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001102 ///
1103 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001104 /// rather than attempting to map the label statement itself.
1105 /// Subclasses may override this routine to provide different behavior.
1106 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1107 SourceLocation LabelLoc,
1108 LabelStmt *Label) {
1109 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1110 }
Mike Stump11289f42009-09-09 15:08:12 +00001111
Douglas Gregora16548e2009-08-11 05:31:07 +00001112 /// \brief Build a new GNU statement expression.
Mike Stump11289f42009-09-09 15:08:12 +00001113 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001114 /// By default, performs semantic analysis to build the new expression.
1115 /// Subclasses may override this routine to provide different behavior.
1116 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1117 StmtArg SubStmt,
1118 SourceLocation RParenLoc) {
1119 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1120 }
Mike Stump11289f42009-09-09 15:08:12 +00001121
Douglas Gregora16548e2009-08-11 05:31:07 +00001122 /// \brief Build a new __builtin_types_compatible_p expression.
1123 ///
1124 /// By default, performs semantic analysis to build the new expression.
1125 /// Subclasses may override this routine to provide different behavior.
1126 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1127 QualType T1, QualType T2,
1128 SourceLocation RParenLoc) {
1129 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1130 T1.getAsOpaquePtr(),
1131 T2.getAsOpaquePtr(),
1132 RParenLoc);
1133 }
Mike Stump11289f42009-09-09 15:08:12 +00001134
Douglas Gregora16548e2009-08-11 05:31:07 +00001135 /// \brief Build a new __builtin_choose_expr expression.
1136 ///
1137 /// By default, performs semantic analysis to build the new expression.
1138 /// Subclasses may override this routine to provide different behavior.
1139 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1140 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1141 SourceLocation RParenLoc) {
1142 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1143 move(Cond), move(LHS), move(RHS),
1144 RParenLoc);
1145 }
Mike Stump11289f42009-09-09 15:08:12 +00001146
Douglas Gregora16548e2009-08-11 05:31:07 +00001147 /// \brief Build a new overloaded operator call expression.
1148 ///
1149 /// By default, performs semantic analysis to build the new expression.
1150 /// The semantic analysis provides the behavior of template instantiation,
1151 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001152 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001153 /// argument-dependent lookup, etc. Subclasses may override this routine to
1154 /// provide different behavior.
1155 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1156 SourceLocation OpLoc,
1157 ExprArg Callee,
1158 ExprArg First,
1159 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001160
1161 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001162 /// reinterpret_cast.
1163 ///
1164 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001165 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001166 /// Subclasses may override this routine to provide different behavior.
1167 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1168 Stmt::StmtClass Class,
1169 SourceLocation LAngleLoc,
1170 QualType T,
1171 SourceLocation RAngleLoc,
1172 SourceLocation LParenLoc,
1173 ExprArg SubExpr,
1174 SourceLocation RParenLoc) {
1175 switch (Class) {
1176 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001177 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1178 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001179 move(SubExpr), RParenLoc);
1180
1181 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001182 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1183 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001184 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001185
Douglas Gregora16548e2009-08-11 05:31:07 +00001186 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001187 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1188 RAngleLoc, LParenLoc,
1189 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001190 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001191
Douglas Gregora16548e2009-08-11 05:31:07 +00001192 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001193 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1194 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001195 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001196
Douglas Gregora16548e2009-08-11 05:31:07 +00001197 default:
1198 assert(false && "Invalid C++ named cast");
1199 break;
1200 }
Mike Stump11289f42009-09-09 15:08:12 +00001201
Douglas Gregora16548e2009-08-11 05:31:07 +00001202 return getSema().ExprError();
1203 }
Mike Stump11289f42009-09-09 15:08:12 +00001204
Douglas Gregora16548e2009-08-11 05:31:07 +00001205 /// \brief Build a new C++ static_cast expression.
1206 ///
1207 /// By default, performs semantic analysis to build the new expression.
1208 /// Subclasses may override this routine to provide different behavior.
1209 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1210 SourceLocation LAngleLoc,
1211 QualType T,
1212 SourceLocation RAngleLoc,
1213 SourceLocation LParenLoc,
1214 ExprArg SubExpr,
1215 SourceLocation RParenLoc) {
1216 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001217 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001218 LParenLoc, move(SubExpr), RParenLoc);
1219 }
1220
1221 /// \brief Build a new C++ dynamic_cast expression.
1222 ///
1223 /// By default, performs semantic analysis to build the new expression.
1224 /// Subclasses may override this routine to provide different behavior.
1225 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1226 SourceLocation LAngleLoc,
1227 QualType T,
1228 SourceLocation RAngleLoc,
1229 SourceLocation LParenLoc,
1230 ExprArg SubExpr,
1231 SourceLocation RParenLoc) {
1232 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001233 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001234 LParenLoc, move(SubExpr), RParenLoc);
1235 }
1236
1237 /// \brief Build a new C++ reinterpret_cast expression.
1238 ///
1239 /// By default, performs semantic analysis to build the new expression.
1240 /// Subclasses may override this routine to provide different behavior.
1241 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1242 SourceLocation LAngleLoc,
1243 QualType T,
1244 SourceLocation RAngleLoc,
1245 SourceLocation LParenLoc,
1246 ExprArg SubExpr,
1247 SourceLocation RParenLoc) {
1248 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1249 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1250 LParenLoc, move(SubExpr), RParenLoc);
1251 }
1252
1253 /// \brief Build a new C++ const_cast expression.
1254 ///
1255 /// By default, performs semantic analysis to build the new expression.
1256 /// Subclasses may override this routine to provide different behavior.
1257 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1258 SourceLocation LAngleLoc,
1259 QualType T,
1260 SourceLocation RAngleLoc,
1261 SourceLocation LParenLoc,
1262 ExprArg SubExpr,
1263 SourceLocation RParenLoc) {
1264 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001265 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001266 LParenLoc, move(SubExpr), RParenLoc);
1267 }
Mike Stump11289f42009-09-09 15:08:12 +00001268
Douglas Gregora16548e2009-08-11 05:31:07 +00001269 /// \brief Build a new C++ functional-style cast expression.
1270 ///
1271 /// By default, performs semantic analysis to build the new expression.
1272 /// Subclasses may override this routine to provide different behavior.
1273 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1274 QualType T,
1275 SourceLocation LParenLoc,
1276 ExprArg SubExpr,
1277 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001278 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001279 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1280 T.getAsOpaquePtr(),
1281 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001282 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001283 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001284 RParenLoc);
1285 }
Mike Stump11289f42009-09-09 15:08:12 +00001286
Douglas Gregora16548e2009-08-11 05:31:07 +00001287 /// \brief Build a new C++ typeid(type) expression.
1288 ///
1289 /// By default, performs semantic analysis to build the new expression.
1290 /// Subclasses may override this routine to provide different behavior.
1291 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1292 SourceLocation LParenLoc,
1293 QualType T,
1294 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001295 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001296 T.getAsOpaquePtr(), RParenLoc);
1297 }
Mike Stump11289f42009-09-09 15:08:12 +00001298
Douglas Gregora16548e2009-08-11 05:31:07 +00001299 /// \brief Build a new C++ typeid(expr) expression.
1300 ///
1301 /// By default, performs semantic analysis to build the new expression.
1302 /// Subclasses may override this routine to provide different behavior.
1303 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1304 SourceLocation LParenLoc,
1305 ExprArg Operand,
1306 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001307 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001308 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1309 RParenLoc);
1310 if (Result.isInvalid())
1311 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001312
Douglas Gregora16548e2009-08-11 05:31:07 +00001313 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1314 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001315 }
1316
Douglas Gregora16548e2009-08-11 05:31:07 +00001317 /// \brief Build a new C++ "this" expression.
1318 ///
1319 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001320 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001321 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001322 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001323 QualType ThisType) {
1324 return getSema().Owned(
1325 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1326 }
1327
1328 /// \brief Build a new C++ throw expression.
1329 ///
1330 /// By default, performs semantic analysis to build the new expression.
1331 /// Subclasses may override this routine to provide different behavior.
1332 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1333 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1334 }
1335
1336 /// \brief Build a new C++ default-argument expression.
1337 ///
1338 /// By default, builds a new default-argument expression, which does not
1339 /// require any semantic analysis. Subclasses may override this routine to
1340 /// provide different behavior.
1341 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001342 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001343 }
1344
1345 /// \brief Build a new C++ zero-initialization expression.
1346 ///
1347 /// By default, performs semantic analysis to build the new expression.
1348 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001349 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001350 SourceLocation LParenLoc,
1351 QualType T,
1352 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001353 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1354 T.getAsOpaquePtr(), LParenLoc,
1355 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001356 0, RParenLoc);
1357 }
Mike Stump11289f42009-09-09 15:08:12 +00001358
Douglas Gregora16548e2009-08-11 05:31:07 +00001359 /// \brief Build a new C++ conditional declaration expression.
1360 ///
1361 /// By default, performs semantic analysis to build the new expression.
1362 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001363 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001364 SourceLocation EqLoc,
1365 VarDecl *Var) {
1366 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1367 EqLoc,
1368 Var));
1369 }
Mike Stump11289f42009-09-09 15:08:12 +00001370
Douglas Gregora16548e2009-08-11 05:31:07 +00001371 /// \brief Build a new C++ "new" expression.
1372 ///
1373 /// By default, performs semantic analysis to build the new expression.
1374 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001375 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001376 bool UseGlobal,
1377 SourceLocation PlacementLParen,
1378 MultiExprArg PlacementArgs,
1379 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001380 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001381 QualType AllocType,
1382 SourceLocation TypeLoc,
1383 SourceRange TypeRange,
1384 ExprArg ArraySize,
1385 SourceLocation ConstructorLParen,
1386 MultiExprArg ConstructorArgs,
1387 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001388 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001389 PlacementLParen,
1390 move(PlacementArgs),
1391 PlacementRParen,
1392 ParenTypeId,
1393 AllocType,
1394 TypeLoc,
1395 TypeRange,
1396 move(ArraySize),
1397 ConstructorLParen,
1398 move(ConstructorArgs),
1399 ConstructorRParen);
1400 }
Mike Stump11289f42009-09-09 15:08:12 +00001401
Douglas Gregora16548e2009-08-11 05:31:07 +00001402 /// \brief Build a new C++ "delete" expression.
1403 ///
1404 /// By default, performs semantic analysis to build the new expression.
1405 /// Subclasses may override this routine to provide different behavior.
1406 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1407 bool IsGlobalDelete,
1408 bool IsArrayForm,
1409 ExprArg Operand) {
1410 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1411 move(Operand));
1412 }
Mike Stump11289f42009-09-09 15:08:12 +00001413
Douglas Gregora16548e2009-08-11 05:31:07 +00001414 /// \brief Build a new unary type trait expression.
1415 ///
1416 /// By default, performs semantic analysis to build the new expression.
1417 /// Subclasses may override this routine to provide different behavior.
1418 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1419 SourceLocation StartLoc,
1420 SourceLocation LParenLoc,
1421 QualType T,
1422 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001423 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001424 T.getAsOpaquePtr(), RParenLoc);
1425 }
1426
Mike Stump11289f42009-09-09 15:08:12 +00001427 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001428 /// expression.
1429 ///
1430 /// By default, performs semantic analysis to build the new expression.
1431 /// Subclasses may override this routine to provide different behavior.
1432 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1433 SourceRange QualifierRange,
1434 DeclarationName Name,
1435 SourceLocation Location,
1436 bool IsAddressOfOperand) {
1437 CXXScopeSpec SS;
1438 SS.setRange(QualifierRange);
1439 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001440 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001441 Location,
1442 Name,
1443 /*Trailing lparen=*/false,
1444 &SS,
1445 IsAddressOfOperand);
1446 }
1447
1448 /// \brief Build a new template-id expression.
1449 ///
1450 /// By default, performs semantic analysis to build the new expression.
1451 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001452 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1453 SourceRange QualifierRange,
1454 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001455 SourceLocation TemplateLoc,
1456 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001457 TemplateArgumentLoc *TemplateArgs,
Douglas Gregora16548e2009-08-11 05:31:07 +00001458 unsigned NumTemplateArgs,
1459 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001460 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1461 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001462 LAngleLoc,
1463 TemplateArgs, NumTemplateArgs,
1464 RAngleLoc);
1465 }
1466
1467 /// \brief Build a new object-construction expression.
1468 ///
1469 /// By default, performs semantic analysis to build the new expression.
1470 /// Subclasses may override this routine to provide different behavior.
1471 OwningExprResult RebuildCXXConstructExpr(QualType T,
1472 CXXConstructorDecl *Constructor,
1473 bool IsElidable,
1474 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001475 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1476 SourceLocation(),
1477 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001478 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001479 }
1480
1481 /// \brief Build a new object-construction expression.
1482 ///
1483 /// By default, performs semantic analysis to build the new expression.
1484 /// Subclasses may override this routine to provide different behavior.
1485 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1486 QualType T,
1487 SourceLocation LParenLoc,
1488 MultiExprArg Args,
1489 SourceLocation *Commas,
1490 SourceLocation RParenLoc) {
1491 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1492 T.getAsOpaquePtr(),
1493 LParenLoc,
1494 move(Args),
1495 Commas,
1496 RParenLoc);
1497 }
1498
1499 /// \brief Build a new object-construction expression.
1500 ///
1501 /// By default, performs semantic analysis to build the new expression.
1502 /// Subclasses may override this routine to provide different behavior.
1503 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1504 QualType T,
1505 SourceLocation LParenLoc,
1506 MultiExprArg Args,
1507 SourceLocation *Commas,
1508 SourceLocation RParenLoc) {
1509 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1510 /*FIXME*/LParenLoc),
1511 T.getAsOpaquePtr(),
1512 LParenLoc,
1513 move(Args),
1514 Commas,
1515 RParenLoc);
1516 }
Mike Stump11289f42009-09-09 15:08:12 +00001517
Douglas Gregora16548e2009-08-11 05:31:07 +00001518 /// \brief Build a new member reference expression.
1519 ///
1520 /// By default, performs semantic analysis to build the new expression.
1521 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001522 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001523 bool IsArrow,
1524 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001525 NestedNameSpecifier *Qualifier,
1526 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001527 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001528 SourceLocation MemberLoc,
1529 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001530 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001531 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001532
Douglas Gregora16548e2009-08-11 05:31:07 +00001533 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001534 SS.setRange(QualifierRange);
1535 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001536
Douglas Gregor308047d2009-09-09 00:23:06 +00001537 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001538 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001539 MemberLoc,
1540 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001541 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001542 &SS,
1543 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001544 }
1545
Douglas Gregor308047d2009-09-09 00:23:06 +00001546 /// \brief Build a new member reference expression with explicit template
1547 /// arguments.
1548 ///
1549 /// By default, performs semantic analysis to build the new expression.
1550 /// Subclasses may override this routine to provide different behavior.
1551 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1552 bool IsArrow,
1553 SourceLocation OperatorLoc,
1554 NestedNameSpecifier *Qualifier,
1555 SourceRange QualifierRange,
1556 TemplateName Template,
1557 SourceLocation TemplateNameLoc,
1558 NamedDecl *FirstQualifierInScope,
1559 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001560 const TemplateArgumentLoc *TemplateArgs,
Douglas Gregor308047d2009-09-09 00:23:06 +00001561 unsigned NumTemplateArgs,
1562 SourceLocation RAngleLoc) {
1563 OwningExprResult Base = move(BaseE);
1564 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001565
Douglas Gregor308047d2009-09-09 00:23:06 +00001566 CXXScopeSpec SS;
1567 SS.setRange(QualifierRange);
1568 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001569
Douglas Gregor308047d2009-09-09 00:23:06 +00001570 // FIXME: We're going to end up looking up the template based on its name,
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001571 // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
Douglas Gregor308047d2009-09-09 00:23:06 +00001572 DeclarationName Name;
1573 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1574 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001575 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001576 = Template.getAsOverloadedFunctionDecl())
1577 Name = Ovl->getDeclName();
1578 else
1579 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump11289f42009-09-09 15:08:12 +00001580
1581 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001582 OperatorLoc, OpKind,
1583 TemplateNameLoc, Name, true,
1584 LAngleLoc, TemplateArgs,
1585 NumTemplateArgs, RAngleLoc,
1586 Sema::DeclPtrTy(), &SS);
1587 }
Mike Stump11289f42009-09-09 15:08:12 +00001588
Douglas Gregora16548e2009-08-11 05:31:07 +00001589 /// \brief Build a new Objective-C @encode expression.
1590 ///
1591 /// By default, performs semantic analysis to build the new expression.
1592 /// Subclasses may override this routine to provide different behavior.
1593 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1594 QualType T,
1595 SourceLocation RParenLoc) {
1596 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1597 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001598 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001599
1600 /// \brief Build a new Objective-C protocol expression.
1601 ///
1602 /// By default, performs semantic analysis to build the new expression.
1603 /// Subclasses may override this routine to provide different behavior.
1604 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1605 SourceLocation AtLoc,
1606 SourceLocation ProtoLoc,
1607 SourceLocation LParenLoc,
1608 SourceLocation RParenLoc) {
1609 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1610 Protocol->getIdentifier(),
1611 AtLoc,
1612 ProtoLoc,
1613 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001614 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001615 }
Mike Stump11289f42009-09-09 15:08:12 +00001616
Douglas Gregora16548e2009-08-11 05:31:07 +00001617 /// \brief Build a new shuffle vector expression.
1618 ///
1619 /// By default, performs semantic analysis to build the new expression.
1620 /// Subclasses may override this routine to provide different behavior.
1621 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1622 MultiExprArg SubExprs,
1623 SourceLocation RParenLoc) {
1624 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001625 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001626 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1627 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1628 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1629 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001630
Douglas Gregora16548e2009-08-11 05:31:07 +00001631 // Build a reference to the __builtin_shufflevector builtin
1632 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001633 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001634 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1635 BuiltinLoc, false, false);
1636 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001637
1638 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001639 unsigned NumSubExprs = SubExprs.size();
1640 Expr **Subs = (Expr **)SubExprs.release();
1641 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1642 Subs, NumSubExprs,
1643 Builtin->getResultType(),
1644 RParenLoc);
1645 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001646
Douglas Gregora16548e2009-08-11 05:31:07 +00001647 // Type-check the __builtin_shufflevector expression.
1648 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1649 if (Result.isInvalid())
1650 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001651
Douglas Gregora16548e2009-08-11 05:31:07 +00001652 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001653 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001654 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001655};
Douglas Gregora16548e2009-08-11 05:31:07 +00001656
Douglas Gregorebe10102009-08-20 07:17:43 +00001657template<typename Derived>
1658Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1659 if (!S)
1660 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001661
Douglas Gregorebe10102009-08-20 07:17:43 +00001662 switch (S->getStmtClass()) {
1663 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001664
Douglas Gregorebe10102009-08-20 07:17:43 +00001665 // Transform individual statement nodes
1666#define STMT(Node, Parent) \
1667 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1668#define EXPR(Node, Parent)
1669#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001670
Douglas Gregorebe10102009-08-20 07:17:43 +00001671 // Transform expressions by calling TransformExpr.
1672#define STMT(Node, Parent)
1673#define EXPR(Node, Parent) case Stmt::Node##Class:
1674#include "clang/AST/StmtNodes.def"
1675 {
1676 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1677 if (E.isInvalid())
1678 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001679
Douglas Gregorebe10102009-08-20 07:17:43 +00001680 return getSema().Owned(E.takeAs<Stmt>());
1681 }
Mike Stump11289f42009-09-09 15:08:12 +00001682 }
1683
Douglas Gregorebe10102009-08-20 07:17:43 +00001684 return SemaRef.Owned(S->Retain());
1685}
Mike Stump11289f42009-09-09 15:08:12 +00001686
1687
Douglas Gregore922c772009-08-04 22:27:00 +00001688template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001689Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1690 bool isAddressOfOperand) {
1691 if (!E)
1692 return SemaRef.Owned(E);
1693
1694 switch (E->getStmtClass()) {
1695 case Stmt::NoStmtClass: break;
1696#define STMT(Node, Parent) case Stmt::Node##Class: break;
1697#define EXPR(Node, Parent) \
1698 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1699#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001700 }
1701
Douglas Gregora16548e2009-08-11 05:31:07 +00001702 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001703}
1704
1705template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001706NestedNameSpecifier *
1707TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001708 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001709 QualType ObjectType,
1710 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001711 if (!NNS)
1712 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001713
Douglas Gregorebe10102009-08-20 07:17:43 +00001714 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001715 NestedNameSpecifier *Prefix = NNS->getPrefix();
1716 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001717 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001718 ObjectType,
1719 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001720 if (!Prefix)
1721 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001722
1723 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001724 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001725 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001726 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001727 }
Mike Stump11289f42009-09-09 15:08:12 +00001728
Douglas Gregor1135c352009-08-06 05:28:30 +00001729 switch (NNS->getKind()) {
1730 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001731 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001732 "Identifier nested-name-specifier with no prefix or object type");
1733 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1734 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001735 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001736
1737 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001738 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001739 ObjectType,
1740 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001741
Douglas Gregor1135c352009-08-06 05:28:30 +00001742 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001743 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001744 = cast_or_null<NamespaceDecl>(
1745 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001746 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001747 Prefix == NNS->getPrefix() &&
1748 NS == NNS->getAsNamespace())
1749 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001750
Douglas Gregor1135c352009-08-06 05:28:30 +00001751 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1752 }
Mike Stump11289f42009-09-09 15:08:12 +00001753
Douglas Gregor1135c352009-08-06 05:28:30 +00001754 case NestedNameSpecifier::Global:
1755 // There is no meaningful transformation that one could perform on the
1756 // global scope.
1757 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001758
Douglas Gregor1135c352009-08-06 05:28:30 +00001759 case NestedNameSpecifier::TypeSpecWithTemplate:
1760 case NestedNameSpecifier::TypeSpec: {
Douglas Gregor07cc4ac2009-10-29 22:21:39 +00001761 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregor1135c352009-08-06 05:28:30 +00001762 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001763 if (T.isNull())
1764 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001765
Douglas Gregor1135c352009-08-06 05:28:30 +00001766 if (!getDerived().AlwaysRebuild() &&
1767 Prefix == NNS->getPrefix() &&
1768 T == QualType(NNS->getAsType(), 0))
1769 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001770
1771 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1772 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001773 T);
1774 }
1775 }
Mike Stump11289f42009-09-09 15:08:12 +00001776
Douglas Gregor1135c352009-08-06 05:28:30 +00001777 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001778 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001779}
1780
1781template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001782DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001783TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001784 SourceLocation Loc,
1785 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001786 if (!Name)
1787 return Name;
1788
1789 switch (Name.getNameKind()) {
1790 case DeclarationName::Identifier:
1791 case DeclarationName::ObjCZeroArgSelector:
1792 case DeclarationName::ObjCOneArgSelector:
1793 case DeclarationName::ObjCMultiArgSelector:
1794 case DeclarationName::CXXOperatorName:
1795 case DeclarationName::CXXUsingDirective:
1796 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001797
Douglas Gregorf816bd72009-09-03 22:13:48 +00001798 case DeclarationName::CXXConstructorName:
1799 case DeclarationName::CXXDestructorName:
1800 case DeclarationName::CXXConversionFunctionName: {
1801 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001802 QualType T;
1803 if (!ObjectType.isNull() &&
1804 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1805 TemplateSpecializationType *SpecType
1806 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1807 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1808 } else
1809 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001810 if (T.isNull())
1811 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001812
Douglas Gregorf816bd72009-09-03 22:13:48 +00001813 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001814 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001815 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001816 }
Mike Stump11289f42009-09-09 15:08:12 +00001817 }
1818
Douglas Gregorf816bd72009-09-03 22:13:48 +00001819 return DeclarationName();
1820}
1821
1822template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001823TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001824TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1825 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001826 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001827 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001828 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1829 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1830 if (!NNS)
1831 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001832
Douglas Gregor71dc5092009-08-06 06:41:21 +00001833 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001834 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001835 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1836 if (!TransTemplate)
1837 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001838
Douglas Gregor71dc5092009-08-06 06:41:21 +00001839 if (!getDerived().AlwaysRebuild() &&
1840 NNS == QTN->getQualifier() &&
1841 TransTemplate == Template)
1842 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001843
Douglas Gregor71dc5092009-08-06 06:41:21 +00001844 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1845 TransTemplate);
1846 }
Mike Stump11289f42009-09-09 15:08:12 +00001847
Douglas Gregor71dc5092009-08-06 06:41:21 +00001848 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1849 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001850 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001851 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1852 if (!TransOvl)
1853 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001854
Douglas Gregor71dc5092009-08-06 06:41:21 +00001855 if (!getDerived().AlwaysRebuild() &&
1856 NNS == QTN->getQualifier() &&
1857 TransOvl == Ovl)
1858 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001859
Douglas Gregor71dc5092009-08-06 06:41:21 +00001860 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1861 TransOvl);
1862 }
Mike Stump11289f42009-09-09 15:08:12 +00001863
Douglas Gregor71dc5092009-08-06 06:41:21 +00001864 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001865 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001866 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1867 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001868 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001869 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001870
Douglas Gregor71dc5092009-08-06 06:41:21 +00001871 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001872 NNS == DTN->getQualifier() &&
1873 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001874 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001875
Douglas Gregor308047d2009-09-09 00:23:06 +00001876 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001877 }
Mike Stump11289f42009-09-09 15:08:12 +00001878
Douglas Gregor71dc5092009-08-06 06:41:21 +00001879 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001880 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001881 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1882 if (!TransTemplate)
1883 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001884
Douglas Gregor71dc5092009-08-06 06:41:21 +00001885 if (!getDerived().AlwaysRebuild() &&
1886 TransTemplate == Template)
1887 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001888
Douglas Gregor71dc5092009-08-06 06:41:21 +00001889 return TemplateName(TransTemplate);
1890 }
Mike Stump11289f42009-09-09 15:08:12 +00001891
Douglas Gregor71dc5092009-08-06 06:41:21 +00001892 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1893 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001894 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001895 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1896 if (!TransOvl)
1897 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001898
Douglas Gregor71dc5092009-08-06 06:41:21 +00001899 if (!getDerived().AlwaysRebuild() &&
1900 TransOvl == Ovl)
1901 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001902
Douglas Gregor71dc5092009-08-06 06:41:21 +00001903 return TemplateName(TransOvl);
1904}
1905
1906template<typename Derived>
John McCall0ad16662009-10-29 08:12:44 +00001907void TreeTransform<Derived>::InventTemplateArgumentLoc(
1908 const TemplateArgument &Arg,
1909 TemplateArgumentLoc &Output) {
1910 SourceLocation Loc = getDerived().getBaseLocation();
1911 switch (Arg.getKind()) {
1912 case TemplateArgument::Null:
1913 llvm::llvm_unreachable("null template argument in TreeTransform");
1914 break;
1915
1916 case TemplateArgument::Type:
1917 Output = TemplateArgumentLoc(Arg,
1918 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1919
1920 break;
1921
1922 case TemplateArgument::Expression:
1923 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1924 break;
1925
1926 case TemplateArgument::Declaration:
1927 case TemplateArgument::Integral:
1928 case TemplateArgument::Pack:
John McCall0d07eb32009-10-29 18:45:58 +00001929 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00001930 break;
1931 }
1932}
1933
1934template<typename Derived>
1935bool TreeTransform<Derived>::TransformTemplateArgument(
1936 const TemplateArgumentLoc &Input,
1937 TemplateArgumentLoc &Output) {
1938 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregore922c772009-08-04 22:27:00 +00001939 switch (Arg.getKind()) {
1940 case TemplateArgument::Null:
1941 case TemplateArgument::Integral:
John McCall0ad16662009-10-29 08:12:44 +00001942 Output = Input;
1943 return false;
Mike Stump11289f42009-09-09 15:08:12 +00001944
Douglas Gregore922c772009-08-04 22:27:00 +00001945 case TemplateArgument::Type: {
John McCall0ad16662009-10-29 08:12:44 +00001946 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1947 if (DI == NULL)
1948 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1949
1950 DI = getDerived().TransformType(DI);
1951 if (!DI) return true;
1952
1953 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1954 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001955 }
Mike Stump11289f42009-09-09 15:08:12 +00001956
Douglas Gregore922c772009-08-04 22:27:00 +00001957 case TemplateArgument::Declaration: {
John McCall0ad16662009-10-29 08:12:44 +00001958 // FIXME: we should never have to transform one of these.
Douglas Gregoref6ab412009-10-27 06:26:26 +00001959 DeclarationName Name;
1960 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1961 Name = ND->getDeclName();
John McCall0ad16662009-10-29 08:12:44 +00001962 TemporaryBase Rebase(*this, SourceLocation(), Name);
Douglas Gregore922c772009-08-04 22:27:00 +00001963 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall0ad16662009-10-29 08:12:44 +00001964 if (!D) return true;
1965
John McCall0d07eb32009-10-29 18:45:58 +00001966 Expr *SourceExpr = Input.getSourceDeclExpression();
1967 if (SourceExpr) {
1968 EnterExpressionEvaluationContext Unevaluated(getSema(),
1969 Action::Unevaluated);
1970 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
1971 if (E.isInvalid())
1972 SourceExpr = NULL;
1973 else {
1974 SourceExpr = E.takeAs<Expr>();
1975 SourceExpr->Retain();
1976 }
1977 }
1978
1979 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall0ad16662009-10-29 08:12:44 +00001980 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001981 }
Mike Stump11289f42009-09-09 15:08:12 +00001982
Douglas Gregore922c772009-08-04 22:27:00 +00001983 case TemplateArgument::Expression: {
1984 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00001985 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00001986 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00001987
John McCall0ad16662009-10-29 08:12:44 +00001988 Expr *InputExpr = Input.getSourceExpression();
1989 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
1990
1991 Sema::OwningExprResult E
1992 = getDerived().TransformExpr(InputExpr);
1993 if (E.isInvalid()) return true;
1994
1995 Expr *ETaken = E.takeAs<Expr>();
John McCall0d07eb32009-10-29 18:45:58 +00001996 ETaken->Retain();
John McCall0ad16662009-10-29 08:12:44 +00001997 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
1998 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001999 }
Mike Stump11289f42009-09-09 15:08:12 +00002000
Douglas Gregore922c772009-08-04 22:27:00 +00002001 case TemplateArgument::Pack: {
2002 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
2003 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00002004 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00002005 AEnd = Arg.pack_end();
2006 A != AEnd; ++A) {
Mike Stump11289f42009-09-09 15:08:12 +00002007
John McCall0ad16662009-10-29 08:12:44 +00002008 // FIXME: preserve source information here when we start
2009 // caring about parameter packs.
2010
John McCall0d07eb32009-10-29 18:45:58 +00002011 TemplateArgumentLoc InputArg;
2012 TemplateArgumentLoc OutputArg;
2013 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2014 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall0ad16662009-10-29 08:12:44 +00002015 return true;
2016
John McCall0d07eb32009-10-29 18:45:58 +00002017 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregore922c772009-08-04 22:27:00 +00002018 }
2019 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00002020 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00002021 true);
John McCall0d07eb32009-10-29 18:45:58 +00002022 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00002023 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002024 }
2025 }
Mike Stump11289f42009-09-09 15:08:12 +00002026
Douglas Gregore922c772009-08-04 22:27:00 +00002027 // Work around bogus GCC warning
John McCall0ad16662009-10-29 08:12:44 +00002028 return true;
Douglas Gregore922c772009-08-04 22:27:00 +00002029}
2030
Douglas Gregord6ff3322009-08-04 16:50:30 +00002031//===----------------------------------------------------------------------===//
2032// Type transformation
2033//===----------------------------------------------------------------------===//
2034
2035template<typename Derived>
2036QualType TreeTransform<Derived>::TransformType(QualType T) {
2037 if (getDerived().AlreadyTransformed(T))
2038 return T;
Mike Stump11289f42009-09-09 15:08:12 +00002039
John McCall550e0c22009-10-21 00:40:46 +00002040 // Temporary workaround. All of these transformations should
2041 // eventually turn into transformations on TypeLocs.
2042 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00002043 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00002044
2045 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00002046
John McCall550e0c22009-10-21 00:40:46 +00002047 if (!NewDI)
2048 return QualType();
2049
2050 return NewDI->getType();
2051}
2052
2053template<typename Derived>
2054DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2055 if (getDerived().AlreadyTransformed(DI->getType()))
2056 return DI;
2057
2058 TypeLocBuilder TLB;
2059
2060 TypeLoc TL = DI->getTypeLoc();
2061 TLB.reserve(TL.getFullDataSize());
2062
2063 QualType Result = getDerived().TransformType(TLB, TL);
2064 if (Result.isNull())
2065 return 0;
2066
2067 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2068}
2069
2070template<typename Derived>
2071QualType
2072TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2073 switch (T.getTypeLocClass()) {
2074#define ABSTRACT_TYPELOC(CLASS, PARENT)
2075#define TYPELOC(CLASS, PARENT) \
2076 case TypeLoc::CLASS: \
2077 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2078#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00002079 }
Mike Stump11289f42009-09-09 15:08:12 +00002080
John McCall550e0c22009-10-21 00:40:46 +00002081 llvm::llvm_unreachable("unhandled type loc!");
2082 return QualType();
2083}
2084
2085/// FIXME: By default, this routine adds type qualifiers only to types
2086/// that can have qualifiers, and silently suppresses those qualifiers
2087/// that are not permitted (e.g., qualifiers on reference or function
2088/// types). This is the right thing for template instantiation, but
2089/// probably not for other clients.
2090template<typename Derived>
2091QualType
2092TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2093 QualifiedTypeLoc T) {
2094 Qualifiers Quals = T.getType().getQualifiers();
2095
2096 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2097 if (Result.isNull())
2098 return QualType();
2099
2100 // Silently suppress qualifiers if the result type can't be qualified.
2101 // FIXME: this is the right thing for template instantiation, but
2102 // probably not for other clients.
2103 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002104 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002105
John McCall550e0c22009-10-21 00:40:46 +00002106 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2107
2108 TLB.push<QualifiedTypeLoc>(Result);
2109
2110 // No location information to preserve.
2111
2112 return Result;
2113}
2114
2115template <class TyLoc> static inline
2116QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2117 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2118 NewT.setNameLoc(T.getNameLoc());
2119 return T.getType();
2120}
2121
2122// Ugly metaprogramming macros because I couldn't be bothered to make
2123// the equivalent template version work.
2124#define TransformPointerLikeType(TypeClass) do { \
2125 QualType PointeeType \
2126 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2127 if (PointeeType.isNull()) \
2128 return QualType(); \
2129 \
2130 QualType Result = TL.getType(); \
2131 if (getDerived().AlwaysRebuild() || \
2132 PointeeType != TL.getPointeeLoc().getType()) { \
John McCall70dd5f62009-10-30 00:06:24 +00002133 Result = getDerived().Rebuild##TypeClass(PointeeType, \
2134 TL.getSigilLoc()); \
John McCall550e0c22009-10-21 00:40:46 +00002135 if (Result.isNull()) \
2136 return QualType(); \
2137 } \
2138 \
2139 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2140 NewT.setSigilLoc(TL.getSigilLoc()); \
2141 \
2142 return Result; \
2143} while(0)
2144
John McCall550e0c22009-10-21 00:40:46 +00002145template<typename Derived>
2146QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2147 BuiltinTypeLoc T) {
2148 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002149}
Mike Stump11289f42009-09-09 15:08:12 +00002150
Douglas Gregord6ff3322009-08-04 16:50:30 +00002151template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002152QualType
John McCall550e0c22009-10-21 00:40:46 +00002153TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2154 FixedWidthIntTypeLoc T) {
2155 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002156}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002157
Douglas Gregord6ff3322009-08-04 16:50:30 +00002158template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002159QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2160 ComplexTypeLoc T) {
2161 // FIXME: recurse?
2162 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002163}
Mike Stump11289f42009-09-09 15:08:12 +00002164
Douglas Gregord6ff3322009-08-04 16:50:30 +00002165template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002166QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2167 PointerTypeLoc TL) {
2168 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002169}
Mike Stump11289f42009-09-09 15:08:12 +00002170
2171template<typename Derived>
2172QualType
John McCall550e0c22009-10-21 00:40:46 +00002173TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2174 BlockPointerTypeLoc TL) {
2175 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002176}
2177
John McCall70dd5f62009-10-30 00:06:24 +00002178/// Transforms a reference type. Note that somewhat paradoxically we
2179/// don't care whether the type itself is an l-value type or an r-value
2180/// type; we only care if the type was *written* as an l-value type
2181/// or an r-value type.
2182template<typename Derived>
2183QualType
2184TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
2185 ReferenceTypeLoc TL) {
2186 const ReferenceType *T = TL.getTypePtr();
2187
2188 // Note that this works with the pointee-as-written.
2189 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
2190 if (PointeeType.isNull())
2191 return QualType();
2192
2193 QualType Result = TL.getType();
2194 if (getDerived().AlwaysRebuild() ||
2195 PointeeType != T->getPointeeTypeAsWritten()) {
2196 Result = getDerived().RebuildReferenceType(PointeeType,
2197 T->isSpelledAsLValue(),
2198 TL.getSigilLoc());
2199 if (Result.isNull())
2200 return QualType();
2201 }
2202
2203 // r-value references can be rebuilt as l-value references.
2204 ReferenceTypeLoc NewTL;
2205 if (isa<LValueReferenceType>(Result))
2206 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
2207 else
2208 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
2209 NewTL.setSigilLoc(TL.getSigilLoc());
2210
2211 return Result;
2212}
2213
Mike Stump11289f42009-09-09 15:08:12 +00002214template<typename Derived>
2215QualType
John McCall550e0c22009-10-21 00:40:46 +00002216TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2217 LValueReferenceTypeLoc TL) {
John McCall70dd5f62009-10-30 00:06:24 +00002218 return TransformReferenceType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002219}
2220
Mike Stump11289f42009-09-09 15:08:12 +00002221template<typename Derived>
2222QualType
John McCall550e0c22009-10-21 00:40:46 +00002223TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2224 RValueReferenceTypeLoc TL) {
John McCall70dd5f62009-10-30 00:06:24 +00002225 return TransformReferenceType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002226}
Mike Stump11289f42009-09-09 15:08:12 +00002227
Douglas Gregord6ff3322009-08-04 16:50:30 +00002228template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002229QualType
John McCall550e0c22009-10-21 00:40:46 +00002230TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2231 MemberPointerTypeLoc TL) {
2232 MemberPointerType *T = TL.getTypePtr();
2233
2234 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002235 if (PointeeType.isNull())
2236 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002237
John McCall550e0c22009-10-21 00:40:46 +00002238 // TODO: preserve source information for this.
2239 QualType ClassType
2240 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002241 if (ClassType.isNull())
2242 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002243
John McCall550e0c22009-10-21 00:40:46 +00002244 QualType Result = TL.getType();
2245 if (getDerived().AlwaysRebuild() ||
2246 PointeeType != T->getPointeeType() ||
2247 ClassType != QualType(T->getClass(), 0)) {
John McCall70dd5f62009-10-30 00:06:24 +00002248 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
2249 TL.getStarLoc());
John McCall550e0c22009-10-21 00:40:46 +00002250 if (Result.isNull())
2251 return QualType();
2252 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002253
John McCall550e0c22009-10-21 00:40:46 +00002254 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2255 NewTL.setSigilLoc(TL.getSigilLoc());
2256
2257 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002258}
2259
Mike Stump11289f42009-09-09 15:08:12 +00002260template<typename Derived>
2261QualType
John McCall550e0c22009-10-21 00:40:46 +00002262TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2263 ConstantArrayTypeLoc TL) {
2264 ConstantArrayType *T = TL.getTypePtr();
2265 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002266 if (ElementType.isNull())
2267 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002268
John McCall550e0c22009-10-21 00:40:46 +00002269 QualType Result = TL.getType();
2270 if (getDerived().AlwaysRebuild() ||
2271 ElementType != T->getElementType()) {
2272 Result = getDerived().RebuildConstantArrayType(ElementType,
2273 T->getSizeModifier(),
2274 T->getSize(),
John McCall70dd5f62009-10-30 00:06:24 +00002275 T->getIndexTypeCVRQualifiers(),
2276 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002277 if (Result.isNull())
2278 return QualType();
2279 }
2280
2281 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2282 NewTL.setLBracketLoc(TL.getLBracketLoc());
2283 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002284
John McCall550e0c22009-10-21 00:40:46 +00002285 Expr *Size = TL.getSizeExpr();
2286 if (Size) {
2287 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2288 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2289 }
2290 NewTL.setSizeExpr(Size);
2291
2292 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002293}
Mike Stump11289f42009-09-09 15:08:12 +00002294
Douglas Gregord6ff3322009-08-04 16:50:30 +00002295template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002296QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002297 TypeLocBuilder &TLB,
2298 IncompleteArrayTypeLoc TL) {
2299 IncompleteArrayType *T = TL.getTypePtr();
2300 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002301 if (ElementType.isNull())
2302 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002303
John McCall550e0c22009-10-21 00:40:46 +00002304 QualType Result = TL.getType();
2305 if (getDerived().AlwaysRebuild() ||
2306 ElementType != T->getElementType()) {
2307 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002308 T->getSizeModifier(),
John McCall70dd5f62009-10-30 00:06:24 +00002309 T->getIndexTypeCVRQualifiers(),
2310 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002311 if (Result.isNull())
2312 return QualType();
2313 }
2314
2315 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2316 NewTL.setLBracketLoc(TL.getLBracketLoc());
2317 NewTL.setRBracketLoc(TL.getRBracketLoc());
2318 NewTL.setSizeExpr(0);
2319
2320 return Result;
2321}
2322
2323template<typename Derived>
2324QualType
2325TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2326 VariableArrayTypeLoc TL) {
2327 VariableArrayType *T = TL.getTypePtr();
2328 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2329 if (ElementType.isNull())
2330 return QualType();
2331
2332 // Array bounds are not potentially evaluated contexts
2333 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2334
2335 Sema::OwningExprResult SizeResult
2336 = getDerived().TransformExpr(T->getSizeExpr());
2337 if (SizeResult.isInvalid())
2338 return QualType();
2339
2340 Expr *Size = static_cast<Expr*>(SizeResult.get());
2341
2342 QualType Result = TL.getType();
2343 if (getDerived().AlwaysRebuild() ||
2344 ElementType != T->getElementType() ||
2345 Size != T->getSizeExpr()) {
2346 Result = getDerived().RebuildVariableArrayType(ElementType,
2347 T->getSizeModifier(),
2348 move(SizeResult),
2349 T->getIndexTypeCVRQualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00002350 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002351 if (Result.isNull())
2352 return QualType();
2353 }
2354 else SizeResult.take();
2355
2356 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2357 NewTL.setLBracketLoc(TL.getLBracketLoc());
2358 NewTL.setRBracketLoc(TL.getRBracketLoc());
2359 NewTL.setSizeExpr(Size);
2360
2361 return Result;
2362}
2363
2364template<typename Derived>
2365QualType
2366TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2367 DependentSizedArrayTypeLoc TL) {
2368 DependentSizedArrayType *T = TL.getTypePtr();
2369 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2370 if (ElementType.isNull())
2371 return QualType();
2372
2373 // Array bounds are not potentially evaluated contexts
2374 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2375
2376 Sema::OwningExprResult SizeResult
2377 = getDerived().TransformExpr(T->getSizeExpr());
2378 if (SizeResult.isInvalid())
2379 return QualType();
2380
2381 Expr *Size = static_cast<Expr*>(SizeResult.get());
2382
2383 QualType Result = TL.getType();
2384 if (getDerived().AlwaysRebuild() ||
2385 ElementType != T->getElementType() ||
2386 Size != T->getSizeExpr()) {
2387 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2388 T->getSizeModifier(),
2389 move(SizeResult),
2390 T->getIndexTypeCVRQualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00002391 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002392 if (Result.isNull())
2393 return QualType();
2394 }
2395 else SizeResult.take();
2396
2397 // We might have any sort of array type now, but fortunately they
2398 // all have the same location layout.
2399 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2400 NewTL.setLBracketLoc(TL.getLBracketLoc());
2401 NewTL.setRBracketLoc(TL.getRBracketLoc());
2402 NewTL.setSizeExpr(Size);
2403
2404 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002405}
Mike Stump11289f42009-09-09 15:08:12 +00002406
2407template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002408QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002409 TypeLocBuilder &TLB,
2410 DependentSizedExtVectorTypeLoc TL) {
2411 DependentSizedExtVectorType *T = TL.getTypePtr();
2412
2413 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002414 QualType ElementType = getDerived().TransformType(T->getElementType());
2415 if (ElementType.isNull())
2416 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002417
Douglas Gregore922c772009-08-04 22:27:00 +00002418 // Vector sizes are not potentially evaluated contexts
2419 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2420
Douglas Gregord6ff3322009-08-04 16:50:30 +00002421 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2422 if (Size.isInvalid())
2423 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002424
John McCall550e0c22009-10-21 00:40:46 +00002425 QualType Result = TL.getType();
2426 if (getDerived().AlwaysRebuild() ||
John McCall24e7cb62009-10-23 17:55:45 +00002427 ElementType != T->getElementType() ||
2428 Size.get() != T->getSizeExpr()) {
John McCall550e0c22009-10-21 00:40:46 +00002429 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002430 move(Size),
2431 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002432 if (Result.isNull())
2433 return QualType();
2434 }
2435 else Size.take();
2436
2437 // Result might be dependent or not.
2438 if (isa<DependentSizedExtVectorType>(Result)) {
2439 DependentSizedExtVectorTypeLoc NewTL
2440 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2441 NewTL.setNameLoc(TL.getNameLoc());
2442 } else {
2443 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2444 NewTL.setNameLoc(TL.getNameLoc());
2445 }
2446
2447 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002448}
Mike Stump11289f42009-09-09 15:08:12 +00002449
2450template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002451QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2452 VectorTypeLoc TL) {
2453 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002454 QualType ElementType = getDerived().TransformType(T->getElementType());
2455 if (ElementType.isNull())
2456 return QualType();
2457
John McCall550e0c22009-10-21 00:40:46 +00002458 QualType Result = TL.getType();
2459 if (getDerived().AlwaysRebuild() ||
2460 ElementType != T->getElementType()) {
2461 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2462 if (Result.isNull())
2463 return QualType();
2464 }
2465
2466 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2467 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002468
John McCall550e0c22009-10-21 00:40:46 +00002469 return Result;
2470}
2471
2472template<typename Derived>
2473QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2474 ExtVectorTypeLoc TL) {
2475 VectorType *T = TL.getTypePtr();
2476 QualType ElementType = getDerived().TransformType(T->getElementType());
2477 if (ElementType.isNull())
2478 return QualType();
2479
2480 QualType Result = TL.getType();
2481 if (getDerived().AlwaysRebuild() ||
2482 ElementType != T->getElementType()) {
2483 Result = getDerived().RebuildExtVectorType(ElementType,
2484 T->getNumElements(),
2485 /*FIXME*/ SourceLocation());
2486 if (Result.isNull())
2487 return QualType();
2488 }
2489
2490 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2491 NewTL.setNameLoc(TL.getNameLoc());
2492
2493 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002494}
Mike Stump11289f42009-09-09 15:08:12 +00002495
2496template<typename Derived>
2497QualType
John McCall550e0c22009-10-21 00:40:46 +00002498TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2499 FunctionProtoTypeLoc TL) {
2500 FunctionProtoType *T = TL.getTypePtr();
2501 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002502 if (ResultType.isNull())
2503 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002504
John McCall550e0c22009-10-21 00:40:46 +00002505 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002506 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002507 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2508 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2509 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002510
John McCall550e0c22009-10-21 00:40:46 +00002511 QualType NewType;
2512 ParmVarDecl *NewParm;
2513
2514 if (OldParm) {
2515 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2516 assert(OldDI->getType() == T->getArgType(i));
2517
2518 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2519 if (!NewDI)
2520 return QualType();
2521
2522 if (NewDI == OldDI)
2523 NewParm = OldParm;
2524 else
2525 NewParm = ParmVarDecl::Create(SemaRef.Context,
2526 OldParm->getDeclContext(),
2527 OldParm->getLocation(),
2528 OldParm->getIdentifier(),
2529 NewDI->getType(),
2530 NewDI,
2531 OldParm->getStorageClass(),
2532 /* DefArg */ NULL);
2533 NewType = NewParm->getType();
2534
2535 // Deal with the possibility that we don't have a parameter
2536 // declaration for this parameter.
2537 } else {
2538 NewParm = 0;
2539
2540 QualType OldType = T->getArgType(i);
2541 NewType = getDerived().TransformType(OldType);
2542 if (NewType.isNull())
2543 return QualType();
2544 }
2545
2546 ParamTypes.push_back(NewType);
2547 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002548 }
Mike Stump11289f42009-09-09 15:08:12 +00002549
John McCall550e0c22009-10-21 00:40:46 +00002550 QualType Result = TL.getType();
2551 if (getDerived().AlwaysRebuild() ||
2552 ResultType != T->getResultType() ||
2553 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2554 Result = getDerived().RebuildFunctionProtoType(ResultType,
2555 ParamTypes.data(),
2556 ParamTypes.size(),
2557 T->isVariadic(),
2558 T->getTypeQuals());
2559 if (Result.isNull())
2560 return QualType();
2561 }
Mike Stump11289f42009-09-09 15:08:12 +00002562
John McCall550e0c22009-10-21 00:40:46 +00002563 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2564 NewTL.setLParenLoc(TL.getLParenLoc());
2565 NewTL.setRParenLoc(TL.getRParenLoc());
2566 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2567 NewTL.setArg(i, ParamDecls[i]);
2568
2569 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002570}
Mike Stump11289f42009-09-09 15:08:12 +00002571
Douglas Gregord6ff3322009-08-04 16:50:30 +00002572template<typename Derived>
2573QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002574 TypeLocBuilder &TLB,
2575 FunctionNoProtoTypeLoc TL) {
2576 FunctionNoProtoType *T = TL.getTypePtr();
2577 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2578 if (ResultType.isNull())
2579 return QualType();
2580
2581 QualType Result = TL.getType();
2582 if (getDerived().AlwaysRebuild() ||
2583 ResultType != T->getResultType())
2584 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2585
2586 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2587 NewTL.setLParenLoc(TL.getLParenLoc());
2588 NewTL.setRParenLoc(TL.getRParenLoc());
2589
2590 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002591}
Mike Stump11289f42009-09-09 15:08:12 +00002592
Douglas Gregord6ff3322009-08-04 16:50:30 +00002593template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002594QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2595 TypedefTypeLoc TL) {
2596 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002597 TypedefDecl *Typedef
2598 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2599 if (!Typedef)
2600 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002601
John McCall550e0c22009-10-21 00:40:46 +00002602 QualType Result = TL.getType();
2603 if (getDerived().AlwaysRebuild() ||
2604 Typedef != T->getDecl()) {
2605 Result = getDerived().RebuildTypedefType(Typedef);
2606 if (Result.isNull())
2607 return QualType();
2608 }
Mike Stump11289f42009-09-09 15:08:12 +00002609
John McCall550e0c22009-10-21 00:40:46 +00002610 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2611 NewTL.setNameLoc(TL.getNameLoc());
2612
2613 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002614}
Mike Stump11289f42009-09-09 15:08:12 +00002615
Douglas Gregord6ff3322009-08-04 16:50:30 +00002616template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002617QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2618 TypeOfExprTypeLoc TL) {
2619 TypeOfExprType *T = TL.getTypePtr();
2620
Douglas Gregore922c772009-08-04 22:27:00 +00002621 // typeof expressions are not potentially evaluated contexts
2622 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002623
Douglas Gregord6ff3322009-08-04 16:50:30 +00002624 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2625 if (E.isInvalid())
2626 return QualType();
2627
John McCall550e0c22009-10-21 00:40:46 +00002628 QualType Result = TL.getType();
2629 if (getDerived().AlwaysRebuild() ||
2630 E.get() != T->getUnderlyingExpr()) {
2631 Result = getDerived().RebuildTypeOfExprType(move(E));
2632 if (Result.isNull())
2633 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002634 }
John McCall550e0c22009-10-21 00:40:46 +00002635 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002636
John McCall550e0c22009-10-21 00:40:46 +00002637 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2638 NewTL.setNameLoc(TL.getNameLoc());
2639
2640 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002641}
Mike Stump11289f42009-09-09 15:08:12 +00002642
2643template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002644QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2645 TypeOfTypeLoc TL) {
2646 TypeOfType *T = TL.getTypePtr();
2647
2648 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002649 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2650 if (Underlying.isNull())
2651 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002652
John McCall550e0c22009-10-21 00:40:46 +00002653 QualType Result = TL.getType();
2654 if (getDerived().AlwaysRebuild() ||
2655 Underlying != T->getUnderlyingType()) {
2656 Result = getDerived().RebuildTypeOfType(Underlying);
2657 if (Result.isNull())
2658 return QualType();
2659 }
Mike Stump11289f42009-09-09 15:08:12 +00002660
John McCall550e0c22009-10-21 00:40:46 +00002661 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2662 NewTL.setNameLoc(TL.getNameLoc());
2663
2664 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002665}
Mike Stump11289f42009-09-09 15:08:12 +00002666
2667template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002668QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2669 DecltypeTypeLoc TL) {
2670 DecltypeType *T = TL.getTypePtr();
2671
Douglas Gregore922c772009-08-04 22:27:00 +00002672 // decltype expressions are not potentially evaluated contexts
2673 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002674
Douglas Gregord6ff3322009-08-04 16:50:30 +00002675 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2676 if (E.isInvalid())
2677 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002678
John McCall550e0c22009-10-21 00:40:46 +00002679 QualType Result = TL.getType();
2680 if (getDerived().AlwaysRebuild() ||
2681 E.get() != T->getUnderlyingExpr()) {
2682 Result = getDerived().RebuildDecltypeType(move(E));
2683 if (Result.isNull())
2684 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002685 }
John McCall550e0c22009-10-21 00:40:46 +00002686 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002687
John McCall550e0c22009-10-21 00:40:46 +00002688 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2689 NewTL.setNameLoc(TL.getNameLoc());
2690
2691 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002692}
2693
2694template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002695QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2696 RecordTypeLoc TL) {
2697 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002698 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002699 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002700 if (!Record)
2701 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002702
John McCall550e0c22009-10-21 00:40:46 +00002703 QualType Result = TL.getType();
2704 if (getDerived().AlwaysRebuild() ||
2705 Record != T->getDecl()) {
2706 Result = getDerived().RebuildRecordType(Record);
2707 if (Result.isNull())
2708 return QualType();
2709 }
Mike Stump11289f42009-09-09 15:08:12 +00002710
John McCall550e0c22009-10-21 00:40:46 +00002711 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2712 NewTL.setNameLoc(TL.getNameLoc());
2713
2714 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002715}
Mike Stump11289f42009-09-09 15:08:12 +00002716
2717template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002718QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2719 EnumTypeLoc TL) {
2720 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002721 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002722 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002723 if (!Enum)
2724 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002725
John McCall550e0c22009-10-21 00:40:46 +00002726 QualType Result = TL.getType();
2727 if (getDerived().AlwaysRebuild() ||
2728 Enum != T->getDecl()) {
2729 Result = getDerived().RebuildEnumType(Enum);
2730 if (Result.isNull())
2731 return QualType();
2732 }
Mike Stump11289f42009-09-09 15:08:12 +00002733
John McCall550e0c22009-10-21 00:40:46 +00002734 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2735 NewTL.setNameLoc(TL.getNameLoc());
2736
2737 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002738}
John McCallfcc33b02009-09-05 00:15:47 +00002739
2740template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002741QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2742 ElaboratedTypeLoc TL) {
2743 ElaboratedType *T = TL.getTypePtr();
2744
2745 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002746 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2747 if (Underlying.isNull())
2748 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002749
John McCall550e0c22009-10-21 00:40:46 +00002750 QualType Result = TL.getType();
2751 if (getDerived().AlwaysRebuild() ||
2752 Underlying != T->getUnderlyingType()) {
2753 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2754 if (Result.isNull())
2755 return QualType();
2756 }
Mike Stump11289f42009-09-09 15:08:12 +00002757
John McCall550e0c22009-10-21 00:40:46 +00002758 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2759 NewTL.setNameLoc(TL.getNameLoc());
2760
2761 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002762}
Mike Stump11289f42009-09-09 15:08:12 +00002763
2764
Douglas Gregord6ff3322009-08-04 16:50:30 +00002765template<typename Derived>
2766QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002767 TypeLocBuilder &TLB,
2768 TemplateTypeParmTypeLoc TL) {
2769 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002770}
2771
Mike Stump11289f42009-09-09 15:08:12 +00002772template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002773QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002774 TypeLocBuilder &TLB,
2775 SubstTemplateTypeParmTypeLoc TL) {
2776 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002777}
2778
2779template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002780inline QualType
2781TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002782 TypeLocBuilder &TLB,
2783 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002784 return TransformTemplateSpecializationType(TLB, TL, QualType());
2785}
John McCall550e0c22009-10-21 00:40:46 +00002786
John McCall0ad16662009-10-29 08:12:44 +00002787template<typename Derived>
2788QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2789 const TemplateSpecializationType *TST,
2790 QualType ObjectType) {
2791 // FIXME: this entire method is a temporary workaround; callers
2792 // should be rewritten to provide real type locs.
John McCall550e0c22009-10-21 00:40:46 +00002793
John McCall0ad16662009-10-29 08:12:44 +00002794 // Fake up a TemplateSpecializationTypeLoc.
2795 TypeLocBuilder TLB;
2796 TemplateSpecializationTypeLoc TL
2797 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2798
John McCall0d07eb32009-10-29 18:45:58 +00002799 SourceLocation BaseLoc = getDerived().getBaseLocation();
2800
2801 TL.setTemplateNameLoc(BaseLoc);
2802 TL.setLAngleLoc(BaseLoc);
2803 TL.setRAngleLoc(BaseLoc);
John McCall0ad16662009-10-29 08:12:44 +00002804 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2805 const TemplateArgument &TA = TST->getArg(i);
2806 TemplateArgumentLoc TAL;
2807 getDerived().InventTemplateArgumentLoc(TA, TAL);
2808 TL.setArgLocInfo(i, TAL.getLocInfo());
2809 }
2810
2811 TypeLocBuilder IgnoredTLB;
2812 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +00002813}
2814
2815template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002816QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00002817 TypeLocBuilder &TLB,
2818 TemplateSpecializationTypeLoc TL,
2819 QualType ObjectType) {
2820 const TemplateSpecializationType *T = TL.getTypePtr();
2821
Mike Stump11289f42009-09-09 15:08:12 +00002822 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002823 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002824 if (Template.isNull())
2825 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002826
John McCall0ad16662009-10-29 08:12:44 +00002827 llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
2828 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
2829 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
2830 NewTemplateArgs[i]))
Douglas Gregord6ff3322009-08-04 16:50:30 +00002831 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002832
John McCall0ad16662009-10-29 08:12:44 +00002833 // FIXME: maybe don't rebuild if all the template arguments are the same.
2834
2835 QualType Result =
2836 getDerived().RebuildTemplateSpecializationType(Template,
2837 TL.getTemplateNameLoc(),
2838 TL.getLAngleLoc(),
2839 NewTemplateArgs.data(),
2840 NewTemplateArgs.size(),
2841 TL.getRAngleLoc());
2842
2843 if (!Result.isNull()) {
2844 TemplateSpecializationTypeLoc NewTL
2845 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2846 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2847 NewTL.setLAngleLoc(TL.getLAngleLoc());
2848 NewTL.setRAngleLoc(TL.getRAngleLoc());
2849 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2850 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002851 }
Mike Stump11289f42009-09-09 15:08:12 +00002852
John McCall0ad16662009-10-29 08:12:44 +00002853 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002854}
Mike Stump11289f42009-09-09 15:08:12 +00002855
2856template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002857QualType
2858TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2859 QualifiedNameTypeLoc TL) {
2860 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002861 NestedNameSpecifier *NNS
2862 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2863 SourceRange());
2864 if (!NNS)
2865 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002866
Douglas Gregord6ff3322009-08-04 16:50:30 +00002867 QualType Named = getDerived().TransformType(T->getNamedType());
2868 if (Named.isNull())
2869 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002870
John McCall550e0c22009-10-21 00:40:46 +00002871 QualType Result = TL.getType();
2872 if (getDerived().AlwaysRebuild() ||
2873 NNS != T->getQualifier() ||
2874 Named != T->getNamedType()) {
2875 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2876 if (Result.isNull())
2877 return QualType();
2878 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002879
John McCall550e0c22009-10-21 00:40:46 +00002880 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2881 NewTL.setNameLoc(TL.getNameLoc());
2882
2883 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002884}
Mike Stump11289f42009-09-09 15:08:12 +00002885
2886template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002887QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2888 TypenameTypeLoc TL) {
2889 TypenameType *T = TL.getTypePtr();
John McCall0ad16662009-10-29 08:12:44 +00002890
2891 /* FIXME: preserve source information better than this */
2892 SourceRange SR(TL.getNameLoc());
2893
Douglas Gregord6ff3322009-08-04 16:50:30 +00002894 NestedNameSpecifier *NNS
John McCall0ad16662009-10-29 08:12:44 +00002895 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002896 if (!NNS)
2897 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002898
John McCall550e0c22009-10-21 00:40:46 +00002899 QualType Result;
2900
Douglas Gregord6ff3322009-08-04 16:50:30 +00002901 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002902 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002903 = getDerived().TransformType(QualType(TemplateId, 0));
2904 if (NewTemplateId.isNull())
2905 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002906
Douglas Gregord6ff3322009-08-04 16:50:30 +00002907 if (!getDerived().AlwaysRebuild() &&
2908 NNS == T->getQualifier() &&
2909 NewTemplateId == QualType(TemplateId, 0))
2910 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002911
John McCall550e0c22009-10-21 00:40:46 +00002912 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2913 } else {
John McCall0ad16662009-10-29 08:12:44 +00002914 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002915 }
John McCall550e0c22009-10-21 00:40:46 +00002916 if (Result.isNull())
2917 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002918
John McCall550e0c22009-10-21 00:40:46 +00002919 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2920 NewTL.setNameLoc(TL.getNameLoc());
2921
2922 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002923}
Mike Stump11289f42009-09-09 15:08:12 +00002924
Douglas Gregord6ff3322009-08-04 16:50:30 +00002925template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002926QualType
2927TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2928 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002929 assert(false && "TransformObjCInterfaceType unimplemented");
2930 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002931}
Mike Stump11289f42009-09-09 15:08:12 +00002932
2933template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002934QualType
2935TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2936 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002937 assert(false && "TransformObjCObjectPointerType unimplemented");
2938 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002939}
2940
Douglas Gregord6ff3322009-08-04 16:50:30 +00002941//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002942// Statement transformation
2943//===----------------------------------------------------------------------===//
2944template<typename Derived>
2945Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002946TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2947 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002948}
2949
2950template<typename Derived>
2951Sema::OwningStmtResult
2952TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2953 return getDerived().TransformCompoundStmt(S, false);
2954}
2955
2956template<typename Derived>
2957Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002958TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002959 bool IsStmtExpr) {
2960 bool SubStmtChanged = false;
2961 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2962 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2963 B != BEnd; ++B) {
2964 OwningStmtResult Result = getDerived().TransformStmt(*B);
2965 if (Result.isInvalid())
2966 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002967
Douglas Gregorebe10102009-08-20 07:17:43 +00002968 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2969 Statements.push_back(Result.takeAs<Stmt>());
2970 }
Mike Stump11289f42009-09-09 15:08:12 +00002971
Douglas Gregorebe10102009-08-20 07:17:43 +00002972 if (!getDerived().AlwaysRebuild() &&
2973 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00002974 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002975
2976 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2977 move_arg(Statements),
2978 S->getRBracLoc(),
2979 IsStmtExpr);
2980}
Mike Stump11289f42009-09-09 15:08:12 +00002981
Douglas Gregorebe10102009-08-20 07:17:43 +00002982template<typename Derived>
2983Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002984TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002985 // The case value expressions are not potentially evaluated.
2986 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002987
Douglas Gregorebe10102009-08-20 07:17:43 +00002988 // Transform the left-hand case value.
2989 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2990 if (LHS.isInvalid())
2991 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002992
Douglas Gregorebe10102009-08-20 07:17:43 +00002993 // Transform the right-hand case value (for the GNU case-range extension).
2994 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2995 if (RHS.isInvalid())
2996 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002997
Douglas Gregorebe10102009-08-20 07:17:43 +00002998 // Build the case statement.
2999 // Case statements are always rebuilt so that they will attached to their
3000 // transformed switch statement.
3001 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
3002 move(LHS),
3003 S->getEllipsisLoc(),
3004 move(RHS),
3005 S->getColonLoc());
3006 if (Case.isInvalid())
3007 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003008
Douglas Gregorebe10102009-08-20 07:17:43 +00003009 // Transform the statement following the case
3010 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3011 if (SubStmt.isInvalid())
3012 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003013
Douglas Gregorebe10102009-08-20 07:17:43 +00003014 // Attach the body to the case statement
3015 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
3016}
3017
3018template<typename Derived>
3019Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003020TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003021 // Transform the statement following the default case
3022 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3023 if (SubStmt.isInvalid())
3024 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003025
Douglas Gregorebe10102009-08-20 07:17:43 +00003026 // Default statements are always rebuilt
3027 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3028 move(SubStmt));
3029}
Mike Stump11289f42009-09-09 15:08:12 +00003030
Douglas Gregorebe10102009-08-20 07:17:43 +00003031template<typename Derived>
3032Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003033TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003034 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3035 if (SubStmt.isInvalid())
3036 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003037
Douglas Gregorebe10102009-08-20 07:17:43 +00003038 // FIXME: Pass the real colon location in.
3039 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3040 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3041 move(SubStmt));
3042}
Mike Stump11289f42009-09-09 15:08:12 +00003043
Douglas Gregorebe10102009-08-20 07:17:43 +00003044template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003045Sema::OwningStmtResult
3046TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003047 // Transform the condition
3048 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3049 if (Cond.isInvalid())
3050 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003051
Douglas Gregorebe10102009-08-20 07:17:43 +00003052 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003053
Douglas Gregorebe10102009-08-20 07:17:43 +00003054 // Transform the "then" branch.
3055 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3056 if (Then.isInvalid())
3057 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003058
Douglas Gregorebe10102009-08-20 07:17:43 +00003059 // Transform the "else" branch.
3060 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3061 if (Else.isInvalid())
3062 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003063
Douglas Gregorebe10102009-08-20 07:17:43 +00003064 if (!getDerived().AlwaysRebuild() &&
3065 FullCond->get() == S->getCond() &&
3066 Then.get() == S->getThen() &&
3067 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00003068 return SemaRef.Owned(S->Retain());
3069
Douglas Gregorebe10102009-08-20 07:17:43 +00003070 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00003071 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00003072}
3073
3074template<typename Derived>
3075Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003076TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003077 // Transform the condition.
3078 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3079 if (Cond.isInvalid())
3080 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003081
Douglas Gregorebe10102009-08-20 07:17:43 +00003082 // Rebuild the switch statement.
3083 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3084 if (Switch.isInvalid())
3085 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003086
Douglas Gregorebe10102009-08-20 07:17:43 +00003087 // Transform the body of the switch statement.
3088 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3089 if (Body.isInvalid())
3090 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003091
Douglas Gregorebe10102009-08-20 07:17:43 +00003092 // Complete the switch statement.
3093 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3094 move(Body));
3095}
Mike Stump11289f42009-09-09 15:08:12 +00003096
Douglas Gregorebe10102009-08-20 07:17:43 +00003097template<typename Derived>
3098Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003099TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003100 // Transform the condition
3101 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3102 if (Cond.isInvalid())
3103 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003104
Douglas Gregorebe10102009-08-20 07:17:43 +00003105 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003106
Douglas Gregorebe10102009-08-20 07:17:43 +00003107 // Transform the body
3108 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3109 if (Body.isInvalid())
3110 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003111
Douglas Gregorebe10102009-08-20 07:17:43 +00003112 if (!getDerived().AlwaysRebuild() &&
3113 FullCond->get() == S->getCond() &&
3114 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003115 return SemaRef.Owned(S->Retain());
3116
Douglas Gregorebe10102009-08-20 07:17:43 +00003117 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3118}
Mike Stump11289f42009-09-09 15:08:12 +00003119
Douglas Gregorebe10102009-08-20 07:17:43 +00003120template<typename Derived>
3121Sema::OwningStmtResult
3122TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3123 // Transform the condition
3124 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3125 if (Cond.isInvalid())
3126 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003127
Douglas Gregorebe10102009-08-20 07:17:43 +00003128 // Transform the body
3129 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3130 if (Body.isInvalid())
3131 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003132
Douglas Gregorebe10102009-08-20 07:17:43 +00003133 if (!getDerived().AlwaysRebuild() &&
3134 Cond.get() == S->getCond() &&
3135 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003136 return SemaRef.Owned(S->Retain());
3137
Douglas Gregorebe10102009-08-20 07:17:43 +00003138 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3139 /*FIXME:*/S->getWhileLoc(), move(Cond),
3140 S->getRParenLoc());
3141}
Mike Stump11289f42009-09-09 15:08:12 +00003142
Douglas Gregorebe10102009-08-20 07:17:43 +00003143template<typename Derived>
3144Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003145TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003146 // Transform the initialization statement
3147 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3148 if (Init.isInvalid())
3149 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003150
Douglas Gregorebe10102009-08-20 07:17:43 +00003151 // Transform the condition
3152 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3153 if (Cond.isInvalid())
3154 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003155
Douglas Gregorebe10102009-08-20 07:17:43 +00003156 // Transform the increment
3157 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3158 if (Inc.isInvalid())
3159 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003160
Douglas Gregorebe10102009-08-20 07:17:43 +00003161 // Transform the body
3162 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3163 if (Body.isInvalid())
3164 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003165
Douglas Gregorebe10102009-08-20 07:17:43 +00003166 if (!getDerived().AlwaysRebuild() &&
3167 Init.get() == S->getInit() &&
3168 Cond.get() == S->getCond() &&
3169 Inc.get() == S->getInc() &&
3170 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003171 return SemaRef.Owned(S->Retain());
3172
Douglas Gregorebe10102009-08-20 07:17:43 +00003173 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3174 move(Init), move(Cond), move(Inc),
3175 S->getRParenLoc(), move(Body));
3176}
3177
3178template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003179Sema::OwningStmtResult
3180TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003181 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003182 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003183 S->getLabel());
3184}
3185
3186template<typename Derived>
3187Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003188TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003189 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3190 if (Target.isInvalid())
3191 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003192
Douglas Gregorebe10102009-08-20 07:17:43 +00003193 if (!getDerived().AlwaysRebuild() &&
3194 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003195 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003196
3197 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3198 move(Target));
3199}
3200
3201template<typename Derived>
3202Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003203TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3204 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003205}
Mike Stump11289f42009-09-09 15:08:12 +00003206
Douglas Gregorebe10102009-08-20 07:17:43 +00003207template<typename Derived>
3208Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003209TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3210 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003211}
Mike Stump11289f42009-09-09 15:08:12 +00003212
Douglas Gregorebe10102009-08-20 07:17:43 +00003213template<typename Derived>
3214Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003215TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003216 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3217 if (Result.isInvalid())
3218 return SemaRef.StmtError();
3219
Mike Stump11289f42009-09-09 15:08:12 +00003220 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003221 // to tell whether the return type of the function has changed.
3222 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3223}
Mike Stump11289f42009-09-09 15:08:12 +00003224
Douglas Gregorebe10102009-08-20 07:17:43 +00003225template<typename Derived>
3226Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003227TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003228 bool DeclChanged = false;
3229 llvm::SmallVector<Decl *, 4> Decls;
3230 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3231 D != DEnd; ++D) {
3232 Decl *Transformed = getDerived().TransformDefinition(*D);
3233 if (!Transformed)
3234 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003235
Douglas Gregorebe10102009-08-20 07:17:43 +00003236 if (Transformed != *D)
3237 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003238
Douglas Gregorebe10102009-08-20 07:17:43 +00003239 Decls.push_back(Transformed);
3240 }
Mike Stump11289f42009-09-09 15:08:12 +00003241
Douglas Gregorebe10102009-08-20 07:17:43 +00003242 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003243 return SemaRef.Owned(S->Retain());
3244
3245 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003246 S->getStartLoc(), S->getEndLoc());
3247}
Mike Stump11289f42009-09-09 15:08:12 +00003248
Douglas Gregorebe10102009-08-20 07:17:43 +00003249template<typename Derived>
3250Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003251TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003252 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003253 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003254}
3255
3256template<typename Derived>
3257Sema::OwningStmtResult
3258TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3259 // FIXME: Implement!
3260 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003261 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003262}
3263
3264
3265template<typename Derived>
3266Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003267TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003268 // FIXME: Implement this
3269 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003270 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003271}
Mike Stump11289f42009-09-09 15:08:12 +00003272
Douglas Gregorebe10102009-08-20 07:17:43 +00003273template<typename Derived>
3274Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003275TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003276 // FIXME: Implement this
3277 assert(false && "Cannot transform an Objective-C @catch statement");
3278 return SemaRef.Owned(S->Retain());
3279}
Mike Stump11289f42009-09-09 15:08:12 +00003280
Douglas Gregorebe10102009-08-20 07:17:43 +00003281template<typename Derived>
3282Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003283TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003284 // FIXME: Implement this
3285 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003286 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003287}
Mike Stump11289f42009-09-09 15:08:12 +00003288
Douglas Gregorebe10102009-08-20 07:17:43 +00003289template<typename Derived>
3290Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003291TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003292 // FIXME: Implement this
3293 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003294 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003295}
Mike Stump11289f42009-09-09 15:08:12 +00003296
Douglas Gregorebe10102009-08-20 07:17:43 +00003297template<typename Derived>
3298Sema::OwningStmtResult
3299TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003300 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003301 // FIXME: Implement this
3302 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003303 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003304}
3305
3306template<typename Derived>
3307Sema::OwningStmtResult
3308TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003309 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003310 // FIXME: Implement this
3311 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003312 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003313}
3314
3315
3316template<typename Derived>
3317Sema::OwningStmtResult
3318TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3319 // Transform the exception declaration, if any.
3320 VarDecl *Var = 0;
3321 if (S->getExceptionDecl()) {
3322 VarDecl *ExceptionDecl = S->getExceptionDecl();
3323 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3324 ExceptionDecl->getDeclName());
3325
3326 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3327 if (T.isNull())
3328 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003329
Douglas Gregorebe10102009-08-20 07:17:43 +00003330 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3331 T,
3332 ExceptionDecl->getDeclaratorInfo(),
3333 ExceptionDecl->getIdentifier(),
3334 ExceptionDecl->getLocation(),
3335 /*FIXME: Inaccurate*/
3336 SourceRange(ExceptionDecl->getLocation()));
3337 if (!Var || Var->isInvalidDecl()) {
3338 if (Var)
3339 Var->Destroy(SemaRef.Context);
3340 return SemaRef.StmtError();
3341 }
3342 }
Mike Stump11289f42009-09-09 15:08:12 +00003343
Douglas Gregorebe10102009-08-20 07:17:43 +00003344 // Transform the actual exception handler.
3345 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3346 if (Handler.isInvalid()) {
3347 if (Var)
3348 Var->Destroy(SemaRef.Context);
3349 return SemaRef.StmtError();
3350 }
Mike Stump11289f42009-09-09 15:08:12 +00003351
Douglas Gregorebe10102009-08-20 07:17:43 +00003352 if (!getDerived().AlwaysRebuild() &&
3353 !Var &&
3354 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003355 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003356
3357 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3358 Var,
3359 move(Handler));
3360}
Mike Stump11289f42009-09-09 15:08:12 +00003361
Douglas Gregorebe10102009-08-20 07:17:43 +00003362template<typename Derived>
3363Sema::OwningStmtResult
3364TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3365 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003366 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003367 = getDerived().TransformCompoundStmt(S->getTryBlock());
3368 if (TryBlock.isInvalid())
3369 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003370
Douglas Gregorebe10102009-08-20 07:17:43 +00003371 // Transform the handlers.
3372 bool HandlerChanged = false;
3373 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3374 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003375 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003376 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3377 if (Handler.isInvalid())
3378 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003379
Douglas Gregorebe10102009-08-20 07:17:43 +00003380 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3381 Handlers.push_back(Handler.takeAs<Stmt>());
3382 }
Mike Stump11289f42009-09-09 15:08:12 +00003383
Douglas Gregorebe10102009-08-20 07:17:43 +00003384 if (!getDerived().AlwaysRebuild() &&
3385 TryBlock.get() == S->getTryBlock() &&
3386 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003387 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003388
3389 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003390 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003391}
Mike Stump11289f42009-09-09 15:08:12 +00003392
Douglas Gregorebe10102009-08-20 07:17:43 +00003393//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003394// Expression transformation
3395//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003396template<typename Derived>
3397Sema::OwningExprResult
3398TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
3399 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003400}
Mike Stump11289f42009-09-09 15:08:12 +00003401
3402template<typename Derived>
3403Sema::OwningExprResult
3404TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003405 NestedNameSpecifier *Qualifier = 0;
3406 if (E->getQualifier()) {
3407 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3408 E->getQualifierRange());
3409 if (!Qualifier)
3410 return SemaRef.ExprError();
3411 }
3412
Mike Stump11289f42009-09-09 15:08:12 +00003413 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003414 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3415 if (!ND)
3416 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003417
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003418 if (!getDerived().AlwaysRebuild() &&
3419 Qualifier == E->getQualifier() &&
3420 ND == E->getDecl() &&
3421 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003422 return SemaRef.Owned(E->Retain());
3423
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003424 // FIXME: We're losing the explicit template arguments in this transformation.
3425
John McCall0ad16662009-10-29 08:12:44 +00003426 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003427 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00003428 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3429 TransArgs[I]))
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003430 return SemaRef.ExprError();
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003431 }
3432
3433 // FIXME: Pass the qualifier/qualifier range along.
3434 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
3435 ND, E->getLocation());
Douglas Gregora16548e2009-08-11 05:31:07 +00003436}
Mike Stump11289f42009-09-09 15:08:12 +00003437
Douglas Gregora16548e2009-08-11 05:31:07 +00003438template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003439Sema::OwningExprResult
3440TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
3441 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003442}
Mike Stump11289f42009-09-09 15:08:12 +00003443
Douglas Gregora16548e2009-08-11 05:31:07 +00003444template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003445Sema::OwningExprResult
3446TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
3447 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003448}
Mike Stump11289f42009-09-09 15:08:12 +00003449
Douglas Gregora16548e2009-08-11 05:31:07 +00003450template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003451Sema::OwningExprResult
3452TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
3453 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003454}
Mike Stump11289f42009-09-09 15:08:12 +00003455
Douglas Gregora16548e2009-08-11 05:31:07 +00003456template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003457Sema::OwningExprResult
3458TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
3459 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003460}
Mike Stump11289f42009-09-09 15:08:12 +00003461
Douglas Gregora16548e2009-08-11 05:31:07 +00003462template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003463Sema::OwningExprResult
3464TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
3465 return SemaRef.Owned(E->Retain());
3466}
3467
3468template<typename Derived>
3469Sema::OwningExprResult
3470TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003471 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3472 if (SubExpr.isInvalid())
3473 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003474
Douglas Gregora16548e2009-08-11 05:31:07 +00003475 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003476 return SemaRef.Owned(E->Retain());
3477
3478 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003479 E->getRParen());
3480}
3481
Mike Stump11289f42009-09-09 15:08:12 +00003482template<typename Derived>
3483Sema::OwningExprResult
3484TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003485 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3486 if (SubExpr.isInvalid())
3487 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003488
Douglas Gregora16548e2009-08-11 05:31:07 +00003489 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003490 return SemaRef.Owned(E->Retain());
3491
Douglas Gregora16548e2009-08-11 05:31:07 +00003492 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3493 E->getOpcode(),
3494 move(SubExpr));
3495}
Mike Stump11289f42009-09-09 15:08:12 +00003496
Douglas Gregora16548e2009-08-11 05:31:07 +00003497template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003498Sema::OwningExprResult
3499TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003500 if (E->isArgumentType()) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003501 TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
3502
Douglas Gregora16548e2009-08-11 05:31:07 +00003503 QualType T = getDerived().TransformType(E->getArgumentType());
3504 if (T.isNull())
3505 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003506
Douglas Gregora16548e2009-08-11 05:31:07 +00003507 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3508 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003509
3510 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3511 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003512 E->getSourceRange());
3513 }
Mike Stump11289f42009-09-09 15:08:12 +00003514
Douglas Gregora16548e2009-08-11 05:31:07 +00003515 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003516 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003517 // C++0x [expr.sizeof]p1:
3518 // The operand is either an expression, which is an unevaluated operand
3519 // [...]
3520 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003521
Douglas Gregora16548e2009-08-11 05:31:07 +00003522 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3523 if (SubExpr.isInvalid())
3524 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003525
Douglas Gregora16548e2009-08-11 05:31:07 +00003526 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3527 return SemaRef.Owned(E->Retain());
3528 }
Mike Stump11289f42009-09-09 15:08:12 +00003529
Douglas Gregora16548e2009-08-11 05:31:07 +00003530 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3531 E->isSizeOf(),
3532 E->getSourceRange());
3533}
Mike Stump11289f42009-09-09 15:08:12 +00003534
Douglas Gregora16548e2009-08-11 05:31:07 +00003535template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003536Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003537TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3538 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3539 if (LHS.isInvalid())
3540 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003541
Douglas Gregora16548e2009-08-11 05:31:07 +00003542 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3543 if (RHS.isInvalid())
3544 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003545
3546
Douglas Gregora16548e2009-08-11 05:31:07 +00003547 if (!getDerived().AlwaysRebuild() &&
3548 LHS.get() == E->getLHS() &&
3549 RHS.get() == E->getRHS())
3550 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003551
Douglas Gregora16548e2009-08-11 05:31:07 +00003552 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3553 /*FIXME:*/E->getLHS()->getLocStart(),
3554 move(RHS),
3555 E->getRBracketLoc());
3556}
Mike Stump11289f42009-09-09 15:08:12 +00003557
3558template<typename Derived>
3559Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003560TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3561 // Transform the callee.
3562 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3563 if (Callee.isInvalid())
3564 return SemaRef.ExprError();
3565
3566 // Transform arguments.
3567 bool ArgChanged = false;
3568 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3569 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3570 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3571 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3572 if (Arg.isInvalid())
3573 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003574
Douglas Gregora16548e2009-08-11 05:31:07 +00003575 // FIXME: Wrong source location information for the ','.
3576 FakeCommaLocs.push_back(
3577 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003578
3579 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003580 Args.push_back(Arg.takeAs<Expr>());
3581 }
Mike Stump11289f42009-09-09 15:08:12 +00003582
Douglas Gregora16548e2009-08-11 05:31:07 +00003583 if (!getDerived().AlwaysRebuild() &&
3584 Callee.get() == E->getCallee() &&
3585 !ArgChanged)
3586 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003587
Douglas Gregora16548e2009-08-11 05:31:07 +00003588 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003589 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003590 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3591 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3592 move_arg(Args),
3593 FakeCommaLocs.data(),
3594 E->getRParenLoc());
3595}
Mike Stump11289f42009-09-09 15:08:12 +00003596
3597template<typename Derived>
3598Sema::OwningExprResult
3599TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003600 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3601 if (Base.isInvalid())
3602 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003603
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003604 NestedNameSpecifier *Qualifier = 0;
3605 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003606 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003607 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3608 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003609 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003610 return SemaRef.ExprError();
3611 }
Mike Stump11289f42009-09-09 15:08:12 +00003612
3613 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003614 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3615 if (!Member)
3616 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003617
Douglas Gregora16548e2009-08-11 05:31:07 +00003618 if (!getDerived().AlwaysRebuild() &&
3619 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003620 Qualifier == E->getQualifier() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00003621 Member == E->getMemberDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003622 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003623
3624 // FIXME: Bogus source location for the operator
3625 SourceLocation FakeOperatorLoc
3626 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3627
3628 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3629 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003630 Qualifier,
3631 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003632 E->getMemberLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003633 Member);
Douglas Gregora16548e2009-08-11 05:31:07 +00003634}
Mike Stump11289f42009-09-09 15:08:12 +00003635
Douglas Gregora16548e2009-08-11 05:31:07 +00003636template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003637Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003638TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3639 assert(false && "Cannot transform abstract class");
3640 return SemaRef.Owned(E->Retain());
3641}
3642
3643template<typename Derived>
3644Sema::OwningExprResult
3645TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003646 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3647 if (LHS.isInvalid())
3648 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003649
Douglas Gregora16548e2009-08-11 05:31:07 +00003650 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3651 if (RHS.isInvalid())
3652 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003653
Douglas Gregora16548e2009-08-11 05:31:07 +00003654 if (!getDerived().AlwaysRebuild() &&
3655 LHS.get() == E->getLHS() &&
3656 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003657 return SemaRef.Owned(E->Retain());
3658
Douglas Gregora16548e2009-08-11 05:31:07 +00003659 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3660 move(LHS), move(RHS));
3661}
3662
Mike Stump11289f42009-09-09 15:08:12 +00003663template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003664Sema::OwningExprResult
3665TreeTransform<Derived>::TransformCompoundAssignOperator(
3666 CompoundAssignOperator *E) {
3667 return getDerived().TransformBinaryOperator(E);
3668}
Mike Stump11289f42009-09-09 15:08:12 +00003669
Douglas Gregora16548e2009-08-11 05:31:07 +00003670template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003671Sema::OwningExprResult
3672TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003673 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3674 if (Cond.isInvalid())
3675 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003676
Douglas Gregora16548e2009-08-11 05:31:07 +00003677 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3678 if (LHS.isInvalid())
3679 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003680
Douglas Gregora16548e2009-08-11 05:31:07 +00003681 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3682 if (RHS.isInvalid())
3683 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003684
Douglas Gregora16548e2009-08-11 05:31:07 +00003685 if (!getDerived().AlwaysRebuild() &&
3686 Cond.get() == E->getCond() &&
3687 LHS.get() == E->getLHS() &&
3688 RHS.get() == E->getRHS())
3689 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003690
3691 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003692 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003693 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003694 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003695 move(RHS));
3696}
Mike Stump11289f42009-09-09 15:08:12 +00003697
3698template<typename Derived>
3699Sema::OwningExprResult
3700TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003701 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3702
3703 // FIXME: Will we ever have type information here? It seems like we won't,
3704 // so do we even need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003705 QualType T = getDerived().TransformType(E->getType());
3706 if (T.isNull())
3707 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003708
Douglas Gregora16548e2009-08-11 05:31:07 +00003709 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3710 if (SubExpr.isInvalid())
3711 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003712
Douglas Gregora16548e2009-08-11 05:31:07 +00003713 if (!getDerived().AlwaysRebuild() &&
3714 T == E->getType() &&
3715 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003716 return SemaRef.Owned(E->Retain());
3717
Douglas Gregora16548e2009-08-11 05:31:07 +00003718 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003719 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003720 E->isLvalueCast());
3721}
Mike Stump11289f42009-09-09 15:08:12 +00003722
Douglas Gregora16548e2009-08-11 05:31:07 +00003723template<typename Derived>
3724Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003725TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3726 assert(false && "Cannot transform abstract class");
3727 return SemaRef.Owned(E->Retain());
3728}
3729
3730template<typename Derived>
3731Sema::OwningExprResult
3732TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003733 QualType T;
3734 {
3735 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003736 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003737 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3738 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003739
Douglas Gregora16548e2009-08-11 05:31:07 +00003740 T = getDerived().TransformType(E->getTypeAsWritten());
3741 if (T.isNull())
3742 return SemaRef.ExprError();
3743 }
Mike Stump11289f42009-09-09 15:08:12 +00003744
Douglas Gregora16548e2009-08-11 05:31:07 +00003745 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3746 if (SubExpr.isInvalid())
3747 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003748
Douglas Gregora16548e2009-08-11 05:31:07 +00003749 if (!getDerived().AlwaysRebuild() &&
3750 T == E->getTypeAsWritten() &&
3751 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003752 return SemaRef.Owned(E->Retain());
3753
Douglas Gregora16548e2009-08-11 05:31:07 +00003754 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3755 E->getRParenLoc(),
3756 move(SubExpr));
3757}
Mike Stump11289f42009-09-09 15:08:12 +00003758
Douglas Gregora16548e2009-08-11 05:31:07 +00003759template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003760Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003761TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3762 QualType T;
3763 {
3764 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003765 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003766 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3767 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003768
Douglas Gregora16548e2009-08-11 05:31:07 +00003769 T = getDerived().TransformType(E->getType());
3770 if (T.isNull())
3771 return SemaRef.ExprError();
3772 }
Mike Stump11289f42009-09-09 15:08:12 +00003773
Douglas Gregora16548e2009-08-11 05:31:07 +00003774 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3775 if (Init.isInvalid())
3776 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003777
Douglas Gregora16548e2009-08-11 05:31:07 +00003778 if (!getDerived().AlwaysRebuild() &&
3779 T == E->getType() &&
3780 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003781 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003782
3783 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3784 /*FIXME:*/E->getInitializer()->getLocEnd(),
3785 move(Init));
3786}
Mike Stump11289f42009-09-09 15:08:12 +00003787
Douglas Gregora16548e2009-08-11 05:31:07 +00003788template<typename Derived>
3789Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003790TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003791 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3792 if (Base.isInvalid())
3793 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003794
Douglas Gregora16548e2009-08-11 05:31:07 +00003795 if (!getDerived().AlwaysRebuild() &&
3796 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003797 return SemaRef.Owned(E->Retain());
3798
Douglas Gregora16548e2009-08-11 05:31:07 +00003799 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003800 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003801 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3802 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3803 E->getAccessorLoc(),
3804 E->getAccessor());
3805}
Mike Stump11289f42009-09-09 15:08:12 +00003806
Douglas Gregora16548e2009-08-11 05:31:07 +00003807template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003808Sema::OwningExprResult
3809TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003810 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003811
Douglas Gregora16548e2009-08-11 05:31:07 +00003812 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3813 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3814 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3815 if (Init.isInvalid())
3816 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003817
Douglas Gregora16548e2009-08-11 05:31:07 +00003818 InitChanged = InitChanged || Init.get() != E->getInit(I);
3819 Inits.push_back(Init.takeAs<Expr>());
3820 }
Mike Stump11289f42009-09-09 15:08:12 +00003821
Douglas Gregora16548e2009-08-11 05:31:07 +00003822 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003823 return SemaRef.Owned(E->Retain());
3824
Douglas Gregora16548e2009-08-11 05:31:07 +00003825 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3826 E->getRBraceLoc());
3827}
Mike Stump11289f42009-09-09 15:08:12 +00003828
Douglas Gregora16548e2009-08-11 05:31:07 +00003829template<typename Derived>
3830Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003831TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003832 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003833
Douglas Gregorebe10102009-08-20 07:17:43 +00003834 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003835 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3836 if (Init.isInvalid())
3837 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003838
Douglas Gregorebe10102009-08-20 07:17:43 +00003839 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003840 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3841 bool ExprChanged = false;
3842 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3843 DEnd = E->designators_end();
3844 D != DEnd; ++D) {
3845 if (D->isFieldDesignator()) {
3846 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3847 D->getDotLoc(),
3848 D->getFieldLoc()));
3849 continue;
3850 }
Mike Stump11289f42009-09-09 15:08:12 +00003851
Douglas Gregora16548e2009-08-11 05:31:07 +00003852 if (D->isArrayDesignator()) {
3853 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3854 if (Index.isInvalid())
3855 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003856
3857 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003858 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003859
Douglas Gregora16548e2009-08-11 05:31:07 +00003860 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3861 ArrayExprs.push_back(Index.release());
3862 continue;
3863 }
Mike Stump11289f42009-09-09 15:08:12 +00003864
Douglas Gregora16548e2009-08-11 05:31:07 +00003865 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003866 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003867 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3868 if (Start.isInvalid())
3869 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003870
Douglas Gregora16548e2009-08-11 05:31:07 +00003871 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3872 if (End.isInvalid())
3873 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003874
3875 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003876 End.get(),
3877 D->getLBracketLoc(),
3878 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003879
Douglas Gregora16548e2009-08-11 05:31:07 +00003880 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3881 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003882
Douglas Gregora16548e2009-08-11 05:31:07 +00003883 ArrayExprs.push_back(Start.release());
3884 ArrayExprs.push_back(End.release());
3885 }
Mike Stump11289f42009-09-09 15:08:12 +00003886
Douglas Gregora16548e2009-08-11 05:31:07 +00003887 if (!getDerived().AlwaysRebuild() &&
3888 Init.get() == E->getInit() &&
3889 !ExprChanged)
3890 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003891
Douglas Gregora16548e2009-08-11 05:31:07 +00003892 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3893 E->getEqualOrColonLoc(),
3894 E->usesGNUSyntax(), move(Init));
3895}
Mike Stump11289f42009-09-09 15:08:12 +00003896
Douglas Gregora16548e2009-08-11 05:31:07 +00003897template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003898Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003899TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003900 ImplicitValueInitExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003901 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3902
3903 // FIXME: Will we ever have proper type location here? Will we actually
3904 // need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003905 QualType T = getDerived().TransformType(E->getType());
3906 if (T.isNull())
3907 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003908
Douglas Gregora16548e2009-08-11 05:31:07 +00003909 if (!getDerived().AlwaysRebuild() &&
3910 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003911 return SemaRef.Owned(E->Retain());
3912
Douglas Gregora16548e2009-08-11 05:31:07 +00003913 return getDerived().RebuildImplicitValueInitExpr(T);
3914}
Mike Stump11289f42009-09-09 15:08:12 +00003915
Douglas Gregora16548e2009-08-11 05:31:07 +00003916template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003917Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003918TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3919 // FIXME: Do we want the type as written?
3920 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003921
Douglas Gregora16548e2009-08-11 05:31:07 +00003922 {
3923 // FIXME: Source location isn't quite accurate.
3924 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3925 T = getDerived().TransformType(E->getType());
3926 if (T.isNull())
3927 return SemaRef.ExprError();
3928 }
Mike Stump11289f42009-09-09 15:08:12 +00003929
Douglas Gregora16548e2009-08-11 05:31:07 +00003930 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3931 if (SubExpr.isInvalid())
3932 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003933
Douglas Gregora16548e2009-08-11 05:31:07 +00003934 if (!getDerived().AlwaysRebuild() &&
3935 T == E->getType() &&
3936 SubExpr.get() == E->getSubExpr())
3937 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003938
Douglas Gregora16548e2009-08-11 05:31:07 +00003939 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3940 T, E->getRParenLoc());
3941}
3942
3943template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003944Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003945TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3946 bool ArgumentChanged = false;
3947 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3948 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3949 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3950 if (Init.isInvalid())
3951 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003952
Douglas Gregora16548e2009-08-11 05:31:07 +00003953 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3954 Inits.push_back(Init.takeAs<Expr>());
3955 }
Mike Stump11289f42009-09-09 15:08:12 +00003956
Douglas Gregora16548e2009-08-11 05:31:07 +00003957 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3958 move_arg(Inits),
3959 E->getRParenLoc());
3960}
Mike Stump11289f42009-09-09 15:08:12 +00003961
Douglas Gregora16548e2009-08-11 05:31:07 +00003962/// \brief Transform an address-of-label expression.
3963///
3964/// By default, the transformation of an address-of-label expression always
3965/// rebuilds the expression, so that the label identifier can be resolved to
3966/// the corresponding label statement by semantic analysis.
3967template<typename Derived>
3968Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003969TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003970 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3971 E->getLabel());
3972}
Mike Stump11289f42009-09-09 15:08:12 +00003973
3974template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003975Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00003976 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00003977 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3978 if (SubStmt.isInvalid())
3979 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003980
Douglas Gregora16548e2009-08-11 05:31:07 +00003981 if (!getDerived().AlwaysRebuild() &&
3982 SubStmt.get() == E->getSubStmt())
3983 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003984
3985 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003986 move(SubStmt),
3987 E->getRParenLoc());
3988}
Mike Stump11289f42009-09-09 15:08:12 +00003989
Douglas Gregora16548e2009-08-11 05:31:07 +00003990template<typename Derived>
3991Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003992TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003993 QualType T1, T2;
3994 {
3995 // FIXME: Source location isn't quite accurate.
3996 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003997
Douglas Gregora16548e2009-08-11 05:31:07 +00003998 T1 = getDerived().TransformType(E->getArgType1());
3999 if (T1.isNull())
4000 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004001
Douglas Gregora16548e2009-08-11 05:31:07 +00004002 T2 = getDerived().TransformType(E->getArgType2());
4003 if (T2.isNull())
4004 return SemaRef.ExprError();
4005 }
4006
4007 if (!getDerived().AlwaysRebuild() &&
4008 T1 == E->getArgType1() &&
4009 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00004010 return SemaRef.Owned(E->Retain());
4011
Douglas Gregora16548e2009-08-11 05:31:07 +00004012 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
4013 T1, T2, E->getRParenLoc());
4014}
Mike Stump11289f42009-09-09 15:08:12 +00004015
Douglas Gregora16548e2009-08-11 05:31:07 +00004016template<typename Derived>
4017Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004018TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004019 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4020 if (Cond.isInvalid())
4021 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004022
Douglas Gregora16548e2009-08-11 05:31:07 +00004023 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4024 if (LHS.isInvalid())
4025 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004026
Douglas Gregora16548e2009-08-11 05:31:07 +00004027 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4028 if (RHS.isInvalid())
4029 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004030
Douglas Gregora16548e2009-08-11 05:31:07 +00004031 if (!getDerived().AlwaysRebuild() &&
4032 Cond.get() == E->getCond() &&
4033 LHS.get() == E->getLHS() &&
4034 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00004035 return SemaRef.Owned(E->Retain());
4036
Douglas Gregora16548e2009-08-11 05:31:07 +00004037 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4038 move(Cond), move(LHS), move(RHS),
4039 E->getRParenLoc());
4040}
Mike Stump11289f42009-09-09 15:08:12 +00004041
Douglas Gregora16548e2009-08-11 05:31:07 +00004042template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004043Sema::OwningExprResult
4044TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
4045 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004046}
4047
4048template<typename Derived>
4049Sema::OwningExprResult
4050TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
4051 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4052 if (Callee.isInvalid())
4053 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004054
Douglas Gregora16548e2009-08-11 05:31:07 +00004055 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
4056 if (First.isInvalid())
4057 return SemaRef.ExprError();
4058
4059 OwningExprResult Second(SemaRef);
4060 if (E->getNumArgs() == 2) {
4061 Second = getDerived().TransformExpr(E->getArg(1));
4062 if (Second.isInvalid())
4063 return SemaRef.ExprError();
4064 }
Mike Stump11289f42009-09-09 15:08:12 +00004065
Douglas Gregora16548e2009-08-11 05:31:07 +00004066 if (!getDerived().AlwaysRebuild() &&
4067 Callee.get() == E->getCallee() &&
4068 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00004069 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4070 return SemaRef.Owned(E->Retain());
4071
Douglas Gregora16548e2009-08-11 05:31:07 +00004072 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4073 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004074 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00004075 move(First),
4076 move(Second));
4077}
Mike Stump11289f42009-09-09 15:08:12 +00004078
Douglas Gregora16548e2009-08-11 05:31:07 +00004079template<typename Derived>
4080Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004081TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004082 return getDerived().TransformCallExpr(E);
4083}
Mike Stump11289f42009-09-09 15:08:12 +00004084
Douglas Gregora16548e2009-08-11 05:31:07 +00004085template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004086Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004087TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
4088 QualType ExplicitTy;
4089 {
4090 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00004091 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004092 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4093 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004094
Douglas Gregora16548e2009-08-11 05:31:07 +00004095 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4096 if (ExplicitTy.isNull())
4097 return SemaRef.ExprError();
4098 }
Mike Stump11289f42009-09-09 15:08:12 +00004099
Douglas Gregora16548e2009-08-11 05:31:07 +00004100 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4101 if (SubExpr.isInvalid())
4102 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004103
Douglas Gregora16548e2009-08-11 05:31:07 +00004104 if (!getDerived().AlwaysRebuild() &&
4105 ExplicitTy == E->getTypeAsWritten() &&
4106 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004107 return SemaRef.Owned(E->Retain());
4108
Douglas Gregora16548e2009-08-11 05:31:07 +00004109 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00004110 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004111 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4112 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4113 SourceLocation FakeRParenLoc
4114 = SemaRef.PP.getLocForEndOfToken(
4115 E->getSubExpr()->getSourceRange().getEnd());
4116 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004117 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004118 FakeLAngleLoc,
4119 ExplicitTy,
4120 FakeRAngleLoc,
4121 FakeRAngleLoc,
4122 move(SubExpr),
4123 FakeRParenLoc);
4124}
Mike Stump11289f42009-09-09 15:08:12 +00004125
Douglas Gregora16548e2009-08-11 05:31:07 +00004126template<typename Derived>
4127Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004128TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004129 return getDerived().TransformCXXNamedCastExpr(E);
4130}
Mike Stump11289f42009-09-09 15:08:12 +00004131
4132template<typename Derived>
4133Sema::OwningExprResult
4134TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
4135 return getDerived().TransformCXXNamedCastExpr(E);
4136}
4137
Douglas Gregora16548e2009-08-11 05:31:07 +00004138template<typename Derived>
4139Sema::OwningExprResult
4140TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004141 CXXReinterpretCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004142 return getDerived().TransformCXXNamedCastExpr(E);
4143}
Mike Stump11289f42009-09-09 15:08:12 +00004144
Douglas Gregora16548e2009-08-11 05:31:07 +00004145template<typename Derived>
4146Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004147TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004148 return getDerived().TransformCXXNamedCastExpr(E);
4149}
Mike Stump11289f42009-09-09 15:08:12 +00004150
Douglas Gregora16548e2009-08-11 05:31:07 +00004151template<typename Derived>
4152Sema::OwningExprResult
4153TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004154 CXXFunctionalCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004155 QualType ExplicitTy;
4156 {
4157 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004158
Douglas Gregora16548e2009-08-11 05:31:07 +00004159 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4160 if (ExplicitTy.isNull())
4161 return SemaRef.ExprError();
4162 }
Mike Stump11289f42009-09-09 15:08:12 +00004163
Douglas Gregora16548e2009-08-11 05:31:07 +00004164 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4165 if (SubExpr.isInvalid())
4166 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004167
Douglas Gregora16548e2009-08-11 05:31:07 +00004168 if (!getDerived().AlwaysRebuild() &&
4169 ExplicitTy == E->getTypeAsWritten() &&
4170 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004171 return SemaRef.Owned(E->Retain());
4172
Douglas Gregora16548e2009-08-11 05:31:07 +00004173 // FIXME: The end of the type's source range is wrong
4174 return getDerived().RebuildCXXFunctionalCastExpr(
4175 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4176 ExplicitTy,
4177 /*FIXME:*/E->getSubExpr()->getLocStart(),
4178 move(SubExpr),
4179 E->getRParenLoc());
4180}
Mike Stump11289f42009-09-09 15:08:12 +00004181
Douglas Gregora16548e2009-08-11 05:31:07 +00004182template<typename Derived>
4183Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004184TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004185 if (E->isTypeOperand()) {
4186 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004187
Douglas Gregora16548e2009-08-11 05:31:07 +00004188 QualType T = getDerived().TransformType(E->getTypeOperand());
4189 if (T.isNull())
4190 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004191
Douglas Gregora16548e2009-08-11 05:31:07 +00004192 if (!getDerived().AlwaysRebuild() &&
4193 T == E->getTypeOperand())
4194 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004195
Douglas Gregora16548e2009-08-11 05:31:07 +00004196 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4197 /*FIXME:*/E->getLocStart(),
4198 T,
4199 E->getLocEnd());
4200 }
Mike Stump11289f42009-09-09 15:08:12 +00004201
Douglas Gregora16548e2009-08-11 05:31:07 +00004202 // We don't know whether the expression is potentially evaluated until
4203 // after we perform semantic analysis, so the expression is potentially
4204 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004205 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004206 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004207
Douglas Gregora16548e2009-08-11 05:31:07 +00004208 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4209 if (SubExpr.isInvalid())
4210 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004211
Douglas Gregora16548e2009-08-11 05:31:07 +00004212 if (!getDerived().AlwaysRebuild() &&
4213 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004214 return SemaRef.Owned(E->Retain());
4215
Douglas Gregora16548e2009-08-11 05:31:07 +00004216 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4217 /*FIXME:*/E->getLocStart(),
4218 move(SubExpr),
4219 E->getLocEnd());
4220}
4221
4222template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004223Sema::OwningExprResult
4224TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
4225 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004226}
Mike Stump11289f42009-09-09 15:08:12 +00004227
Douglas Gregora16548e2009-08-11 05:31:07 +00004228template<typename Derived>
4229Sema::OwningExprResult
4230TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004231 CXXNullPtrLiteralExpr *E) {
4232 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004233}
Mike Stump11289f42009-09-09 15:08:12 +00004234
Douglas Gregora16548e2009-08-11 05:31:07 +00004235template<typename Derived>
4236Sema::OwningExprResult
4237TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
4238 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004239
Douglas Gregora16548e2009-08-11 05:31:07 +00004240 QualType T = getDerived().TransformType(E->getType());
4241 if (T.isNull())
4242 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004243
Douglas Gregora16548e2009-08-11 05:31:07 +00004244 if (!getDerived().AlwaysRebuild() &&
4245 T == E->getType())
4246 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004247
Douglas Gregora16548e2009-08-11 05:31:07 +00004248 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4249}
Mike Stump11289f42009-09-09 15:08:12 +00004250
Douglas Gregora16548e2009-08-11 05:31:07 +00004251template<typename Derived>
4252Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004253TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004254 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4255 if (SubExpr.isInvalid())
4256 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004257
Douglas Gregora16548e2009-08-11 05:31:07 +00004258 if (!getDerived().AlwaysRebuild() &&
4259 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004260 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004261
4262 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4263}
Mike Stump11289f42009-09-09 15:08:12 +00004264
Douglas Gregora16548e2009-08-11 05:31:07 +00004265template<typename Derived>
4266Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004267TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
4268 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004269 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4270 if (!Param)
4271 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004272
Douglas Gregora16548e2009-08-11 05:31:07 +00004273 if (getDerived().AlwaysRebuild() &&
4274 Param == E->getParam())
4275 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004276
Douglas Gregora16548e2009-08-11 05:31:07 +00004277 return getDerived().RebuildCXXDefaultArgExpr(Param);
4278}
Mike Stump11289f42009-09-09 15:08:12 +00004279
Douglas Gregora16548e2009-08-11 05:31:07 +00004280template<typename Derived>
4281Sema::OwningExprResult
4282TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
4283 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4284
4285 QualType T = getDerived().TransformType(E->getType());
4286 if (T.isNull())
4287 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004288
Douglas Gregora16548e2009-08-11 05:31:07 +00004289 if (!getDerived().AlwaysRebuild() &&
4290 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004291 return SemaRef.Owned(E->Retain());
4292
4293 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004294 /*FIXME:*/E->getTypeBeginLoc(),
4295 T,
4296 E->getRParenLoc());
4297}
Mike Stump11289f42009-09-09 15:08:12 +00004298
Douglas Gregora16548e2009-08-11 05:31:07 +00004299template<typename Derived>
4300Sema::OwningExprResult
4301TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00004302 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004303 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004304 if (!Var)
4305 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004306
Douglas Gregora16548e2009-08-11 05:31:07 +00004307 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004308 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004309 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004310
4311 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004312 /*FIXME:*/E->getStartLoc(),
4313 Var);
4314}
Mike Stump11289f42009-09-09 15:08:12 +00004315
Douglas Gregora16548e2009-08-11 05:31:07 +00004316template<typename Derived>
4317Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004318TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004319 // Transform the type that we're allocating
4320 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4321 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4322 if (AllocType.isNull())
4323 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004324
Douglas Gregora16548e2009-08-11 05:31:07 +00004325 // Transform the size of the array we're allocating (if any).
4326 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4327 if (ArraySize.isInvalid())
4328 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004329
Douglas Gregora16548e2009-08-11 05:31:07 +00004330 // Transform the placement arguments (if any).
4331 bool ArgumentChanged = false;
4332 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4333 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4334 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4335 if (Arg.isInvalid())
4336 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004337
Douglas Gregora16548e2009-08-11 05:31:07 +00004338 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4339 PlacementArgs.push_back(Arg.take());
4340 }
Mike Stump11289f42009-09-09 15:08:12 +00004341
Douglas Gregorebe10102009-08-20 07:17:43 +00004342 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004343 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4344 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4345 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4346 if (Arg.isInvalid())
4347 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004348
Douglas Gregora16548e2009-08-11 05:31:07 +00004349 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4350 ConstructorArgs.push_back(Arg.take());
4351 }
Mike Stump11289f42009-09-09 15:08:12 +00004352
Douglas Gregora16548e2009-08-11 05:31:07 +00004353 if (!getDerived().AlwaysRebuild() &&
4354 AllocType == E->getAllocatedType() &&
4355 ArraySize.get() == E->getArraySize() &&
4356 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004357 return SemaRef.Owned(E->Retain());
4358
Douglas Gregora16548e2009-08-11 05:31:07 +00004359 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4360 E->isGlobalNew(),
4361 /*FIXME:*/E->getLocStart(),
4362 move_arg(PlacementArgs),
4363 /*FIXME:*/E->getLocStart(),
4364 E->isParenTypeId(),
4365 AllocType,
4366 /*FIXME:*/E->getLocStart(),
4367 /*FIXME:*/SourceRange(),
4368 move(ArraySize),
4369 /*FIXME:*/E->getLocStart(),
4370 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004371 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004372}
Mike Stump11289f42009-09-09 15:08:12 +00004373
Douglas Gregora16548e2009-08-11 05:31:07 +00004374template<typename Derived>
4375Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004376TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004377 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4378 if (Operand.isInvalid())
4379 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004380
Douglas Gregora16548e2009-08-11 05:31:07 +00004381 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004382 Operand.get() == E->getArgument())
4383 return SemaRef.Owned(E->Retain());
4384
Douglas Gregora16548e2009-08-11 05:31:07 +00004385 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4386 E->isGlobalDelete(),
4387 E->isArrayForm(),
4388 move(Operand));
4389}
Mike Stump11289f42009-09-09 15:08:12 +00004390
Douglas Gregora16548e2009-08-11 05:31:07 +00004391template<typename Derived>
4392Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004393TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
4394 CXXPseudoDestructorExpr *E) {
4395 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4396 if (Base.isInvalid())
4397 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004398
Douglas Gregorad8a3362009-09-04 17:36:40 +00004399 NestedNameSpecifier *Qualifier
4400 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4401 E->getQualifierRange());
4402 if (E->getQualifier() && !Qualifier)
4403 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004404
Douglas Gregorad8a3362009-09-04 17:36:40 +00004405 QualType DestroyedType;
4406 {
4407 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4408 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4409 if (DestroyedType.isNull())
4410 return SemaRef.ExprError();
4411 }
Mike Stump11289f42009-09-09 15:08:12 +00004412
Douglas Gregorad8a3362009-09-04 17:36:40 +00004413 if (!getDerived().AlwaysRebuild() &&
4414 Base.get() == E->getBase() &&
4415 Qualifier == E->getQualifier() &&
4416 DestroyedType == E->getDestroyedType())
4417 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004418
Douglas Gregorad8a3362009-09-04 17:36:40 +00004419 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4420 E->getOperatorLoc(),
4421 E->isArrow(),
4422 E->getDestroyedTypeLoc(),
4423 DestroyedType,
4424 Qualifier,
4425 E->getQualifierRange());
4426}
Mike Stump11289f42009-09-09 15:08:12 +00004427
Douglas Gregorad8a3362009-09-04 17:36:40 +00004428template<typename Derived>
4429Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004430TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004431 UnresolvedFunctionNameExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004432 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004433 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004434}
Mike Stump11289f42009-09-09 15:08:12 +00004435
Douglas Gregora16548e2009-08-11 05:31:07 +00004436template<typename Derived>
4437Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004438TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004439 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004440
Douglas Gregora16548e2009-08-11 05:31:07 +00004441 QualType T = getDerived().TransformType(E->getQueriedType());
4442 if (T.isNull())
4443 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004444
Douglas Gregora16548e2009-08-11 05:31:07 +00004445 if (!getDerived().AlwaysRebuild() &&
4446 T == E->getQueriedType())
4447 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004448
Douglas Gregora16548e2009-08-11 05:31:07 +00004449 // FIXME: Bad location information
4450 SourceLocation FakeLParenLoc
4451 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004452
4453 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004454 E->getLocStart(),
4455 /*FIXME:*/FakeLParenLoc,
4456 T,
4457 E->getLocEnd());
4458}
Mike Stump11289f42009-09-09 15:08:12 +00004459
Douglas Gregora16548e2009-08-11 05:31:07 +00004460template<typename Derived>
4461Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004462TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004463 UnresolvedDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004464 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004465 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4466 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004467 if (!NNS)
4468 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004469
4470 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004471 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4472 if (!Name)
4473 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004474
4475 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004476 NNS == E->getQualifier() &&
4477 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004478 return SemaRef.Owned(E->Retain());
4479
4480 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004481 E->getQualifierRange(),
4482 Name,
4483 E->getLocation(),
4484 /*FIXME:*/false);
4485}
4486
4487template<typename Derived>
4488Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004489TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
Douglas Gregorba91b892009-10-29 17:56:10 +00004490 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4491
Mike Stump11289f42009-09-09 15:08:12 +00004492 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004493 = getDerived().TransformTemplateName(E->getTemplateName());
4494 if (Template.isNull())
4495 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004496
Douglas Gregord019ff62009-10-22 17:20:55 +00004497 NestedNameSpecifier *Qualifier = 0;
4498 if (E->getQualifier()) {
4499 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4500 E->getQualifierRange());
4501 if (!Qualifier)
4502 return SemaRef.ExprError();
4503 }
4504
John McCall0ad16662009-10-29 08:12:44 +00004505 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora16548e2009-08-11 05:31:07 +00004506 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004507 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4508 TransArgs[I]))
Douglas Gregora16548e2009-08-11 05:31:07 +00004509 return SemaRef.ExprError();
Douglas Gregora16548e2009-08-11 05:31:07 +00004510 }
4511
4512 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4513 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004514
4515 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004516 // actually refers to a type, in which case the caller is actually dealing
4517 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004518 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4519 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004520 E->getLAngleLoc(),
4521 TransArgs.data(),
4522 TransArgs.size(),
4523 E->getRAngleLoc());
4524}
4525
4526template<typename Derived>
4527Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004528TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004529 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4530
4531 QualType T = getDerived().TransformType(E->getType());
4532 if (T.isNull())
4533 return SemaRef.ExprError();
4534
4535 CXXConstructorDecl *Constructor
4536 = cast_or_null<CXXConstructorDecl>(
4537 getDerived().TransformDecl(E->getConstructor()));
4538 if (!Constructor)
4539 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004540
Douglas Gregora16548e2009-08-11 05:31:07 +00004541 bool ArgumentChanged = false;
4542 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004543 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004544 ArgEnd = E->arg_end();
4545 Arg != ArgEnd; ++Arg) {
4546 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4547 if (TransArg.isInvalid())
4548 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004549
Douglas Gregora16548e2009-08-11 05:31:07 +00004550 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4551 Args.push_back(TransArg.takeAs<Expr>());
4552 }
4553
4554 if (!getDerived().AlwaysRebuild() &&
4555 T == E->getType() &&
4556 Constructor == E->getConstructor() &&
4557 !ArgumentChanged)
4558 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004559
Douglas Gregora16548e2009-08-11 05:31:07 +00004560 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4561 move_arg(Args));
4562}
Mike Stump11289f42009-09-09 15:08:12 +00004563
Douglas Gregora16548e2009-08-11 05:31:07 +00004564/// \brief Transform a C++ temporary-binding expression.
4565///
Mike Stump11289f42009-09-09 15:08:12 +00004566/// The transformation of a temporary-binding expression always attempts to
4567/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004568/// subexpression itself did not change, because the temporary variable itself
4569/// must be unique.
4570template<typename Derived>
4571Sema::OwningExprResult
4572TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4573 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4574 if (SubExpr.isInvalid())
4575 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004576
Douglas Gregora16548e2009-08-11 05:31:07 +00004577 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4578}
Mike Stump11289f42009-09-09 15:08:12 +00004579
4580/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004581/// be destroyed after the expression is evaluated.
4582///
Mike Stump11289f42009-09-09 15:08:12 +00004583/// The transformation of a full expression always attempts to build a new
4584/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004585/// subexpression itself did not change, because it will need to capture the
4586/// the new temporary variables introduced in the subexpression.
4587template<typename Derived>
4588Sema::OwningExprResult
4589TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump11289f42009-09-09 15:08:12 +00004590 CXXExprWithTemporaries *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004591 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4592 if (SubExpr.isInvalid())
4593 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004594
Douglas Gregora16548e2009-08-11 05:31:07 +00004595 return SemaRef.Owned(
4596 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4597 E->shouldDestroyTemporaries()));
4598}
Mike Stump11289f42009-09-09 15:08:12 +00004599
Douglas Gregora16548e2009-08-11 05:31:07 +00004600template<typename Derived>
4601Sema::OwningExprResult
4602TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004603 CXXTemporaryObjectExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004604 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4605 QualType T = getDerived().TransformType(E->getType());
4606 if (T.isNull())
4607 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004608
Douglas Gregora16548e2009-08-11 05:31:07 +00004609 CXXConstructorDecl *Constructor
4610 = cast_or_null<CXXConstructorDecl>(
4611 getDerived().TransformDecl(E->getConstructor()));
4612 if (!Constructor)
4613 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004614
Douglas Gregora16548e2009-08-11 05:31:07 +00004615 bool ArgumentChanged = false;
4616 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4617 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004618 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004619 ArgEnd = E->arg_end();
4620 Arg != ArgEnd; ++Arg) {
4621 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4622 if (TransArg.isInvalid())
4623 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004624
Douglas Gregora16548e2009-08-11 05:31:07 +00004625 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4626 Args.push_back((Expr *)TransArg.release());
4627 }
Mike Stump11289f42009-09-09 15:08:12 +00004628
Douglas Gregora16548e2009-08-11 05:31:07 +00004629 if (!getDerived().AlwaysRebuild() &&
4630 T == E->getType() &&
4631 Constructor == E->getConstructor() &&
4632 !ArgumentChanged)
4633 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004634
Douglas Gregora16548e2009-08-11 05:31:07 +00004635 // FIXME: Bogus location information
4636 SourceLocation CommaLoc;
4637 if (Args.size() > 1) {
4638 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004639 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004640 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4641 }
4642 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4643 T,
4644 /*FIXME:*/E->getTypeBeginLoc(),
4645 move_arg(Args),
4646 &CommaLoc,
4647 E->getLocEnd());
4648}
Mike Stump11289f42009-09-09 15:08:12 +00004649
Douglas Gregora16548e2009-08-11 05:31:07 +00004650template<typename Derived>
4651Sema::OwningExprResult
4652TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004653 CXXUnresolvedConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004654 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4655 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4656 if (T.isNull())
4657 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004658
Douglas Gregora16548e2009-08-11 05:31:07 +00004659 bool ArgumentChanged = false;
4660 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4661 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4662 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4663 ArgEnd = E->arg_end();
4664 Arg != ArgEnd; ++Arg) {
4665 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4666 if (TransArg.isInvalid())
4667 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004668
Douglas Gregora16548e2009-08-11 05:31:07 +00004669 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4670 FakeCommaLocs.push_back(
4671 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4672 Args.push_back(TransArg.takeAs<Expr>());
4673 }
Mike Stump11289f42009-09-09 15:08:12 +00004674
Douglas Gregora16548e2009-08-11 05:31:07 +00004675 if (!getDerived().AlwaysRebuild() &&
4676 T == E->getTypeAsWritten() &&
4677 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004678 return SemaRef.Owned(E->Retain());
4679
Douglas Gregora16548e2009-08-11 05:31:07 +00004680 // FIXME: we're faking the locations of the commas
4681 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4682 T,
4683 E->getLParenLoc(),
4684 move_arg(Args),
4685 FakeCommaLocs.data(),
4686 E->getRParenLoc());
4687}
Mike Stump11289f42009-09-09 15:08:12 +00004688
Douglas Gregora16548e2009-08-11 05:31:07 +00004689template<typename Derived>
4690Sema::OwningExprResult
4691TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004692 CXXUnresolvedMemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004693 // Transform the base of the expression.
4694 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4695 if (Base.isInvalid())
4696 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004697
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004698 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004699 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004700 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004701 E->getOperatorLoc(),
4702 E->isArrow()? tok::arrow : tok::period,
4703 ObjectType);
4704 if (Base.isInvalid())
4705 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004706
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004707 // Transform the first part of the nested-name-specifier that qualifies
4708 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004709 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004710 = getDerived().TransformFirstQualifierInScope(
4711 E->getFirstQualifierFoundInScope(),
4712 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004713
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004714 NestedNameSpecifier *Qualifier = 0;
4715 if (E->getQualifier()) {
4716 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4717 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004718 QualType::getFromOpaquePtr(ObjectType),
4719 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004720 if (!Qualifier)
4721 return SemaRef.ExprError();
4722 }
Mike Stump11289f42009-09-09 15:08:12 +00004723
4724 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004725 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4726 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004727 if (!Name)
4728 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004729
Douglas Gregor308047d2009-09-09 00:23:06 +00004730 if (!E->hasExplicitTemplateArgumentList()) {
4731 // This is a reference to a member without an explicitly-specified
4732 // template argument list. Optimize for this common case.
4733 if (!getDerived().AlwaysRebuild() &&
4734 Base.get() == E->getBase() &&
4735 Qualifier == E->getQualifier() &&
4736 Name == E->getMember() &&
4737 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004738 return SemaRef.Owned(E->Retain());
4739
Douglas Gregor308047d2009-09-09 00:23:06 +00004740 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4741 E->isArrow(),
4742 E->getOperatorLoc(),
4743 Qualifier,
4744 E->getQualifierRange(),
4745 Name,
4746 E->getMemberLoc(),
4747 FirstQualifierInScope);
4748 }
4749
4750 // FIXME: This is an ugly hack, which forces the same template name to
4751 // be looked up multiple times. Yuck!
4752 // FIXME: This also won't work for, e.g., x->template operator+<int>
4753 TemplateName OrigTemplateName
4754 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump11289f42009-09-09 15:08:12 +00004755
4756 TemplateName Template
4757 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004758 QualType::getFromOpaquePtr(ObjectType));
4759 if (Template.isNull())
4760 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004761
John McCall0ad16662009-10-29 08:12:44 +00004762 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor308047d2009-09-09 00:23:06 +00004763 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004764 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4765 TransArgs[I]))
Douglas Gregor308047d2009-09-09 00:23:06 +00004766 return SemaRef.ExprError();
Douglas Gregor308047d2009-09-09 00:23:06 +00004767 }
Mike Stump11289f42009-09-09 15:08:12 +00004768
Douglas Gregora16548e2009-08-11 05:31:07 +00004769 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4770 E->isArrow(),
4771 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004772 Qualifier,
4773 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004774 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004775 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004776 FirstQualifierInScope,
4777 E->getLAngleLoc(),
4778 TransArgs.data(),
4779 TransArgs.size(),
4780 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004781}
4782
4783template<typename Derived>
4784Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004785TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4786 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004787}
4788
Mike Stump11289f42009-09-09 15:08:12 +00004789template<typename Derived>
4790Sema::OwningExprResult
4791TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004792 // FIXME: poor source location
4793 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4794 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4795 if (EncodedType.isNull())
4796 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004797
Douglas Gregora16548e2009-08-11 05:31:07 +00004798 if (!getDerived().AlwaysRebuild() &&
4799 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004800 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004801
4802 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4803 EncodedType,
4804 E->getRParenLoc());
4805}
Mike Stump11289f42009-09-09 15:08:12 +00004806
Douglas Gregora16548e2009-08-11 05:31:07 +00004807template<typename Derived>
4808Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004809TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004810 // FIXME: Implement this!
4811 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004812 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004813}
4814
Mike Stump11289f42009-09-09 15:08:12 +00004815template<typename Derived>
4816Sema::OwningExprResult
4817TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4818 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004819}
4820
Mike Stump11289f42009-09-09 15:08:12 +00004821template<typename Derived>
4822Sema::OwningExprResult
4823TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4824 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004825 = cast_or_null<ObjCProtocolDecl>(
4826 getDerived().TransformDecl(E->getProtocol()));
4827 if (!Protocol)
4828 return SemaRef.ExprError();
4829
4830 if (!getDerived().AlwaysRebuild() &&
4831 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004832 return SemaRef.Owned(E->Retain());
4833
Douglas Gregora16548e2009-08-11 05:31:07 +00004834 return getDerived().RebuildObjCProtocolExpr(Protocol,
4835 E->getAtLoc(),
4836 /*FIXME:*/E->getAtLoc(),
4837 /*FIXME:*/E->getAtLoc(),
4838 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004839
Douglas Gregora16548e2009-08-11 05:31:07 +00004840}
4841
Mike Stump11289f42009-09-09 15:08:12 +00004842template<typename Derived>
4843Sema::OwningExprResult
4844TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004845 // FIXME: Implement this!
4846 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004847 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004848}
4849
Mike Stump11289f42009-09-09 15:08:12 +00004850template<typename Derived>
4851Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004852TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4853 // FIXME: Implement this!
4854 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004855 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004856}
4857
Mike Stump11289f42009-09-09 15:08:12 +00004858template<typename Derived>
4859Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004860TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004861 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004862 // FIXME: Implement this!
4863 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004864 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004865}
4866
Mike Stump11289f42009-09-09 15:08:12 +00004867template<typename Derived>
4868Sema::OwningExprResult
4869TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004870 // FIXME: Implement this!
4871 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004872 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004873}
4874
Mike Stump11289f42009-09-09 15:08:12 +00004875template<typename Derived>
4876Sema::OwningExprResult
4877TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004878 // FIXME: Implement this!
4879 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004880 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004881}
4882
Mike Stump11289f42009-09-09 15:08:12 +00004883template<typename Derived>
4884Sema::OwningExprResult
4885TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004886 bool ArgumentChanged = false;
4887 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4888 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4889 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4890 if (SubExpr.isInvalid())
4891 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004892
Douglas Gregora16548e2009-08-11 05:31:07 +00004893 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4894 SubExprs.push_back(SubExpr.takeAs<Expr>());
4895 }
Mike Stump11289f42009-09-09 15:08:12 +00004896
Douglas Gregora16548e2009-08-11 05:31:07 +00004897 if (!getDerived().AlwaysRebuild() &&
4898 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004899 return SemaRef.Owned(E->Retain());
4900
Douglas Gregora16548e2009-08-11 05:31:07 +00004901 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4902 move_arg(SubExprs),
4903 E->getRParenLoc());
4904}
4905
Mike Stump11289f42009-09-09 15:08:12 +00004906template<typename Derived>
4907Sema::OwningExprResult
4908TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004909 // FIXME: Implement this!
4910 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004911 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004912}
4913
Mike Stump11289f42009-09-09 15:08:12 +00004914template<typename Derived>
4915Sema::OwningExprResult
4916TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004917 // FIXME: Implement this!
4918 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004919 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004920}
Mike Stump11289f42009-09-09 15:08:12 +00004921
Douglas Gregora16548e2009-08-11 05:31:07 +00004922//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00004923// Type reconstruction
4924//===----------------------------------------------------------------------===//
4925
Mike Stump11289f42009-09-09 15:08:12 +00004926template<typename Derived>
John McCall70dd5f62009-10-30 00:06:24 +00004927QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
4928 SourceLocation Star) {
4929 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004930 getDerived().getBaseEntity());
4931}
4932
Mike Stump11289f42009-09-09 15:08:12 +00004933template<typename Derived>
John McCall70dd5f62009-10-30 00:06:24 +00004934QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
4935 SourceLocation Star) {
4936 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004937 getDerived().getBaseEntity());
4938}
4939
Mike Stump11289f42009-09-09 15:08:12 +00004940template<typename Derived>
4941QualType
John McCall70dd5f62009-10-30 00:06:24 +00004942TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
4943 bool WrittenAsLValue,
4944 SourceLocation Sigil) {
4945 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
4946 Sigil, getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004947}
4948
4949template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004950QualType
John McCall70dd5f62009-10-30 00:06:24 +00004951TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
4952 QualType ClassType,
4953 SourceLocation Sigil) {
John McCall8ccfcb52009-09-24 19:53:00 +00004954 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00004955 Sigil, getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004956}
4957
4958template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004959QualType
John McCall70dd5f62009-10-30 00:06:24 +00004960TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType,
4961 SourceLocation Sigil) {
4962 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Sigil,
John McCall550e0c22009-10-21 00:40:46 +00004963 getDerived().getBaseEntity());
4964}
4965
4966template<typename Derived>
4967QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004968TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4969 ArrayType::ArraySizeModifier SizeMod,
4970 const llvm::APInt *Size,
4971 Expr *SizeExpr,
4972 unsigned IndexTypeQuals,
4973 SourceRange BracketsRange) {
4974 if (SizeExpr || !Size)
4975 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4976 IndexTypeQuals, BracketsRange,
4977 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00004978
4979 QualType Types[] = {
4980 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4981 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4982 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00004983 };
4984 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4985 QualType SizeType;
4986 for (unsigned I = 0; I != NumTypes; ++I)
4987 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4988 SizeType = Types[I];
4989 break;
4990 }
Mike Stump11289f42009-09-09 15:08:12 +00004991
Douglas Gregord6ff3322009-08-04 16:50:30 +00004992 if (SizeType.isNull())
4993 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00004994
Douglas Gregord6ff3322009-08-04 16:50:30 +00004995 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004996 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004997 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00004998 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004999}
Mike Stump11289f42009-09-09 15:08:12 +00005000
Douglas Gregord6ff3322009-08-04 16:50:30 +00005001template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005002QualType
5003TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005004 ArrayType::ArraySizeModifier SizeMod,
5005 const llvm::APInt &Size,
John McCall70dd5f62009-10-30 00:06:24 +00005006 unsigned IndexTypeQuals,
5007 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005008 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
John McCall70dd5f62009-10-30 00:06:24 +00005009 IndexTypeQuals, BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005010}
5011
5012template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005013QualType
Mike Stump11289f42009-09-09 15:08:12 +00005014TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005015 ArrayType::ArraySizeModifier SizeMod,
John McCall70dd5f62009-10-30 00:06:24 +00005016 unsigned IndexTypeQuals,
5017 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005018 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
John McCall70dd5f62009-10-30 00:06:24 +00005019 IndexTypeQuals, BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005020}
Mike Stump11289f42009-09-09 15:08:12 +00005021
Douglas Gregord6ff3322009-08-04 16:50:30 +00005022template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005023QualType
5024TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005025 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005026 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005027 unsigned IndexTypeQuals,
5028 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005029 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005030 SizeExpr.takeAs<Expr>(),
5031 IndexTypeQuals, BracketsRange);
5032}
5033
5034template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005035QualType
5036TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005037 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005038 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005039 unsigned IndexTypeQuals,
5040 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005041 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005042 SizeExpr.takeAs<Expr>(),
5043 IndexTypeQuals, BracketsRange);
5044}
5045
5046template<typename Derived>
5047QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5048 unsigned NumElements) {
5049 // FIXME: semantic checking!
5050 return SemaRef.Context.getVectorType(ElementType, NumElements);
5051}
Mike Stump11289f42009-09-09 15:08:12 +00005052
Douglas Gregord6ff3322009-08-04 16:50:30 +00005053template<typename Derived>
5054QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5055 unsigned NumElements,
5056 SourceLocation AttributeLoc) {
5057 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5058 NumElements, true);
5059 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00005060 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005061 AttributeLoc);
5062 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5063 AttributeLoc);
5064}
Mike Stump11289f42009-09-09 15:08:12 +00005065
Douglas Gregord6ff3322009-08-04 16:50:30 +00005066template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005067QualType
5068TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00005069 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005070 SourceLocation AttributeLoc) {
5071 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5072}
Mike Stump11289f42009-09-09 15:08:12 +00005073
Douglas Gregord6ff3322009-08-04 16:50:30 +00005074template<typename Derived>
5075QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00005076 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005077 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00005078 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005079 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00005080 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005081 Quals,
5082 getDerived().getBaseLocation(),
5083 getDerived().getBaseEntity());
5084}
Mike Stump11289f42009-09-09 15:08:12 +00005085
Douglas Gregord6ff3322009-08-04 16:50:30 +00005086template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00005087QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5088 return SemaRef.Context.getFunctionNoProtoType(T);
5089}
5090
5091template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005092QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005093 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5094}
5095
5096template<typename Derived>
5097QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5098 return SemaRef.Context.getTypeOfType(Underlying);
5099}
5100
5101template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005102QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005103 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5104}
5105
5106template<typename Derived>
5107QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00005108 TemplateName Template,
5109 SourceLocation TemplateNameLoc,
5110 SourceLocation LAngleLoc,
5111 const TemplateArgumentLoc *Args,
5112 unsigned NumArgs,
5113 SourceLocation RAngleLoc) {
5114 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
5115 Args, NumArgs, RAngleLoc);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005116}
Mike Stump11289f42009-09-09 15:08:12 +00005117
Douglas Gregor1135c352009-08-06 05:28:30 +00005118template<typename Derived>
5119NestedNameSpecifier *
5120TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5121 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00005122 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005123 QualType ObjectType,
5124 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00005125 CXXScopeSpec SS;
5126 // FIXME: The source location information is all wrong.
5127 SS.setRange(Range);
5128 SS.setScopeRep(Prefix);
5129 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005130 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005131 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005132 ObjectType,
5133 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005134 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005135}
5136
5137template<typename Derived>
5138NestedNameSpecifier *
5139TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5140 SourceRange Range,
5141 NamespaceDecl *NS) {
5142 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5143}
5144
5145template<typename Derived>
5146NestedNameSpecifier *
5147TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5148 SourceRange Range,
5149 bool TemplateKW,
5150 QualType T) {
5151 if (T->isDependentType() || T->isRecordType() ||
5152 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005153 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005154 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5155 T.getTypePtr());
5156 }
Mike Stump11289f42009-09-09 15:08:12 +00005157
Douglas Gregor1135c352009-08-06 05:28:30 +00005158 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5159 return 0;
5160}
Mike Stump11289f42009-09-09 15:08:12 +00005161
Douglas Gregor71dc5092009-08-06 06:41:21 +00005162template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005163TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005164TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5165 bool TemplateKW,
5166 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005167 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005168 Template);
5169}
5170
5171template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005172TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005173TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5174 bool TemplateKW,
5175 OverloadedFunctionDecl *Ovl) {
5176 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5177}
5178
5179template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005180TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005181TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005182 const IdentifierInfo &II,
5183 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005184 CXXScopeSpec SS;
5185 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005186 SS.setScopeRep(Qualifier);
Douglas Gregor308047d2009-09-09 00:23:06 +00005187 return getSema().ActOnDependentTemplateName(
5188 /*FIXME:*/getDerived().getBaseLocation(),
5189 II,
5190 /*FIXME:*/getDerived().getBaseLocation(),
5191 SS,
5192 ObjectType.getAsOpaquePtr())
5193 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005194}
Mike Stump11289f42009-09-09 15:08:12 +00005195
Douglas Gregora16548e2009-08-11 05:31:07 +00005196template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005197Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005198TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5199 SourceLocation OpLoc,
5200 ExprArg Callee,
5201 ExprArg First,
5202 ExprArg Second) {
5203 Expr *FirstExpr = (Expr *)First.get();
5204 Expr *SecondExpr = (Expr *)Second.get();
Sebastian Redladba46e2009-10-29 20:17:01 +00005205 DeclRefExpr *DRE
5206 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregora16548e2009-08-11 05:31:07 +00005207 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005208
Douglas Gregora16548e2009-08-11 05:31:07 +00005209 // Determine whether this should be a builtin operation.
Sebastian Redladba46e2009-10-29 20:17:01 +00005210 if (Op == OO_Subscript) {
5211 if (!FirstExpr->getType()->isOverloadableType() &&
5212 !SecondExpr->getType()->isOverloadableType())
5213 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
5214 DRE->getLocStart(),
5215 move(Second), OpLoc);
5216 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005217 if (!FirstExpr->getType()->isOverloadableType()) {
5218 // The argument is not of overloadable type, so try to create a
5219 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005220 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005221 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005222
Douglas Gregora16548e2009-08-11 05:31:07 +00005223 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5224 }
5225 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005226 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005227 !SecondExpr->getType()->isOverloadableType()) {
5228 // Neither of the arguments is an overloadable type, so try to
5229 // create a built-in binary operation.
5230 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005231 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005232 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5233 if (Result.isInvalid())
5234 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005235
Douglas Gregora16548e2009-08-11 05:31:07 +00005236 First.release();
5237 Second.release();
5238 return move(Result);
5239 }
5240 }
Mike Stump11289f42009-09-09 15:08:12 +00005241
5242 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005243 // used during overload resolution.
5244 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005245
Douglas Gregora16548e2009-08-11 05:31:07 +00005246 // FIXME: Do we have to check
5247 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005248 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005249 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005250
Douglas Gregora16548e2009-08-11 05:31:07 +00005251 // Add any functions found via argument-dependent lookup.
5252 Expr *Args[2] = { FirstExpr, SecondExpr };
5253 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005254 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005255 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redlc057f422009-10-23 19:23:15 +00005256 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5257 Functions);
Mike Stump11289f42009-09-09 15:08:12 +00005258
Douglas Gregora16548e2009-08-11 05:31:07 +00005259 // Create the overloaded operator invocation for unary operators.
5260 if (NumArgs == 1 || isPostIncDec) {
Mike Stump11289f42009-09-09 15:08:12 +00005261 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005262 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5263 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5264 }
Mike Stump11289f42009-09-09 15:08:12 +00005265
Sebastian Redladba46e2009-10-29 20:17:01 +00005266 if (Op == OO_Subscript)
5267 return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
5268 move(First),move(Second));
5269
Douglas Gregora16548e2009-08-11 05:31:07 +00005270 // Create the overloaded operator invocation for binary operators.
Mike Stump11289f42009-09-09 15:08:12 +00005271 BinaryOperator::Opcode Opc =
Douglas Gregora16548e2009-08-11 05:31:07 +00005272 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005273 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005274 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5275 if (Result.isInvalid())
5276 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005277
Douglas Gregora16548e2009-08-11 05:31:07 +00005278 First.release();
5279 Second.release();
Mike Stump11289f42009-09-09 15:08:12 +00005280 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00005281}
Mike Stump11289f42009-09-09 15:08:12 +00005282
Douglas Gregord6ff3322009-08-04 16:50:30 +00005283} // end namespace clang
5284
5285#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H