blob: 4cfaf2b79ba8caaacb49ee84a0d2f26b38301a03 [file] [log] [blame]
John McCalla2becad2009-10-21 00:40:46 +00001//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
Douglas Gregor577f75a2009-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"
John McCallf7a1a742009-11-24 19:00:30 +000017#include "Lookup.h"
Douglas Gregordcee1a12009-08-06 05:28:30 +000018#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregorc68afe22009-09-03 21:38:09 +000019#include "clang/AST/Decl.h"
Douglas Gregor657c1ac2009-08-06 22:17:10 +000020#include "clang/AST/Expr.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000021#include "clang/AST/ExprCXX.h"
22#include "clang/AST/ExprObjC.h"
Douglas Gregor43959a92009-08-20 07:17:43 +000023#include "clang/AST/Stmt.h"
24#include "clang/AST/StmtCXX.h"
25#include "clang/AST/StmtObjC.h"
John McCalla2becad2009-10-21 00:40:46 +000026#include "clang/AST/TypeLocBuilder.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000027#include "clang/Parse/Ownership.h"
28#include "clang/Parse/Designator.h"
29#include "clang/Lex/Preprocessor.h"
John McCalla2becad2009-10-21 00:40:46 +000030#include "llvm/Support/ErrorHandling.h"
Douglas Gregor577f75a2009-08-04 16:50:30 +000031#include <algorithm>
32
33namespace clang {
Mike Stump1eb44332009-09-09 15:08:12 +000034
Douglas Gregor577f75a2009-08-04 16:50:30 +000035/// \brief A semantic tree transformation that allows one to transform one
36/// abstract syntax tree into another.
37///
Mike Stump1eb44332009-09-09 15:08:12 +000038/// A new tree transformation is defined by creating a new subclass \c X of
39/// \c TreeTransform<X> and then overriding certain operations to provide
40/// behavior specific to that transformation. For example, template
Douglas Gregor577f75a2009-08-04 16:50:30 +000041/// instantiation is implemented as a tree transformation where the
42/// transformation of TemplateTypeParmType nodes involves substituting the
43/// template arguments for their corresponding template parameters; a similar
44/// transformation is performed for non-type template parameters and
45/// template template parameters.
46///
47/// This tree-transformation template uses static polymorphism to allow
Mike Stump1eb44332009-09-09 15:08:12 +000048/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregor577f75a2009-08-04 16:50:30 +000049/// override any of the transformation or rebuild operators by providing an
50/// operation with the same signature as the default implementation. The
51/// overridding function should not be virtual.
52///
53/// Semantic tree transformations are split into two stages, either of which
54/// can be replaced by a subclass. The "transform" step transforms an AST node
55/// or the parts of an AST node using the various transformation functions,
56/// then passes the pieces on to the "rebuild" step, which constructs a new AST
57/// node of the appropriate kind from the pieces. The default transformation
58/// routines recursively transform the operands to composite AST nodes (e.g.,
59/// the pointee type of a PointerType node) and, if any of those operand nodes
60/// were changed by the transformation, invokes the rebuild operation to create
61/// a new AST node.
62///
Mike Stump1eb44332009-09-09 15:08:12 +000063/// Subclasses can customize the transformation at various levels. The
Douglas Gregor670444e2009-08-04 22:27:00 +000064/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor577f75a2009-08-04 16:50:30 +000065/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
66/// TransformTemplateName(), or TransformTemplateArgument() with entirely
67/// new implementations.
68///
69/// For more fine-grained transformations, subclasses can replace any of the
70/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
Douglas Gregor43959a92009-08-20 07:17:43 +000071/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregor577f75a2009-08-04 16:50:30 +000072/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump1eb44332009-09-09 15:08:12 +000073/// to substitute template arguments for their corresponding template
Douglas Gregor577f75a2009-08-04 16:50:30 +000074/// parameters. Additionally, subclasses can override the \c RebuildXXX
75/// functions to control how AST nodes are rebuilt when their operands change.
76/// By default, \c TreeTransform will invoke semantic analysis to rebuild
77/// AST nodes. However, certain other tree transformations (e.g, cloning) may
78/// be able to use more efficient rebuild steps.
79///
80/// There are a handful of other functions that can be overridden, allowing one
Mike Stump1eb44332009-09-09 15:08:12 +000081/// to avoid traversing nodes that don't need any transformation
Douglas Gregor577f75a2009-08-04 16:50:30 +000082/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
83/// operands have not changed (\c AlwaysRebuild()), and customize the
84/// default locations and entity names used for type-checking
85/// (\c getBaseLocation(), \c getBaseEntity()).
Douglas Gregor577f75a2009-08-04 16:50:30 +000086template<typename Derived>
87class TreeTransform {
88protected:
89 Sema &SemaRef;
Mike Stump1eb44332009-09-09 15:08:12 +000090
91public:
Douglas Gregorb98b1992009-08-11 05:31:07 +000092 typedef Sema::OwningStmtResult OwningStmtResult;
93 typedef Sema::OwningExprResult OwningExprResult;
94 typedef Sema::StmtArg StmtArg;
95 typedef Sema::ExprArg ExprArg;
96 typedef Sema::MultiExprArg MultiExprArg;
Douglas Gregor43959a92009-08-20 07:17:43 +000097 typedef Sema::MultiStmtArg MultiStmtArg;
Douglas Gregor99e9b4d2009-11-25 00:27:52 +000098 typedef Sema::DeclPtrTy DeclPtrTy;
99
Douglas Gregor577f75a2009-08-04 16:50:30 +0000100 /// \brief Initializes a new tree transformer.
101 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000102
Douglas Gregor577f75a2009-08-04 16:50:30 +0000103 /// \brief Retrieves a reference to the derived class.
104 Derived &getDerived() { return static_cast<Derived&>(*this); }
105
106 /// \brief Retrieves a reference to the derived class.
Mike Stump1eb44332009-09-09 15:08:12 +0000107 const Derived &getDerived() const {
108 return static_cast<const Derived&>(*this);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000109 }
110
111 /// \brief Retrieves a reference to the semantic analysis object used for
112 /// this tree transform.
113 Sema &getSema() const { return SemaRef; }
Mike Stump1eb44332009-09-09 15:08:12 +0000114
Douglas Gregor577f75a2009-08-04 16:50:30 +0000115 /// \brief Whether the transformation should always rebuild AST nodes, even
116 /// if none of the children have changed.
117 ///
118 /// Subclasses may override this function to specify when the transformation
119 /// should rebuild all AST nodes.
120 bool AlwaysRebuild() { return false; }
Mike Stump1eb44332009-09-09 15:08:12 +0000121
Douglas Gregor577f75a2009-08-04 16:50:30 +0000122 /// \brief Returns the location of the entity being transformed, if that
123 /// information was not available elsewhere in the AST.
124 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000125 /// By default, returns no source-location information. Subclasses can
Douglas Gregor577f75a2009-08-04 16:50:30 +0000126 /// provide an alternative implementation that provides better location
127 /// information.
128 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump1eb44332009-09-09 15:08:12 +0000129
Douglas Gregor577f75a2009-08-04 16:50:30 +0000130 /// \brief Returns the name of the entity being transformed, if that
131 /// information was not available elsewhere in the AST.
132 ///
133 /// By default, returns an empty name. Subclasses can provide an alternative
134 /// implementation with a more precise name.
135 DeclarationName getBaseEntity() { return DeclarationName(); }
136
Douglas Gregorb98b1992009-08-11 05:31:07 +0000137 /// \brief Sets the "base" location and entity when that
138 /// information is known based on another transformation.
139 ///
140 /// By default, the source location and entity are ignored. Subclasses can
141 /// override this function to provide a customized implementation.
142 void setBase(SourceLocation Loc, DeclarationName Entity) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000143
Douglas Gregorb98b1992009-08-11 05:31:07 +0000144 /// \brief RAII object that temporarily sets the base location and entity
145 /// used for reporting diagnostics in types.
146 class TemporaryBase {
147 TreeTransform &Self;
148 SourceLocation OldLocation;
149 DeclarationName OldEntity;
Mike Stump1eb44332009-09-09 15:08:12 +0000150
Douglas Gregorb98b1992009-08-11 05:31:07 +0000151 public:
152 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump1eb44332009-09-09 15:08:12 +0000153 DeclarationName Entity) : Self(Self) {
Douglas Gregorb98b1992009-08-11 05:31:07 +0000154 OldLocation = Self.getDerived().getBaseLocation();
155 OldEntity = Self.getDerived().getBaseEntity();
156 Self.getDerived().setBase(Location, Entity);
157 }
Mike Stump1eb44332009-09-09 15:08:12 +0000158
Douglas Gregorb98b1992009-08-11 05:31:07 +0000159 ~TemporaryBase() {
160 Self.getDerived().setBase(OldLocation, OldEntity);
161 }
162 };
Mike Stump1eb44332009-09-09 15:08:12 +0000163
164 /// \brief Determine whether the given type \p T has already been
Douglas Gregor577f75a2009-08-04 16:50:30 +0000165 /// transformed.
166 ///
167 /// Subclasses can provide an alternative implementation of this routine
Mike Stump1eb44332009-09-09 15:08:12 +0000168 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregor577f75a2009-08-04 16:50:30 +0000169 /// not change. For example, template instantiation need not traverse
170 /// non-dependent types.
171 bool AlreadyTransformed(QualType T) {
172 return T.isNull();
173 }
174
175 /// \brief Transforms the given type into another type.
176 ///
John McCalla2becad2009-10-21 00:40:46 +0000177 /// By default, this routine transforms a type by creating a
178 /// DeclaratorInfo for it and delegating to the appropriate
179 /// function. This is expensive, but we don't mind, because
180 /// this method is deprecated anyway; all users should be
181 /// switched to storing DeclaratorInfos.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000182 ///
183 /// \returns the transformed type.
184 QualType TransformType(QualType T);
Mike Stump1eb44332009-09-09 15:08:12 +0000185
John McCalla2becad2009-10-21 00:40:46 +0000186 /// \brief Transforms the given type-with-location into a new
187 /// type-with-location.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000188 ///
John McCalla2becad2009-10-21 00:40:46 +0000189 /// By default, this routine transforms a type by delegating to the
190 /// appropriate TransformXXXType to build a new type. Subclasses
191 /// may override this function (to take over all type
192 /// transformations) or some set of the TransformXXXType functions
193 /// to alter the transformation.
194 DeclaratorInfo *TransformType(DeclaratorInfo *DI);
195
196 /// \brief Transform the given type-with-location into a new
197 /// type, collecting location information in the given builder
198 /// as necessary.
199 ///
200 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
Mike Stump1eb44332009-09-09 15:08:12 +0000201
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000202 /// \brief Transform the given statement.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000203 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000204 /// By default, this routine transforms a statement by delegating to the
Douglas Gregor43959a92009-08-20 07:17:43 +0000205 /// appropriate TransformXXXStmt function to transform a specific kind of
206 /// statement or the TransformExpr() function to transform an expression.
207 /// Subclasses may override this function to transform statements using some
208 /// other mechanism.
209 ///
210 /// \returns the transformed statement.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000211 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump1eb44332009-09-09 15:08:12 +0000212
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000213 /// \brief Transform the given expression.
214 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000215 /// By default, this routine transforms an expression by delegating to the
216 /// appropriate TransformXXXExpr function to build a new expression.
217 /// Subclasses may override this function to transform expressions using some
218 /// other mechanism.
219 ///
220 /// \returns the transformed expression.
221 OwningExprResult TransformExpr(Expr *E) {
222 return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
223 }
224
225 /// \brief Transform the given expression.
226 ///
227 /// By default, this routine transforms an expression by delegating to the
228 /// appropriate TransformXXXExpr function to build a new expression.
229 /// Subclasses may override this function to transform expressions using some
230 /// other mechanism.
231 ///
232 /// \returns the transformed expression.
233 OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
Mike Stump1eb44332009-09-09 15:08:12 +0000234
Douglas Gregor577f75a2009-08-04 16:50:30 +0000235 /// \brief Transform the given declaration, which is referenced from a type
236 /// or expression.
237 ///
Douglas Gregordcee1a12009-08-06 05:28:30 +0000238 /// By default, acts as the identity function on declarations. Subclasses
239 /// may override this function to provide alternate behavior.
240 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregor43959a92009-08-20 07:17:43 +0000241
242 /// \brief Transform the definition of the given declaration.
243 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000244 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregor43959a92009-08-20 07:17:43 +0000245 /// Subclasses may override this function to provide alternate behavior.
246 Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
Mike Stump1eb44332009-09-09 15:08:12 +0000247
Douglas Gregor6cd21982009-10-20 05:58:46 +0000248 /// \brief Transform the given declaration, which was the first part of a
249 /// nested-name-specifier in a member access expression.
250 ///
251 /// This specific declaration transformation only applies to the first
252 /// identifier in a nested-name-specifier of a member access expression, e.g.,
253 /// the \c T in \c x->T::member
254 ///
255 /// By default, invokes TransformDecl() to transform the declaration.
256 /// Subclasses may override this function to provide alternate behavior.
257 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
258 return cast_or_null<NamedDecl>(getDerived().TransformDecl(D));
259 }
260
Douglas Gregor577f75a2009-08-04 16:50:30 +0000261 /// \brief Transform the given nested-name-specifier.
262 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000263 /// By default, transforms all of the types and declarations within the
Douglas Gregordcee1a12009-08-06 05:28:30 +0000264 /// nested-name-specifier. Subclasses may override this function to provide
265 /// alternate behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000266 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +0000267 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000268 QualType ObjectType = QualType(),
269 NamedDecl *FirstQualifierInScope = 0);
Mike Stump1eb44332009-09-09 15:08:12 +0000270
Douglas Gregor81499bb2009-09-03 22:13:48 +0000271 /// \brief Transform the given declaration name.
272 ///
273 /// By default, transforms the types of conversion function, constructor,
274 /// and destructor names and then (if needed) rebuilds the declaration name.
275 /// Identifiers and selectors are returned unmodified. Sublcasses may
276 /// override this function to provide alternate behavior.
277 DeclarationName TransformDeclarationName(DeclarationName Name,
Douglas Gregordd62b152009-10-19 22:04:39 +0000278 SourceLocation Loc,
279 QualType ObjectType = QualType());
Mike Stump1eb44332009-09-09 15:08:12 +0000280
Douglas Gregor577f75a2009-08-04 16:50:30 +0000281 /// \brief Transform the given template name.
Mike Stump1eb44332009-09-09 15:08:12 +0000282 ///
Douglas Gregord1067e52009-08-06 06:41:21 +0000283 /// By default, transforms the template name by transforming the declarations
Mike Stump1eb44332009-09-09 15:08:12 +0000284 /// and nested-name-specifiers that occur within the template name.
Douglas Gregord1067e52009-08-06 06:41:21 +0000285 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000286 TemplateName TransformTemplateName(TemplateName Name,
287 QualType ObjectType = QualType());
Mike Stump1eb44332009-09-09 15:08:12 +0000288
Douglas Gregor577f75a2009-08-04 16:50:30 +0000289 /// \brief Transform the given template argument.
290 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000291 /// By default, this operation transforms the type, expression, or
292 /// declaration stored within the template argument and constructs a
Douglas Gregor670444e2009-08-04 22:27:00 +0000293 /// new template argument from the transformed result. Subclasses may
294 /// override this function to provide alternate behavior.
John McCall833ca992009-10-29 08:12:44 +0000295 ///
296 /// Returns true if there was an error.
297 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
298 TemplateArgumentLoc &Output);
299
300 /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
301 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
302 TemplateArgumentLoc &ArgLoc);
303
304 /// \brief Fakes up a DeclaratorInfo for a type.
305 DeclaratorInfo *InventDeclaratorInfo(QualType T) {
306 return SemaRef.Context.getTrivialDeclaratorInfo(T,
307 getDerived().getBaseLocation());
308 }
Mike Stump1eb44332009-09-09 15:08:12 +0000309
John McCalla2becad2009-10-21 00:40:46 +0000310#define ABSTRACT_TYPELOC(CLASS, PARENT)
311#define TYPELOC(CLASS, PARENT) \
312 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
313#include "clang/AST/TypeLocNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +0000314
John McCall85737a72009-10-30 00:06:24 +0000315 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
316
Douglas Gregordd62b152009-10-19 22:04:39 +0000317 QualType
318 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
319 QualType ObjectType);
John McCall833ca992009-10-29 08:12:44 +0000320
321 QualType
322 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
323 TemplateSpecializationTypeLoc TL,
324 QualType ObjectType);
Douglas Gregordd62b152009-10-19 22:04:39 +0000325
Douglas Gregor43959a92009-08-20 07:17:43 +0000326 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump1eb44332009-09-09 15:08:12 +0000327
Douglas Gregor43959a92009-08-20 07:17:43 +0000328#define STMT(Node, Parent) \
329 OwningStmtResult Transform##Node(Node *S);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000330#define EXPR(Node, Parent) \
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000331 OwningExprResult Transform##Node(Node *E, bool isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000332#define ABSTRACT_EXPR(Node, Parent)
333#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +0000334
Douglas Gregor577f75a2009-08-04 16:50:30 +0000335 /// \brief Build a new pointer type given its pointee type.
336 ///
337 /// By default, performs semantic analysis when building the pointer type.
338 /// Subclasses may override this routine to provide different behavior.
John McCall85737a72009-10-30 00:06:24 +0000339 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000340
341 /// \brief Build a new block pointer type given its pointee type.
342 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000343 /// By default, performs semantic analysis when building the block pointer
Douglas Gregor577f75a2009-08-04 16:50:30 +0000344 /// type. Subclasses may override this routine to provide different behavior.
John McCall85737a72009-10-30 00:06:24 +0000345 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000346
John McCall85737a72009-10-30 00:06:24 +0000347 /// \brief Build a new reference type given the type it references.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000348 ///
John McCall85737a72009-10-30 00:06:24 +0000349 /// By default, performs semantic analysis when building the
350 /// reference type. Subclasses may override this routine to provide
351 /// different behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000352 ///
John McCall85737a72009-10-30 00:06:24 +0000353 /// \param LValue whether the type was written with an lvalue sigil
354 /// or an rvalue sigil.
355 QualType RebuildReferenceType(QualType ReferentType,
356 bool LValue,
357 SourceLocation Sigil);
Mike Stump1eb44332009-09-09 15:08:12 +0000358
Douglas Gregor577f75a2009-08-04 16:50:30 +0000359 /// \brief Build a new member pointer type given the pointee type and the
360 /// class type it refers into.
361 ///
362 /// By default, performs semantic analysis when building the member pointer
363 /// type. Subclasses may override this routine to provide different behavior.
John McCall85737a72009-10-30 00:06:24 +0000364 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
365 SourceLocation Sigil);
Mike Stump1eb44332009-09-09 15:08:12 +0000366
John McCalla2becad2009-10-21 00:40:46 +0000367 /// \brief Build a new Objective C object pointer type.
John McCall85737a72009-10-30 00:06:24 +0000368 QualType RebuildObjCObjectPointerType(QualType PointeeType,
369 SourceLocation Sigil);
John McCalla2becad2009-10-21 00:40:46 +0000370
Douglas Gregor577f75a2009-08-04 16:50:30 +0000371 /// \brief Build a new array type given the element type, size
372 /// modifier, size of the array (if known), size expression, and index type
373 /// qualifiers.
374 ///
375 /// By default, performs semantic analysis when building the array type.
376 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000377 /// Also by default, all of the other Rebuild*Array
Douglas Gregor577f75a2009-08-04 16:50:30 +0000378 QualType RebuildArrayType(QualType ElementType,
379 ArrayType::ArraySizeModifier SizeMod,
380 const llvm::APInt *Size,
381 Expr *SizeExpr,
382 unsigned IndexTypeQuals,
383 SourceRange BracketsRange);
Mike Stump1eb44332009-09-09 15:08:12 +0000384
Douglas Gregor577f75a2009-08-04 16:50:30 +0000385 /// \brief Build a new constant array type given the element type, size
386 /// modifier, (known) size of the array, and index type qualifiers.
387 ///
388 /// By default, performs semantic analysis when building the array type.
389 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000390 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000391 ArrayType::ArraySizeModifier SizeMod,
392 const llvm::APInt &Size,
John McCall85737a72009-10-30 00:06:24 +0000393 unsigned IndexTypeQuals,
394 SourceRange BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000395
Douglas Gregor577f75a2009-08-04 16:50:30 +0000396 /// \brief Build a new incomplete array type given the element type, size
397 /// modifier, and index type qualifiers.
398 ///
399 /// By default, performs semantic analysis when building the array type.
400 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000401 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000402 ArrayType::ArraySizeModifier SizeMod,
John McCall85737a72009-10-30 00:06:24 +0000403 unsigned IndexTypeQuals,
404 SourceRange BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000405
Mike Stump1eb44332009-09-09 15:08:12 +0000406 /// \brief Build a new variable-length array type given the element type,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000407 /// size modifier, size expression, and index type qualifiers.
408 ///
409 /// By default, performs semantic analysis when building the array type.
410 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000411 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000412 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000413 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000414 unsigned IndexTypeQuals,
415 SourceRange BracketsRange);
416
Mike Stump1eb44332009-09-09 15:08:12 +0000417 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000418 /// size modifier, size expression, and index type qualifiers.
419 ///
420 /// By default, performs semantic analysis when building the array type.
421 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000422 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000423 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000424 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000425 unsigned IndexTypeQuals,
426 SourceRange BracketsRange);
427
428 /// \brief Build a new vector type given the element type and
429 /// number of elements.
430 ///
431 /// By default, performs semantic analysis when building the vector type.
432 /// Subclasses may override this routine to provide different behavior.
433 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump1eb44332009-09-09 15:08:12 +0000434
Douglas Gregor577f75a2009-08-04 16:50:30 +0000435 /// \brief Build a new extended vector type given the element type and
436 /// number of elements.
437 ///
438 /// By default, performs semantic analysis when building the vector type.
439 /// Subclasses may override this routine to provide different behavior.
440 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
441 SourceLocation AttributeLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000442
443 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregor577f75a2009-08-04 16:50:30 +0000444 /// given the element type and number of elements.
445 ///
446 /// By default, performs semantic analysis when building the vector type.
447 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000448 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000449 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000450 SourceLocation AttributeLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000451
Douglas Gregor577f75a2009-08-04 16:50:30 +0000452 /// \brief Build a new function type.
453 ///
454 /// By default, performs semantic analysis when building the function type.
455 /// Subclasses may override this routine to provide different behavior.
456 QualType RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +0000457 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000458 unsigned NumParamTypes,
459 bool Variadic, unsigned Quals);
Mike Stump1eb44332009-09-09 15:08:12 +0000460
John McCalla2becad2009-10-21 00:40:46 +0000461 /// \brief Build a new unprototyped function type.
462 QualType RebuildFunctionNoProtoType(QualType ResultType);
463
Douglas Gregor577f75a2009-08-04 16:50:30 +0000464 /// \brief Build a new typedef type.
465 QualType RebuildTypedefType(TypedefDecl *Typedef) {
466 return SemaRef.Context.getTypeDeclType(Typedef);
467 }
468
469 /// \brief Build a new class/struct/union type.
470 QualType RebuildRecordType(RecordDecl *Record) {
471 return SemaRef.Context.getTypeDeclType(Record);
472 }
473
474 /// \brief Build a new Enum type.
475 QualType RebuildEnumType(EnumDecl *Enum) {
476 return SemaRef.Context.getTypeDeclType(Enum);
477 }
John McCall7da24312009-09-05 00:15:47 +0000478
479 /// \brief Build a new elaborated type.
480 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
481 return SemaRef.Context.getElaboratedType(T, Tag);
482 }
Mike Stump1eb44332009-09-09 15:08:12 +0000483
484 /// \brief Build a new typeof(expr) type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000485 ///
486 /// By default, performs semantic analysis when building the typeof type.
487 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000488 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000489
Mike Stump1eb44332009-09-09 15:08:12 +0000490 /// \brief Build a new typeof(type) type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000491 ///
492 /// By default, builds a new TypeOfType with the given underlying type.
493 QualType RebuildTypeOfType(QualType Underlying);
494
Mike Stump1eb44332009-09-09 15:08:12 +0000495 /// \brief Build a new C++0x decltype type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000496 ///
497 /// By default, performs semantic analysis when building the decltype type.
498 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000499 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump1eb44332009-09-09 15:08:12 +0000500
Douglas Gregor577f75a2009-08-04 16:50:30 +0000501 /// \brief Build a new template specialization type.
502 ///
503 /// By default, performs semantic analysis when building the template
504 /// specialization type. Subclasses may override this routine to provide
505 /// different behavior.
506 QualType RebuildTemplateSpecializationType(TemplateName Template,
John McCall833ca992009-10-29 08:12:44 +0000507 SourceLocation TemplateLoc,
John McCalld5532b62009-11-23 01:53:49 +0000508 const TemplateArgumentListInfo &Args);
Mike Stump1eb44332009-09-09 15:08:12 +0000509
Douglas Gregor577f75a2009-08-04 16:50:30 +0000510 /// \brief Build a new qualified name type.
511 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000512 /// By default, builds a new QualifiedNameType type from the
513 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregor577f75a2009-08-04 16:50:30 +0000514 /// this routine to provide different behavior.
515 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
516 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump1eb44332009-09-09 15:08:12 +0000517 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000518
519 /// \brief Build a new typename type that refers to a template-id.
520 ///
521 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump1eb44332009-09-09 15:08:12 +0000522 /// and the given type. Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000523 /// different behavior.
524 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
525 if (NNS->isDependent())
Mike Stump1eb44332009-09-09 15:08:12 +0000526 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000527 cast<TemplateSpecializationType>(T));
Mike Stump1eb44332009-09-09 15:08:12 +0000528
Douglas Gregor577f75a2009-08-04 16:50:30 +0000529 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump1eb44332009-09-09 15:08:12 +0000530 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000531
532 /// \brief Build a new typename type that refers to an identifier.
533 ///
534 /// By default, performs semantic analysis when building the typename type
Mike Stump1eb44332009-09-09 15:08:12 +0000535 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000536 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000537 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall833ca992009-10-29 08:12:44 +0000538 const IdentifierInfo *Id,
539 SourceRange SR) {
540 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000541 }
Mike Stump1eb44332009-09-09 15:08:12 +0000542
Douglas Gregordcee1a12009-08-06 05:28:30 +0000543 /// \brief Build a new nested-name-specifier given the prefix and an
544 /// identifier that names the next step in the nested-name-specifier.
545 ///
546 /// By default, performs semantic analysis when building the new
547 /// nested-name-specifier. Subclasses may override this routine to provide
548 /// different behavior.
549 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
550 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +0000551 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000552 QualType ObjectType,
553 NamedDecl *FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000554
555 /// \brief Build a new nested-name-specifier given the prefix and the
556 /// namespace named in the next step in the nested-name-specifier.
557 ///
558 /// By default, performs semantic analysis when building the new
559 /// nested-name-specifier. Subclasses may override this routine to provide
560 /// different behavior.
561 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
562 SourceRange Range,
563 NamespaceDecl *NS);
564
565 /// \brief Build a new nested-name-specifier given the prefix and the
566 /// type named in the next step in the nested-name-specifier.
567 ///
568 /// By default, performs semantic analysis when building the new
569 /// nested-name-specifier. Subclasses may override this routine to provide
570 /// different behavior.
571 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
572 SourceRange Range,
573 bool TemplateKW,
574 QualType T);
Douglas Gregord1067e52009-08-06 06:41:21 +0000575
576 /// \brief Build a new template name given a nested name specifier, a flag
577 /// indicating whether the "template" keyword was provided, and the template
578 /// that the template name refers to.
579 ///
580 /// By default, builds the new template name directly. Subclasses may override
581 /// this routine to provide different behavior.
582 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
583 bool TemplateKW,
584 TemplateDecl *Template);
585
Douglas Gregord1067e52009-08-06 06:41:21 +0000586 /// \brief Build a new template name given a nested name specifier and the
587 /// name that is referred to as a template.
588 ///
589 /// By default, performs semantic analysis to determine whether the name can
590 /// be resolved to a specific template, then builds the appropriate kind of
591 /// template name. Subclasses may override this routine to provide different
592 /// behavior.
593 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000594 const IdentifierInfo &II,
595 QualType ObjectType);
Mike Stump1eb44332009-09-09 15:08:12 +0000596
Douglas Gregorca1bdd72009-11-04 00:56:37 +0000597 /// \brief Build a new template name given a nested name specifier and the
598 /// overloaded operator 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,
605 OverloadedOperatorKind Operator,
606 QualType ObjectType);
607
Douglas Gregor43959a92009-08-20 07:17:43 +0000608 /// \brief Build a new compound statement.
609 ///
610 /// By default, performs semantic analysis to build the new statement.
611 /// Subclasses may override this routine to provide different behavior.
612 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
613 MultiStmtArg Statements,
614 SourceLocation RBraceLoc,
615 bool IsStmtExpr) {
616 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
617 IsStmtExpr);
618 }
619
620 /// \brief Build a new case statement.
621 ///
622 /// By default, performs semantic analysis to build the new statement.
623 /// Subclasses may override this routine to provide different behavior.
624 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
625 ExprArg LHS,
626 SourceLocation EllipsisLoc,
627 ExprArg RHS,
628 SourceLocation ColonLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000629 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregor43959a92009-08-20 07:17:43 +0000630 ColonLoc);
631 }
Mike Stump1eb44332009-09-09 15:08:12 +0000632
Douglas Gregor43959a92009-08-20 07:17:43 +0000633 /// \brief Attach the body to a new case statement.
634 ///
635 /// By default, performs semantic analysis to build the new statement.
636 /// Subclasses may override this routine to provide different behavior.
637 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
638 getSema().ActOnCaseStmtBody(S.get(), move(Body));
639 return move(S);
640 }
Mike Stump1eb44332009-09-09 15:08:12 +0000641
Douglas Gregor43959a92009-08-20 07:17:43 +0000642 /// \brief Build a new default statement.
643 ///
644 /// By default, performs semantic analysis to build the new statement.
645 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000646 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000647 SourceLocation ColonLoc,
648 StmtArg SubStmt) {
Mike Stump1eb44332009-09-09 15:08:12 +0000649 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregor43959a92009-08-20 07:17:43 +0000650 /*CurScope=*/0);
651 }
Mike Stump1eb44332009-09-09 15:08:12 +0000652
Douglas Gregor43959a92009-08-20 07:17:43 +0000653 /// \brief Build a new label statement.
654 ///
655 /// By default, performs semantic analysis to build the new statement.
656 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000657 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000658 IdentifierInfo *Id,
659 SourceLocation ColonLoc,
660 StmtArg SubStmt) {
661 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
662 }
Mike Stump1eb44332009-09-09 15:08:12 +0000663
Douglas Gregor43959a92009-08-20 07:17:43 +0000664 /// \brief Build a new "if" statement.
665 ///
666 /// By default, performs semantic analysis to build the new statement.
667 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000668 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000669 VarDecl *CondVar, StmtArg Then,
670 SourceLocation ElseLoc, StmtArg Else) {
671 return getSema().ActOnIfStmt(IfLoc, Cond, DeclPtrTy::make(CondVar),
672 move(Then), ElseLoc, move(Else));
Douglas Gregor43959a92009-08-20 07:17:43 +0000673 }
Mike Stump1eb44332009-09-09 15:08:12 +0000674
Douglas Gregor43959a92009-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.
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000679 OwningStmtResult RebuildSwitchStmtStart(Sema::FullExprArg Cond,
680 VarDecl *CondVar) {
681 return getSema().ActOnStartOfSwitchStmt(Cond, DeclPtrTy::make(CondVar));
Douglas Gregor43959a92009-08-20 07:17:43 +0000682 }
Mike Stump1eb44332009-09-09 15:08:12 +0000683
Douglas Gregor43959a92009-08-20 07:17:43 +0000684 /// \brief Attach the body to the switch statement.
685 ///
686 /// By default, performs semantic analysis to build the new statement.
687 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000688 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000689 StmtArg Switch, StmtArg Body) {
690 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
691 move(Body));
692 }
693
694 /// \brief Build a new while statement.
695 ///
696 /// By default, performs semantic analysis to build the new statement.
697 /// Subclasses may override this routine to provide different behavior.
698 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
699 Sema::FullExprArg Cond,
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000700 VarDecl *CondVar,
Douglas Gregor43959a92009-08-20 07:17:43 +0000701 StmtArg Body) {
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000702 return getSema().ActOnWhileStmt(WhileLoc, Cond, DeclPtrTy::make(CondVar),
703 move(Body));
Douglas Gregor43959a92009-08-20 07:17:43 +0000704 }
Mike Stump1eb44332009-09-09 15:08:12 +0000705
Douglas Gregor43959a92009-08-20 07:17:43 +0000706 /// \brief Build a new do-while statement.
707 ///
708 /// By default, performs semantic analysis to build the new statement.
709 /// Subclasses may override this routine to provide different behavior.
710 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
711 SourceLocation WhileLoc,
712 SourceLocation LParenLoc,
713 ExprArg Cond,
714 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000715 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000716 move(Cond), RParenLoc);
717 }
718
719 /// \brief Build a new for statement.
720 ///
721 /// By default, performs semantic analysis to build the new statement.
722 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000723 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000724 SourceLocation LParenLoc,
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000725 StmtArg Init, Sema::FullExprArg Cond,
726 VarDecl *CondVar, Sema::FullExprArg Inc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000727 SourceLocation RParenLoc, StmtArg Body) {
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000728 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), Cond,
729 DeclPtrTy::make(CondVar),
730 Inc, RParenLoc, move(Body));
Douglas Gregor43959a92009-08-20 07:17:43 +0000731 }
Mike Stump1eb44332009-09-09 15:08:12 +0000732
Douglas Gregor43959a92009-08-20 07:17:43 +0000733 /// \brief Build a new goto statement.
734 ///
735 /// By default, performs semantic analysis to build the new statement.
736 /// Subclasses may override this routine to provide different behavior.
737 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
738 SourceLocation LabelLoc,
739 LabelStmt *Label) {
740 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
741 }
742
743 /// \brief Build a new indirect goto statement.
744 ///
745 /// By default, performs semantic analysis to build the new statement.
746 /// Subclasses may override this routine to provide different behavior.
747 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
748 SourceLocation StarLoc,
749 ExprArg Target) {
750 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
751 }
Mike Stump1eb44332009-09-09 15:08:12 +0000752
Douglas Gregor43959a92009-08-20 07:17:43 +0000753 /// \brief Build a new return statement.
754 ///
755 /// By default, performs semantic analysis to build the new statement.
756 /// Subclasses may override this routine to provide different behavior.
757 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
758 ExprArg Result) {
Mike Stump1eb44332009-09-09 15:08:12 +0000759
Douglas Gregor43959a92009-08-20 07:17:43 +0000760 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
761 }
Mike Stump1eb44332009-09-09 15:08:12 +0000762
Douglas Gregor43959a92009-08-20 07:17:43 +0000763 /// \brief Build a new declaration statement.
764 ///
765 /// By default, performs semantic analysis to build the new statement.
766 /// Subclasses may override this routine to provide different behavior.
767 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump1eb44332009-09-09 15:08:12 +0000768 SourceLocation StartLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000769 SourceLocation EndLoc) {
770 return getSema().Owned(
771 new (getSema().Context) DeclStmt(
772 DeclGroupRef::Create(getSema().Context,
773 Decls, NumDecls),
774 StartLoc, EndLoc));
775 }
Mike Stump1eb44332009-09-09 15:08:12 +0000776
Douglas Gregor43959a92009-08-20 07:17:43 +0000777 /// \brief Build a new C++ exception declaration.
778 ///
779 /// By default, performs semantic analysis to build the new decaration.
780 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000781 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregor43959a92009-08-20 07:17:43 +0000782 DeclaratorInfo *Declarator,
783 IdentifierInfo *Name,
784 SourceLocation Loc,
785 SourceRange TypeRange) {
Mike Stump1eb44332009-09-09 15:08:12 +0000786 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000787 TypeRange);
788 }
789
790 /// \brief Build a new C++ catch statement.
791 ///
792 /// By default, performs semantic analysis to build the new statement.
793 /// Subclasses may override this routine to provide different behavior.
794 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
795 VarDecl *ExceptionDecl,
796 StmtArg Handler) {
797 return getSema().Owned(
Mike Stump1eb44332009-09-09 15:08:12 +0000798 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregor43959a92009-08-20 07:17:43 +0000799 Handler.takeAs<Stmt>()));
800 }
Mike Stump1eb44332009-09-09 15:08:12 +0000801
Douglas Gregor43959a92009-08-20 07:17:43 +0000802 /// \brief Build a new C++ try statement.
803 ///
804 /// By default, performs semantic analysis to build the new statement.
805 /// Subclasses may override this routine to provide different behavior.
806 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
807 StmtArg TryBlock,
808 MultiStmtArg Handlers) {
809 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
810 }
Mike Stump1eb44332009-09-09 15:08:12 +0000811
Douglas Gregorb98b1992009-08-11 05:31:07 +0000812 /// \brief Build a new expression that references a declaration.
813 ///
814 /// By default, performs semantic analysis to build the new expression.
815 /// Subclasses may override this routine to provide different behavior.
John McCallf7a1a742009-11-24 19:00:30 +0000816 OwningExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
817 LookupResult &R,
818 bool RequiresADL) {
819 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
820 }
821
822
823 /// \brief Build a new expression that references a declaration.
824 ///
825 /// By default, performs semantic analysis to build the new expression.
826 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora2813ce2009-10-23 18:54:35 +0000827 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
828 SourceRange QualifierRange,
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000829 NamedDecl *ND, SourceLocation Loc,
830 bool isAddressOfOperand) {
Douglas Gregora2813ce2009-10-23 18:54:35 +0000831 CXXScopeSpec SS;
832 SS.setScopeRep(Qualifier);
833 SS.setRange(QualifierRange);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000834 return getSema().BuildDeclarationNameExpr(Loc, ND,
835 /*FIXME:*/false,
Douglas Gregora2813ce2009-10-23 18:54:35 +0000836 &SS,
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000837 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000838 }
Mike Stump1eb44332009-09-09 15:08:12 +0000839
Douglas Gregorb98b1992009-08-11 05:31:07 +0000840 /// \brief Build a new expression in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +0000841 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000842 /// By default, performs semantic analysis to build the new expression.
843 /// Subclasses may override this routine to provide different behavior.
844 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
845 SourceLocation RParen) {
846 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
847 }
848
Douglas Gregora71d8192009-09-04 17:36:40 +0000849 /// \brief Build a new pseudo-destructor expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000850 ///
Douglas Gregora71d8192009-09-04 17:36:40 +0000851 /// By default, performs semantic analysis to build the new expression.
852 /// Subclasses may override this routine to provide different behavior.
853 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
854 SourceLocation OperatorLoc,
855 bool isArrow,
856 SourceLocation DestroyedTypeLoc,
857 QualType DestroyedType,
858 NestedNameSpecifier *Qualifier,
859 SourceRange QualifierRange) {
860 CXXScopeSpec SS;
861 if (Qualifier) {
862 SS.setRange(QualifierRange);
863 SS.setScopeRep(Qualifier);
864 }
865
Mike Stump1eb44332009-09-09 15:08:12 +0000866 DeclarationName Name
Douglas Gregora71d8192009-09-04 17:36:40 +0000867 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
868 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump1eb44332009-09-09 15:08:12 +0000869
870 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregora71d8192009-09-04 17:36:40 +0000871 OperatorLoc,
872 isArrow? tok::arrow : tok::period,
873 DestroyedTypeLoc,
874 Name,
875 Sema::DeclPtrTy::make((Decl *)0),
876 &SS);
Mike Stump1eb44332009-09-09 15:08:12 +0000877 }
878
Douglas Gregorb98b1992009-08-11 05:31:07 +0000879 /// \brief Build a new unary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000880 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000881 /// By default, performs semantic analysis to build the new expression.
882 /// Subclasses may override this routine to provide different behavior.
883 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
884 UnaryOperator::Opcode Opc,
885 ExprArg SubExpr) {
Douglas Gregor6ca7cfb2009-11-05 00:51:44 +0000886 return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
Douglas Gregorb98b1992009-08-11 05:31:07 +0000887 }
Mike Stump1eb44332009-09-09 15:08:12 +0000888
Douglas Gregorb98b1992009-08-11 05:31:07 +0000889 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000890 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000891 /// By default, performs semantic analysis to build the new expression.
892 /// Subclasses may override this routine to provide different behavior.
John McCall5ab75172009-11-04 07:28:41 +0000893 OwningExprResult RebuildSizeOfAlignOf(DeclaratorInfo *DInfo,
894 SourceLocation OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000895 bool isSizeOf, SourceRange R) {
John McCall5ab75172009-11-04 07:28:41 +0000896 return getSema().CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeOf, R);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000897 }
898
Mike Stump1eb44332009-09-09 15:08:12 +0000899 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregorb98b1992009-08-11 05:31:07 +0000900 /// argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000901 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000902 /// By default, performs semantic analysis to build the new expression.
903 /// Subclasses may override this routine to provide different behavior.
904 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
905 bool isSizeOf, SourceRange R) {
Mike Stump1eb44332009-09-09 15:08:12 +0000906 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +0000907 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
908 OpLoc, isSizeOf, R);
909 if (Result.isInvalid())
910 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +0000911
Douglas Gregorb98b1992009-08-11 05:31:07 +0000912 SubExpr.release();
913 return move(Result);
914 }
Mike Stump1eb44332009-09-09 15:08:12 +0000915
Douglas Gregorb98b1992009-08-11 05:31:07 +0000916 /// \brief Build a new array subscript expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000917 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000918 /// By default, performs semantic analysis to build the new expression.
919 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000920 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000921 SourceLocation LBracketLoc,
922 ExprArg RHS,
923 SourceLocation RBracketLoc) {
924 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump1eb44332009-09-09 15:08:12 +0000925 LBracketLoc, move(RHS),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000926 RBracketLoc);
927 }
928
929 /// \brief Build a new call expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000930 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000931 /// By default, performs semantic analysis to build the new expression.
932 /// Subclasses may override this routine to provide different behavior.
933 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
934 MultiExprArg Args,
935 SourceLocation *CommaLocs,
936 SourceLocation RParenLoc) {
937 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
938 move(Args), CommaLocs, RParenLoc);
939 }
940
941 /// \brief Build a new member access expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000942 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000943 /// By default, performs semantic analysis to build the new expression.
944 /// Subclasses may override this routine to provide different behavior.
945 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump1eb44332009-09-09 15:08:12 +0000946 bool isArrow,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000947 NestedNameSpecifier *Qualifier,
948 SourceRange QualifierRange,
949 SourceLocation MemberLoc,
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000950 NamedDecl *Member,
John McCalld5532b62009-11-23 01:53:49 +0000951 const TemplateArgumentListInfo *ExplicitTemplateArgs,
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000952 NamedDecl *FirstQualifierInScope) {
Anders Carlssond8b285f2009-09-01 04:26:58 +0000953 if (!Member->getDeclName()) {
954 // We have a reference to an unnamed field.
955 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump1eb44332009-09-09 15:08:12 +0000956
957 MemberExpr *ME =
Anders Carlssond8b285f2009-09-01 04:26:58 +0000958 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
959 Member, MemberLoc,
960 cast<FieldDecl>(Member)->getType());
961 return getSema().Owned(ME);
962 }
Mike Stump1eb44332009-09-09 15:08:12 +0000963
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000964 CXXScopeSpec SS;
965 if (Qualifier) {
966 SS.setRange(QualifierRange);
967 SS.setScopeRep(Qualifier);
968 }
969
Douglas Gregor017dde52009-08-31 20:00:26 +0000970 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000971 isArrow? tok::arrow : tok::period,
972 MemberLoc,
Douglas Gregor017dde52009-08-31 20:00:26 +0000973 Member->getDeclName(),
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000974 ExplicitTemplateArgs,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000975 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000976 &SS,
977 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000978 }
Mike Stump1eb44332009-09-09 15:08:12 +0000979
Douglas Gregorb98b1992009-08-11 05:31:07 +0000980 /// \brief Build a new binary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000981 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000982 /// By default, performs semantic analysis to build the new expression.
983 /// Subclasses may override this routine to provide different behavior.
984 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
985 BinaryOperator::Opcode Opc,
986 ExprArg LHS, ExprArg RHS) {
Douglas Gregor6ca7cfb2009-11-05 00:51:44 +0000987 return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc,
988 LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
Douglas Gregorb98b1992009-08-11 05:31:07 +0000989 }
990
991 /// \brief Build a new conditional operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000992 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000993 /// By default, performs semantic analysis to build the new expression.
994 /// Subclasses may override this routine to provide different behavior.
995 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
996 SourceLocation QuestionLoc,
997 ExprArg LHS,
998 SourceLocation ColonLoc,
999 ExprArg RHS) {
Mike Stump1eb44332009-09-09 15:08:12 +00001000 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001001 move(LHS), move(RHS));
1002 }
1003
1004 /// \brief Build a new implicit cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001005 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001006 /// By default, builds a new implicit cast without any semantic analysis.
1007 /// Subclasses may override this routine to provide different behavior.
1008 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
1009 ExprArg SubExpr, bool isLvalue) {
1010 ImplicitCastExpr *ICE
Mike Stump1eb44332009-09-09 15:08:12 +00001011 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001012 (Expr *)SubExpr.release(),
1013 isLvalue);
1014 return getSema().Owned(ICE);
1015 }
1016
1017 /// \brief Build a new C-style cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001018 ///
Douglas Gregorb98b1992009-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 RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1022 QualType ExplicitTy,
1023 SourceLocation RParenLoc,
1024 ExprArg SubExpr) {
1025 return getSema().ActOnCastExpr(/*Scope=*/0,
1026 LParenLoc,
1027 ExplicitTy.getAsOpaquePtr(),
1028 RParenLoc,
1029 move(SubExpr));
1030 }
Mike Stump1eb44332009-09-09 15:08:12 +00001031
Douglas Gregorb98b1992009-08-11 05:31:07 +00001032 /// \brief Build a new compound literal expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001033 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001034 /// By default, performs semantic analysis to build the new expression.
1035 /// Subclasses may override this routine to provide different behavior.
1036 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1037 QualType T,
1038 SourceLocation RParenLoc,
1039 ExprArg Init) {
1040 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1041 RParenLoc, move(Init));
1042 }
Mike Stump1eb44332009-09-09 15:08:12 +00001043
Douglas Gregorb98b1992009-08-11 05:31:07 +00001044 /// \brief Build a new extended vector element access expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001045 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001046 /// By default, performs semantic analysis to build the new expression.
1047 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001048 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001049 SourceLocation OpLoc,
1050 SourceLocation AccessorLoc,
1051 IdentifierInfo &Accessor) {
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001052 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001053 tok::period, AccessorLoc,
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001054 DeclarationName(&Accessor),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001055 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1056 }
Mike Stump1eb44332009-09-09 15:08:12 +00001057
Douglas Gregorb98b1992009-08-11 05:31:07 +00001058 /// \brief Build a new initializer list expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001059 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001060 /// By default, performs semantic analysis to build the new expression.
1061 /// Subclasses may override this routine to provide different behavior.
1062 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1063 MultiExprArg Inits,
Douglas Gregore48319a2009-11-09 17:16:50 +00001064 SourceLocation RBraceLoc,
1065 QualType ResultTy) {
1066 OwningExprResult Result
1067 = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1068 if (Result.isInvalid() || ResultTy->isDependentType())
1069 return move(Result);
1070
1071 // Patch in the result type we were given, which may have been computed
1072 // when the initial InitListExpr was built.
1073 InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get());
1074 ILE->setType(ResultTy);
1075 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001076 }
Mike Stump1eb44332009-09-09 15:08:12 +00001077
Douglas Gregorb98b1992009-08-11 05:31:07 +00001078 /// \brief Build a new designated initializer expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001079 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001080 /// By default, performs semantic analysis to build the new expression.
1081 /// Subclasses may override this routine to provide different behavior.
1082 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1083 MultiExprArg ArrayExprs,
1084 SourceLocation EqualOrColonLoc,
1085 bool GNUSyntax,
1086 ExprArg Init) {
1087 OwningExprResult Result
1088 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1089 move(Init));
1090 if (Result.isInvalid())
1091 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001092
Douglas Gregorb98b1992009-08-11 05:31:07 +00001093 ArrayExprs.release();
1094 return move(Result);
1095 }
Mike Stump1eb44332009-09-09 15:08:12 +00001096
Douglas Gregorb98b1992009-08-11 05:31:07 +00001097 /// \brief Build a new value-initialized expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001098 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001099 /// By default, builds the implicit value initialization without performing
1100 /// any semantic analysis. Subclasses may override this routine to provide
1101 /// different behavior.
1102 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1103 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1104 }
Mike Stump1eb44332009-09-09 15:08:12 +00001105
Douglas Gregorb98b1992009-08-11 05:31:07 +00001106 /// \brief Build a new \c va_arg expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001107 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001108 /// By default, performs semantic analysis to build the new expression.
1109 /// Subclasses may override this routine to provide different behavior.
1110 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1111 QualType T, SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001112 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001113 RParenLoc);
1114 }
1115
1116 /// \brief Build a new expression list in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +00001117 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001118 /// By default, performs semantic analysis to build the new expression.
1119 /// Subclasses may override this routine to provide different behavior.
1120 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1121 MultiExprArg SubExprs,
1122 SourceLocation RParenLoc) {
Fariborz Jahanianf88f7ab2009-11-25 01:26:41 +00001123 return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc,
1124 move(SubExprs));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001125 }
Mike Stump1eb44332009-09-09 15:08:12 +00001126
Douglas Gregorb98b1992009-08-11 05:31:07 +00001127 /// \brief Build a new address-of-label expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001128 ///
1129 /// By default, performs semantic analysis, using the name of the label
Douglas Gregorb98b1992009-08-11 05:31:07 +00001130 /// rather than attempting to map the label statement itself.
1131 /// Subclasses may override this routine to provide different behavior.
1132 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1133 SourceLocation LabelLoc,
1134 LabelStmt *Label) {
1135 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1136 }
Mike Stump1eb44332009-09-09 15:08:12 +00001137
Douglas Gregorb98b1992009-08-11 05:31:07 +00001138 /// \brief Build a new GNU statement expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001139 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001140 /// By default, performs semantic analysis to build the new expression.
1141 /// Subclasses may override this routine to provide different behavior.
1142 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1143 StmtArg SubStmt,
1144 SourceLocation RParenLoc) {
1145 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1146 }
Mike Stump1eb44332009-09-09 15:08:12 +00001147
Douglas Gregorb98b1992009-08-11 05:31:07 +00001148 /// \brief Build a new __builtin_types_compatible_p expression.
1149 ///
1150 /// By default, performs semantic analysis to build the new expression.
1151 /// Subclasses may override this routine to provide different behavior.
1152 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1153 QualType T1, QualType T2,
1154 SourceLocation RParenLoc) {
1155 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1156 T1.getAsOpaquePtr(),
1157 T2.getAsOpaquePtr(),
1158 RParenLoc);
1159 }
Mike Stump1eb44332009-09-09 15:08:12 +00001160
Douglas Gregorb98b1992009-08-11 05:31:07 +00001161 /// \brief Build a new __builtin_choose_expr expression.
1162 ///
1163 /// By default, performs semantic analysis to build the new expression.
1164 /// Subclasses may override this routine to provide different behavior.
1165 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1166 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1167 SourceLocation RParenLoc) {
1168 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1169 move(Cond), move(LHS), move(RHS),
1170 RParenLoc);
1171 }
Mike Stump1eb44332009-09-09 15:08:12 +00001172
Douglas Gregorb98b1992009-08-11 05:31:07 +00001173 /// \brief Build a new overloaded operator call expression.
1174 ///
1175 /// By default, performs semantic analysis to build the new expression.
1176 /// The semantic analysis provides the behavior of template instantiation,
1177 /// copying with transformations that turn what looks like an overloaded
Mike Stump1eb44332009-09-09 15:08:12 +00001178 /// operator call into a use of a builtin operator, performing
Douglas Gregorb98b1992009-08-11 05:31:07 +00001179 /// argument-dependent lookup, etc. Subclasses may override this routine to
1180 /// provide different behavior.
1181 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1182 SourceLocation OpLoc,
1183 ExprArg Callee,
1184 ExprArg First,
1185 ExprArg Second);
Mike Stump1eb44332009-09-09 15:08:12 +00001186
1187 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregorb98b1992009-08-11 05:31:07 +00001188 /// reinterpret_cast.
1189 ///
1190 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump1eb44332009-09-09 15:08:12 +00001191 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregorb98b1992009-08-11 05:31:07 +00001192 /// Subclasses may override this routine to provide different behavior.
1193 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1194 Stmt::StmtClass Class,
1195 SourceLocation LAngleLoc,
1196 QualType T,
1197 SourceLocation RAngleLoc,
1198 SourceLocation LParenLoc,
1199 ExprArg SubExpr,
1200 SourceLocation RParenLoc) {
1201 switch (Class) {
1202 case Stmt::CXXStaticCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001203 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1204 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001205 move(SubExpr), RParenLoc);
1206
1207 case Stmt::CXXDynamicCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001208 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1209 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001210 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001211
Douglas Gregorb98b1992009-08-11 05:31:07 +00001212 case Stmt::CXXReinterpretCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001213 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1214 RAngleLoc, LParenLoc,
1215 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001216 RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001217
Douglas Gregorb98b1992009-08-11 05:31:07 +00001218 case Stmt::CXXConstCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001219 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1220 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001221 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001222
Douglas Gregorb98b1992009-08-11 05:31:07 +00001223 default:
1224 assert(false && "Invalid C++ named cast");
1225 break;
1226 }
Mike Stump1eb44332009-09-09 15:08:12 +00001227
Douglas Gregorb98b1992009-08-11 05:31:07 +00001228 return getSema().ExprError();
1229 }
Mike Stump1eb44332009-09-09 15:08:12 +00001230
Douglas Gregorb98b1992009-08-11 05:31:07 +00001231 /// \brief Build a new C++ static_cast expression.
1232 ///
1233 /// By default, performs semantic analysis to build the new expression.
1234 /// Subclasses may override this routine to provide different behavior.
1235 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1236 SourceLocation LAngleLoc,
1237 QualType T,
1238 SourceLocation RAngleLoc,
1239 SourceLocation LParenLoc,
1240 ExprArg SubExpr,
1241 SourceLocation RParenLoc) {
1242 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001243 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001244 LParenLoc, move(SubExpr), RParenLoc);
1245 }
1246
1247 /// \brief Build a new C++ dynamic_cast expression.
1248 ///
1249 /// By default, performs semantic analysis to build the new expression.
1250 /// Subclasses may override this routine to provide different behavior.
1251 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1252 SourceLocation LAngleLoc,
1253 QualType T,
1254 SourceLocation RAngleLoc,
1255 SourceLocation LParenLoc,
1256 ExprArg SubExpr,
1257 SourceLocation RParenLoc) {
1258 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001259 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001260 LParenLoc, move(SubExpr), RParenLoc);
1261 }
1262
1263 /// \brief Build a new C++ reinterpret_cast expression.
1264 ///
1265 /// By default, performs semantic analysis to build the new expression.
1266 /// Subclasses may override this routine to provide different behavior.
1267 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1268 SourceLocation LAngleLoc,
1269 QualType T,
1270 SourceLocation RAngleLoc,
1271 SourceLocation LParenLoc,
1272 ExprArg SubExpr,
1273 SourceLocation RParenLoc) {
1274 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1275 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1276 LParenLoc, move(SubExpr), RParenLoc);
1277 }
1278
1279 /// \brief Build a new C++ const_cast expression.
1280 ///
1281 /// By default, performs semantic analysis to build the new expression.
1282 /// Subclasses may override this routine to provide different behavior.
1283 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1284 SourceLocation LAngleLoc,
1285 QualType T,
1286 SourceLocation RAngleLoc,
1287 SourceLocation LParenLoc,
1288 ExprArg SubExpr,
1289 SourceLocation RParenLoc) {
1290 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001291 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001292 LParenLoc, move(SubExpr), RParenLoc);
1293 }
Mike Stump1eb44332009-09-09 15:08:12 +00001294
Douglas Gregorb98b1992009-08-11 05:31:07 +00001295 /// \brief Build a new C++ functional-style cast expression.
1296 ///
1297 /// By default, performs semantic analysis to build the new expression.
1298 /// Subclasses may override this routine to provide different behavior.
1299 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1300 QualType T,
1301 SourceLocation LParenLoc,
1302 ExprArg SubExpr,
1303 SourceLocation RParenLoc) {
Chris Lattner88650c32009-08-24 05:19:01 +00001304 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregorb98b1992009-08-11 05:31:07 +00001305 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1306 T.getAsOpaquePtr(),
1307 LParenLoc,
Chris Lattner88650c32009-08-24 05:19:01 +00001308 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump1eb44332009-09-09 15:08:12 +00001309 /*CommaLocs=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001310 RParenLoc);
1311 }
Mike Stump1eb44332009-09-09 15:08:12 +00001312
Douglas Gregorb98b1992009-08-11 05:31:07 +00001313 /// \brief Build a new C++ typeid(type) expression.
1314 ///
1315 /// By default, performs semantic analysis to build the new expression.
1316 /// Subclasses may override this routine to provide different behavior.
1317 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1318 SourceLocation LParenLoc,
1319 QualType T,
1320 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001321 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001322 T.getAsOpaquePtr(), RParenLoc);
1323 }
Mike Stump1eb44332009-09-09 15:08:12 +00001324
Douglas Gregorb98b1992009-08-11 05:31:07 +00001325 /// \brief Build a new C++ typeid(expr) expression.
1326 ///
1327 /// By default, performs semantic analysis to build the new expression.
1328 /// Subclasses may override this routine to provide different behavior.
1329 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1330 SourceLocation LParenLoc,
1331 ExprArg Operand,
1332 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001333 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00001334 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1335 RParenLoc);
1336 if (Result.isInvalid())
1337 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001338
Douglas Gregorb98b1992009-08-11 05:31:07 +00001339 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1340 return move(Result);
Mike Stump1eb44332009-09-09 15:08:12 +00001341 }
1342
Douglas Gregorb98b1992009-08-11 05:31:07 +00001343 /// \brief Build a new C++ "this" expression.
1344 ///
1345 /// By default, builds a new "this" expression without performing any
Mike Stump1eb44332009-09-09 15:08:12 +00001346 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregorb98b1992009-08-11 05:31:07 +00001347 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001348 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001349 QualType ThisType) {
1350 return getSema().Owned(
1351 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1352 }
1353
1354 /// \brief Build a new C++ throw expression.
1355 ///
1356 /// By default, performs semantic analysis to build the new expression.
1357 /// Subclasses may override this routine to provide different behavior.
1358 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1359 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1360 }
1361
1362 /// \brief Build a new C++ default-argument expression.
1363 ///
1364 /// By default, builds a new default-argument expression, which does not
1365 /// require any semantic analysis. Subclasses may override this routine to
1366 /// provide different behavior.
1367 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssonf1480ee2009-08-14 18:30:22 +00001368 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001369 }
1370
1371 /// \brief Build a new C++ zero-initialization expression.
1372 ///
1373 /// By default, performs semantic analysis to build the new expression.
1374 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001375 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001376 SourceLocation LParenLoc,
1377 QualType T,
1378 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001379 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1380 T.getAsOpaquePtr(), LParenLoc,
1381 MultiExprArg(getSema(), 0, 0),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001382 0, RParenLoc);
1383 }
Mike Stump1eb44332009-09-09 15:08:12 +00001384
Douglas Gregorb98b1992009-08-11 05:31:07 +00001385 /// \brief Build a new C++ "new" expression.
1386 ///
1387 /// By default, performs semantic analysis to build the new expression.
1388 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001389 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001390 bool UseGlobal,
1391 SourceLocation PlacementLParen,
1392 MultiExprArg PlacementArgs,
1393 SourceLocation PlacementRParen,
Mike Stump1eb44332009-09-09 15:08:12 +00001394 bool ParenTypeId,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001395 QualType AllocType,
1396 SourceLocation TypeLoc,
1397 SourceRange TypeRange,
1398 ExprArg ArraySize,
1399 SourceLocation ConstructorLParen,
1400 MultiExprArg ConstructorArgs,
1401 SourceLocation ConstructorRParen) {
Mike Stump1eb44332009-09-09 15:08:12 +00001402 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001403 PlacementLParen,
1404 move(PlacementArgs),
1405 PlacementRParen,
1406 ParenTypeId,
1407 AllocType,
1408 TypeLoc,
1409 TypeRange,
1410 move(ArraySize),
1411 ConstructorLParen,
1412 move(ConstructorArgs),
1413 ConstructorRParen);
1414 }
Mike Stump1eb44332009-09-09 15:08:12 +00001415
Douglas Gregorb98b1992009-08-11 05:31:07 +00001416 /// \brief Build a new C++ "delete" expression.
1417 ///
1418 /// By default, performs semantic analysis to build the new expression.
1419 /// Subclasses may override this routine to provide different behavior.
1420 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1421 bool IsGlobalDelete,
1422 bool IsArrayForm,
1423 ExprArg Operand) {
1424 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1425 move(Operand));
1426 }
Mike Stump1eb44332009-09-09 15:08:12 +00001427
Douglas Gregorb98b1992009-08-11 05:31:07 +00001428 /// \brief Build a new unary type trait 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 RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1433 SourceLocation StartLoc,
1434 SourceLocation LParenLoc,
1435 QualType T,
1436 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001437 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001438 T.getAsOpaquePtr(), RParenLoc);
1439 }
1440
Mike Stump1eb44332009-09-09 15:08:12 +00001441 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregorb98b1992009-08-11 05:31:07 +00001442 /// expression.
1443 ///
1444 /// By default, performs semantic analysis to build the new expression.
1445 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001446 OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001447 SourceRange QualifierRange,
1448 DeclarationName Name,
1449 SourceLocation Location,
John McCallf7a1a742009-11-24 19:00:30 +00001450 const TemplateArgumentListInfo *TemplateArgs) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00001451 CXXScopeSpec SS;
1452 SS.setRange(QualifierRange);
1453 SS.setScopeRep(NNS);
John McCallf7a1a742009-11-24 19:00:30 +00001454
1455 if (TemplateArgs)
1456 return getSema().BuildQualifiedTemplateIdExpr(SS, Name, Location,
1457 *TemplateArgs);
1458
1459 return getSema().BuildQualifiedDeclarationNameExpr(SS, Name, Location);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001460 }
1461
1462 /// \brief Build a new template-id expression.
1463 ///
1464 /// By default, performs semantic analysis to build the new expression.
1465 /// Subclasses may override this routine to provide different behavior.
John McCallf7a1a742009-11-24 19:00:30 +00001466 OwningExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
1467 LookupResult &R,
1468 bool RequiresADL,
John McCalld5532b62009-11-23 01:53:49 +00001469 const TemplateArgumentListInfo &TemplateArgs) {
John McCallf7a1a742009-11-24 19:00:30 +00001470 return getSema().BuildTemplateIdExpr(SS, R, RequiresADL, TemplateArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001471 }
1472
1473 /// \brief Build a new object-construction expression.
1474 ///
1475 /// By default, performs semantic analysis to build the new expression.
1476 /// Subclasses may override this routine to provide different behavior.
1477 OwningExprResult RebuildCXXConstructExpr(QualType T,
1478 CXXConstructorDecl *Constructor,
1479 bool IsElidable,
1480 MultiExprArg Args) {
Anders Carlssonec8e5ea2009-09-05 07:40:38 +00001481 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1482 SourceLocation(),
1483 T, Constructor, IsElidable,
Anders Carlssonf47511a2009-09-07 22:23:31 +00001484 move(Args));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001485 }
1486
1487 /// \brief Build a new object-construction expression.
1488 ///
1489 /// By default, performs semantic analysis to build the new expression.
1490 /// Subclasses may override this routine to provide different behavior.
1491 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1492 QualType T,
1493 SourceLocation LParenLoc,
1494 MultiExprArg Args,
1495 SourceLocation *Commas,
1496 SourceLocation RParenLoc) {
1497 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1498 T.getAsOpaquePtr(),
1499 LParenLoc,
1500 move(Args),
1501 Commas,
1502 RParenLoc);
1503 }
1504
1505 /// \brief Build a new object-construction expression.
1506 ///
1507 /// By default, performs semantic analysis to build the new expression.
1508 /// Subclasses may override this routine to provide different behavior.
1509 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1510 QualType T,
1511 SourceLocation LParenLoc,
1512 MultiExprArg Args,
1513 SourceLocation *Commas,
1514 SourceLocation RParenLoc) {
1515 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1516 /*FIXME*/LParenLoc),
1517 T.getAsOpaquePtr(),
1518 LParenLoc,
1519 move(Args),
1520 Commas,
1521 RParenLoc);
1522 }
Mike Stump1eb44332009-09-09 15:08:12 +00001523
Douglas Gregorb98b1992009-08-11 05:31:07 +00001524 /// \brief Build a new member reference expression.
1525 ///
1526 /// By default, performs semantic analysis to build the new expression.
1527 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001528 OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001529 bool IsArrow,
1530 SourceLocation OperatorLoc,
Douglas Gregora38c6872009-09-03 16:14:30 +00001531 NestedNameSpecifier *Qualifier,
1532 SourceRange QualifierRange,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001533 DeclarationName Name,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001534 SourceLocation MemberLoc,
1535 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001536 OwningExprResult Base = move(BaseE);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001537 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregora38c6872009-09-03 16:14:30 +00001538
Douglas Gregorb98b1992009-08-11 05:31:07 +00001539 CXXScopeSpec SS;
Douglas Gregora38c6872009-09-03 16:14:30 +00001540 SS.setRange(QualifierRange);
1541 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001542
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001543 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001544 move(Base), OperatorLoc, OpKind,
Douglas Gregor017dde52009-08-31 20:00:26 +00001545 MemberLoc,
1546 Name,
Douglas Gregora38c6872009-09-03 16:14:30 +00001547 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001548 &SS,
1549 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001550 }
1551
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001552 /// \brief Build a new member reference expression with explicit template
1553 /// arguments.
1554 ///
1555 /// By default, performs semantic analysis to build the new expression.
1556 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001557 OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001558 bool IsArrow,
1559 SourceLocation OperatorLoc,
1560 NestedNameSpecifier *Qualifier,
1561 SourceRange QualifierRange,
1562 TemplateName Template,
1563 SourceLocation TemplateNameLoc,
1564 NamedDecl *FirstQualifierInScope,
John McCalld5532b62009-11-23 01:53:49 +00001565 const TemplateArgumentListInfo &TemplateArgs) {
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001566 OwningExprResult Base = move(BaseE);
1567 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump1eb44332009-09-09 15:08:12 +00001568
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001569 CXXScopeSpec SS;
1570 SS.setRange(QualifierRange);
1571 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001572
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001573 // FIXME: We're going to end up looking up the template based on its name,
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001574 // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001575 DeclarationName Name;
1576 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1577 Name = ActualTemplate->getDeclName();
Mike Stump1eb44332009-09-09 15:08:12 +00001578 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001579 = Template.getAsOverloadedFunctionDecl())
1580 Name = Ovl->getDeclName();
Douglas Gregorca1bdd72009-11-04 00:56:37 +00001581 else {
1582 DependentTemplateName *DTN = Template.getAsDependentTemplateName();
1583 if (DTN->isIdentifier())
1584 Name = DTN->getIdentifier();
1585 else
1586 Name = SemaRef.Context.DeclarationNames.getCXXOperatorName(
1587 DTN->getOperator());
1588 }
John McCalld5532b62009-11-23 01:53:49 +00001589 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
1590 OperatorLoc, OpKind,
1591 TemplateNameLoc, Name,
1592 &TemplateArgs,
1593 Sema::DeclPtrTy(), &SS);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001594 }
Mike Stump1eb44332009-09-09 15:08:12 +00001595
Douglas Gregorb98b1992009-08-11 05:31:07 +00001596 /// \brief Build a new Objective-C @encode expression.
1597 ///
1598 /// By default, performs semantic analysis to build the new expression.
1599 /// Subclasses may override this routine to provide different behavior.
1600 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1601 QualType T,
1602 SourceLocation RParenLoc) {
1603 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1604 RParenLoc));
Mike Stump1eb44332009-09-09 15:08:12 +00001605 }
Douglas Gregorb98b1992009-08-11 05:31:07 +00001606
1607 /// \brief Build a new Objective-C protocol expression.
1608 ///
1609 /// By default, performs semantic analysis to build the new expression.
1610 /// Subclasses may override this routine to provide different behavior.
1611 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1612 SourceLocation AtLoc,
1613 SourceLocation ProtoLoc,
1614 SourceLocation LParenLoc,
1615 SourceLocation RParenLoc) {
1616 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1617 Protocol->getIdentifier(),
1618 AtLoc,
1619 ProtoLoc,
1620 LParenLoc,
Mike Stump1eb44332009-09-09 15:08:12 +00001621 RParenLoc));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001622 }
Mike Stump1eb44332009-09-09 15:08:12 +00001623
Douglas Gregorb98b1992009-08-11 05:31:07 +00001624 /// \brief Build a new shuffle vector expression.
1625 ///
1626 /// By default, performs semantic analysis to build the new expression.
1627 /// Subclasses may override this routine to provide different behavior.
1628 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1629 MultiExprArg SubExprs,
1630 SourceLocation RParenLoc) {
1631 // Find the declaration for __builtin_shufflevector
Mike Stump1eb44332009-09-09 15:08:12 +00001632 const IdentifierInfo &Name
Douglas Gregorb98b1992009-08-11 05:31:07 +00001633 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1634 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1635 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1636 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump1eb44332009-09-09 15:08:12 +00001637
Douglas Gregorb98b1992009-08-11 05:31:07 +00001638 // Build a reference to the __builtin_shufflevector builtin
1639 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump1eb44332009-09-09 15:08:12 +00001640 Expr *Callee
Douglas Gregorb98b1992009-08-11 05:31:07 +00001641 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
Douglas Gregor0da76df2009-11-23 11:41:28 +00001642 BuiltinLoc);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001643 SemaRef.UsualUnaryConversions(Callee);
Mike Stump1eb44332009-09-09 15:08:12 +00001644
1645 // Build the CallExpr
Douglas Gregorb98b1992009-08-11 05:31:07 +00001646 unsigned NumSubExprs = SubExprs.size();
1647 Expr **Subs = (Expr **)SubExprs.release();
1648 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1649 Subs, NumSubExprs,
1650 Builtin->getResultType(),
1651 RParenLoc);
1652 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump1eb44332009-09-09 15:08:12 +00001653
Douglas Gregorb98b1992009-08-11 05:31:07 +00001654 // Type-check the __builtin_shufflevector expression.
1655 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1656 if (Result.isInvalid())
1657 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001658
Douglas Gregorb98b1992009-08-11 05:31:07 +00001659 OwnedCall.release();
Mike Stump1eb44332009-09-09 15:08:12 +00001660 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001661 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00001662};
Douglas Gregorb98b1992009-08-11 05:31:07 +00001663
Douglas Gregor43959a92009-08-20 07:17:43 +00001664template<typename Derived>
1665Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1666 if (!S)
1667 return SemaRef.Owned(S);
Mike Stump1eb44332009-09-09 15:08:12 +00001668
Douglas Gregor43959a92009-08-20 07:17:43 +00001669 switch (S->getStmtClass()) {
1670 case Stmt::NoStmtClass: break;
Mike Stump1eb44332009-09-09 15:08:12 +00001671
Douglas Gregor43959a92009-08-20 07:17:43 +00001672 // Transform individual statement nodes
1673#define STMT(Node, Parent) \
1674 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1675#define EXPR(Node, Parent)
1676#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001677
Douglas Gregor43959a92009-08-20 07:17:43 +00001678 // Transform expressions by calling TransformExpr.
1679#define STMT(Node, Parent)
1680#define EXPR(Node, Parent) case Stmt::Node##Class:
1681#include "clang/AST/StmtNodes.def"
1682 {
1683 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1684 if (E.isInvalid())
1685 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00001686
Douglas Gregorafe7ec22009-11-13 18:34:26 +00001687 return getSema().ActOnExprStmt(getSema().FullExpr(E));
Douglas Gregor43959a92009-08-20 07:17:43 +00001688 }
Mike Stump1eb44332009-09-09 15:08:12 +00001689 }
1690
Douglas Gregor43959a92009-08-20 07:17:43 +00001691 return SemaRef.Owned(S->Retain());
1692}
Mike Stump1eb44332009-09-09 15:08:12 +00001693
1694
Douglas Gregor670444e2009-08-04 22:27:00 +00001695template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00001696Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1697 bool isAddressOfOperand) {
1698 if (!E)
1699 return SemaRef.Owned(E);
1700
1701 switch (E->getStmtClass()) {
1702 case Stmt::NoStmtClass: break;
1703#define STMT(Node, Parent) case Stmt::Node##Class: break;
1704#define EXPR(Node, Parent) \
Douglas Gregorc86a6e92009-11-04 07:01:15 +00001705 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E), \
1706 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001707#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001708 }
1709
Douglas Gregorb98b1992009-08-11 05:31:07 +00001710 return SemaRef.Owned(E->Retain());
Douglas Gregor657c1ac2009-08-06 22:17:10 +00001711}
1712
1713template<typename Derived>
Douglas Gregordcee1a12009-08-06 05:28:30 +00001714NestedNameSpecifier *
1715TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +00001716 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001717 QualType ObjectType,
1718 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0979c802009-08-31 21:41:48 +00001719 if (!NNS)
1720 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001721
Douglas Gregor43959a92009-08-20 07:17:43 +00001722 // Transform the prefix of this nested name specifier.
Douglas Gregordcee1a12009-08-06 05:28:30 +00001723 NestedNameSpecifier *Prefix = NNS->getPrefix();
1724 if (Prefix) {
Mike Stump1eb44332009-09-09 15:08:12 +00001725 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001726 ObjectType,
1727 FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +00001728 if (!Prefix)
1729 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001730
1731 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregorc68afe22009-09-03 21:38:09 +00001732 // apply to the first element in the nested-name-specifier.
Douglas Gregora38c6872009-09-03 16:14:30 +00001733 ObjectType = QualType();
Douglas Gregorc68afe22009-09-03 21:38:09 +00001734 FirstQualifierInScope = 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001735 }
Mike Stump1eb44332009-09-09 15:08:12 +00001736
Douglas Gregordcee1a12009-08-06 05:28:30 +00001737 switch (NNS->getKind()) {
1738 case NestedNameSpecifier::Identifier:
Mike Stump1eb44332009-09-09 15:08:12 +00001739 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregora38c6872009-09-03 16:14:30 +00001740 "Identifier nested-name-specifier with no prefix or object type");
1741 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1742 ObjectType.isNull())
Douglas Gregordcee1a12009-08-06 05:28:30 +00001743 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001744
1745 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00001746 *NNS->getAsIdentifier(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001747 ObjectType,
1748 FirstQualifierInScope);
Mike Stump1eb44332009-09-09 15:08:12 +00001749
Douglas Gregordcee1a12009-08-06 05:28:30 +00001750 case NestedNameSpecifier::Namespace: {
Mike Stump1eb44332009-09-09 15:08:12 +00001751 NamespaceDecl *NS
Douglas Gregordcee1a12009-08-06 05:28:30 +00001752 = cast_or_null<NamespaceDecl>(
1753 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump1eb44332009-09-09 15:08:12 +00001754 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordcee1a12009-08-06 05:28:30 +00001755 Prefix == NNS->getPrefix() &&
1756 NS == NNS->getAsNamespace())
1757 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001758
Douglas Gregordcee1a12009-08-06 05:28:30 +00001759 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1760 }
Mike Stump1eb44332009-09-09 15:08:12 +00001761
Douglas Gregordcee1a12009-08-06 05:28:30 +00001762 case NestedNameSpecifier::Global:
1763 // There is no meaningful transformation that one could perform on the
1764 // global scope.
1765 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001766
Douglas Gregordcee1a12009-08-06 05:28:30 +00001767 case NestedNameSpecifier::TypeSpecWithTemplate:
1768 case NestedNameSpecifier::TypeSpec: {
Douglas Gregorfbf2c942009-10-29 22:21:39 +00001769 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregordcee1a12009-08-06 05:28:30 +00001770 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregord1067e52009-08-06 06:41:21 +00001771 if (T.isNull())
1772 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001773
Douglas Gregordcee1a12009-08-06 05:28:30 +00001774 if (!getDerived().AlwaysRebuild() &&
1775 Prefix == NNS->getPrefix() &&
1776 T == QualType(NNS->getAsType(), 0))
1777 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001778
1779 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1780 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregordcee1a12009-08-06 05:28:30 +00001781 T);
1782 }
1783 }
Mike Stump1eb44332009-09-09 15:08:12 +00001784
Douglas Gregordcee1a12009-08-06 05:28:30 +00001785 // Required to silence a GCC warning
Mike Stump1eb44332009-09-09 15:08:12 +00001786 return 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001787}
1788
1789template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001790DeclarationName
Douglas Gregor81499bb2009-09-03 22:13:48 +00001791TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregordd62b152009-10-19 22:04:39 +00001792 SourceLocation Loc,
1793 QualType ObjectType) {
Douglas Gregor81499bb2009-09-03 22:13:48 +00001794 if (!Name)
1795 return Name;
1796
1797 switch (Name.getNameKind()) {
1798 case DeclarationName::Identifier:
1799 case DeclarationName::ObjCZeroArgSelector:
1800 case DeclarationName::ObjCOneArgSelector:
1801 case DeclarationName::ObjCMultiArgSelector:
1802 case DeclarationName::CXXOperatorName:
1803 case DeclarationName::CXXUsingDirective:
1804 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001805
Douglas Gregor81499bb2009-09-03 22:13:48 +00001806 case DeclarationName::CXXConstructorName:
1807 case DeclarationName::CXXDestructorName:
1808 case DeclarationName::CXXConversionFunctionName: {
1809 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregordd62b152009-10-19 22:04:39 +00001810 QualType T;
1811 if (!ObjectType.isNull() &&
1812 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1813 TemplateSpecializationType *SpecType
1814 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1815 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1816 } else
1817 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregor81499bb2009-09-03 22:13:48 +00001818 if (T.isNull())
1819 return DeclarationName();
Mike Stump1eb44332009-09-09 15:08:12 +00001820
Douglas Gregor81499bb2009-09-03 22:13:48 +00001821 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump1eb44332009-09-09 15:08:12 +00001822 Name.getNameKind(),
Douglas Gregor81499bb2009-09-03 22:13:48 +00001823 SemaRef.Context.getCanonicalType(T));
Douglas Gregor81499bb2009-09-03 22:13:48 +00001824 }
Mike Stump1eb44332009-09-09 15:08:12 +00001825 }
1826
Douglas Gregor81499bb2009-09-03 22:13:48 +00001827 return DeclarationName();
1828}
1829
1830template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001831TemplateName
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001832TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1833 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00001834 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001835 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001836 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1837 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1838 if (!NNS)
1839 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001840
Douglas Gregord1067e52009-08-06 06:41:21 +00001841 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001842 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001843 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1844 if (!TransTemplate)
1845 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001846
Douglas Gregord1067e52009-08-06 06:41:21 +00001847 if (!getDerived().AlwaysRebuild() &&
1848 NNS == QTN->getQualifier() &&
1849 TransTemplate == Template)
1850 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001851
Douglas Gregord1067e52009-08-06 06:41:21 +00001852 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1853 TransTemplate);
1854 }
Mike Stump1eb44332009-09-09 15:08:12 +00001855
John McCallf7a1a742009-11-24 19:00:30 +00001856 // These should be getting filtered out before they make it into the AST.
1857 assert(false && "overloaded template name survived to here");
Douglas Gregord1067e52009-08-06 06:41:21 +00001858 }
Mike Stump1eb44332009-09-09 15:08:12 +00001859
Douglas Gregord1067e52009-08-06 06:41:21 +00001860 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001861 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001862 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1863 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001864 if (!NNS && DTN->getQualifier())
Douglas Gregord1067e52009-08-06 06:41:21 +00001865 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001866
Douglas Gregord1067e52009-08-06 06:41:21 +00001867 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordd62b152009-10-19 22:04:39 +00001868 NNS == DTN->getQualifier() &&
1869 ObjectType.isNull())
Douglas Gregord1067e52009-08-06 06:41:21 +00001870 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001871
Douglas Gregorca1bdd72009-11-04 00:56:37 +00001872 if (DTN->isIdentifier())
1873 return getDerived().RebuildTemplateName(NNS, *DTN->getIdentifier(),
1874 ObjectType);
1875
1876 return getDerived().RebuildTemplateName(NNS, DTN->getOperator(),
1877 ObjectType);
Douglas Gregord1067e52009-08-06 06:41:21 +00001878 }
Mike Stump1eb44332009-09-09 15:08:12 +00001879
Douglas Gregord1067e52009-08-06 06:41:21 +00001880 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001881 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001882 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1883 if (!TransTemplate)
1884 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001885
Douglas Gregord1067e52009-08-06 06:41:21 +00001886 if (!getDerived().AlwaysRebuild() &&
1887 TransTemplate == Template)
1888 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001889
Douglas Gregord1067e52009-08-06 06:41:21 +00001890 return TemplateName(TransTemplate);
1891 }
Mike Stump1eb44332009-09-09 15:08:12 +00001892
John McCallf7a1a742009-11-24 19:00:30 +00001893 // These should be getting filtered out before they reach the AST.
1894 assert(false && "overloaded function decl survived to here");
1895 return TemplateName();
Douglas Gregord1067e52009-08-06 06:41:21 +00001896}
1897
1898template<typename Derived>
John McCall833ca992009-10-29 08:12:44 +00001899void TreeTransform<Derived>::InventTemplateArgumentLoc(
1900 const TemplateArgument &Arg,
1901 TemplateArgumentLoc &Output) {
1902 SourceLocation Loc = getDerived().getBaseLocation();
1903 switch (Arg.getKind()) {
1904 case TemplateArgument::Null:
1905 llvm::llvm_unreachable("null template argument in TreeTransform");
1906 break;
1907
1908 case TemplateArgument::Type:
1909 Output = TemplateArgumentLoc(Arg,
1910 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1911
1912 break;
1913
Douglas Gregor788cd062009-11-11 01:00:40 +00001914 case TemplateArgument::Template:
1915 Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
1916 break;
1917
John McCall833ca992009-10-29 08:12:44 +00001918 case TemplateArgument::Expression:
1919 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1920 break;
1921
1922 case TemplateArgument::Declaration:
1923 case TemplateArgument::Integral:
1924 case TemplateArgument::Pack:
John McCall828bff22009-10-29 18:45:58 +00001925 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall833ca992009-10-29 08:12:44 +00001926 break;
1927 }
1928}
1929
1930template<typename Derived>
1931bool TreeTransform<Derived>::TransformTemplateArgument(
1932 const TemplateArgumentLoc &Input,
1933 TemplateArgumentLoc &Output) {
1934 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregor670444e2009-08-04 22:27:00 +00001935 switch (Arg.getKind()) {
1936 case TemplateArgument::Null:
1937 case TemplateArgument::Integral:
John McCall833ca992009-10-29 08:12:44 +00001938 Output = Input;
1939 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00001940
Douglas Gregor670444e2009-08-04 22:27:00 +00001941 case TemplateArgument::Type: {
John McCall833ca992009-10-29 08:12:44 +00001942 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1943 if (DI == NULL)
1944 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1945
1946 DI = getDerived().TransformType(DI);
1947 if (!DI) return true;
1948
1949 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1950 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00001951 }
Mike Stump1eb44332009-09-09 15:08:12 +00001952
Douglas Gregor670444e2009-08-04 22:27:00 +00001953 case TemplateArgument::Declaration: {
John McCall833ca992009-10-29 08:12:44 +00001954 // FIXME: we should never have to transform one of these.
Douglas Gregor972e6ce2009-10-27 06:26:26 +00001955 DeclarationName Name;
1956 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1957 Name = ND->getDeclName();
Douglas Gregor788cd062009-11-11 01:00:40 +00001958 TemporaryBase Rebase(*this, Input.getLocation(), Name);
Douglas Gregor670444e2009-08-04 22:27:00 +00001959 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall833ca992009-10-29 08:12:44 +00001960 if (!D) return true;
1961
John McCall828bff22009-10-29 18:45:58 +00001962 Expr *SourceExpr = Input.getSourceDeclExpression();
1963 if (SourceExpr) {
1964 EnterExpressionEvaluationContext Unevaluated(getSema(),
1965 Action::Unevaluated);
1966 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
1967 if (E.isInvalid())
1968 SourceExpr = NULL;
1969 else {
1970 SourceExpr = E.takeAs<Expr>();
1971 SourceExpr->Retain();
1972 }
1973 }
1974
1975 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall833ca992009-10-29 08:12:44 +00001976 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00001977 }
Mike Stump1eb44332009-09-09 15:08:12 +00001978
Douglas Gregor788cd062009-11-11 01:00:40 +00001979 case TemplateArgument::Template: {
1980 TemporaryBase Rebase(*this, Input.getLocation(), DeclarationName());
1981 TemplateName Template
1982 = getDerived().TransformTemplateName(Arg.getAsTemplate());
1983 if (Template.isNull())
1984 return true;
1985
1986 Output = TemplateArgumentLoc(TemplateArgument(Template),
1987 Input.getTemplateQualifierRange(),
1988 Input.getTemplateNameLoc());
1989 return false;
1990 }
1991
Douglas Gregor670444e2009-08-04 22:27:00 +00001992 case TemplateArgument::Expression: {
1993 // Template argument expressions are not potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00001994 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregor670444e2009-08-04 22:27:00 +00001995 Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00001996
John McCall833ca992009-10-29 08:12:44 +00001997 Expr *InputExpr = Input.getSourceExpression();
1998 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
1999
2000 Sema::OwningExprResult E
2001 = getDerived().TransformExpr(InputExpr);
2002 if (E.isInvalid()) return true;
2003
2004 Expr *ETaken = E.takeAs<Expr>();
John McCall828bff22009-10-29 18:45:58 +00002005 ETaken->Retain();
John McCall833ca992009-10-29 08:12:44 +00002006 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
2007 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002008 }
Mike Stump1eb44332009-09-09 15:08:12 +00002009
Douglas Gregor670444e2009-08-04 22:27:00 +00002010 case TemplateArgument::Pack: {
2011 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
2012 TransformedArgs.reserve(Arg.pack_size());
Mike Stump1eb44332009-09-09 15:08:12 +00002013 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002014 AEnd = Arg.pack_end();
2015 A != AEnd; ++A) {
Mike Stump1eb44332009-09-09 15:08:12 +00002016
John McCall833ca992009-10-29 08:12:44 +00002017 // FIXME: preserve source information here when we start
2018 // caring about parameter packs.
2019
John McCall828bff22009-10-29 18:45:58 +00002020 TemplateArgumentLoc InputArg;
2021 TemplateArgumentLoc OutputArg;
2022 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2023 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall833ca992009-10-29 08:12:44 +00002024 return true;
2025
John McCall828bff22009-10-29 18:45:58 +00002026 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregor670444e2009-08-04 22:27:00 +00002027 }
2028 TemplateArgument Result;
Mike Stump1eb44332009-09-09 15:08:12 +00002029 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002030 true);
John McCall828bff22009-10-29 18:45:58 +00002031 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall833ca992009-10-29 08:12:44 +00002032 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002033 }
2034 }
Mike Stump1eb44332009-09-09 15:08:12 +00002035
Douglas Gregor670444e2009-08-04 22:27:00 +00002036 // Work around bogus GCC warning
John McCall833ca992009-10-29 08:12:44 +00002037 return true;
Douglas Gregor670444e2009-08-04 22:27:00 +00002038}
2039
Douglas Gregor577f75a2009-08-04 16:50:30 +00002040//===----------------------------------------------------------------------===//
2041// Type transformation
2042//===----------------------------------------------------------------------===//
2043
2044template<typename Derived>
2045QualType TreeTransform<Derived>::TransformType(QualType T) {
2046 if (getDerived().AlreadyTransformed(T))
2047 return T;
Mike Stump1eb44332009-09-09 15:08:12 +00002048
John McCalla2becad2009-10-21 00:40:46 +00002049 // Temporary workaround. All of these transformations should
2050 // eventually turn into transformations on TypeLocs.
2051 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCall4802a312009-10-21 00:44:26 +00002052 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCalla2becad2009-10-21 00:40:46 +00002053
2054 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall0953e762009-09-24 19:53:00 +00002055
John McCalla2becad2009-10-21 00:40:46 +00002056 if (!NewDI)
2057 return QualType();
2058
2059 return NewDI->getType();
2060}
2061
2062template<typename Derived>
2063DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2064 if (getDerived().AlreadyTransformed(DI->getType()))
2065 return DI;
2066
2067 TypeLocBuilder TLB;
2068
2069 TypeLoc TL = DI->getTypeLoc();
2070 TLB.reserve(TL.getFullDataSize());
2071
2072 QualType Result = getDerived().TransformType(TLB, TL);
2073 if (Result.isNull())
2074 return 0;
2075
2076 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2077}
2078
2079template<typename Derived>
2080QualType
2081TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2082 switch (T.getTypeLocClass()) {
2083#define ABSTRACT_TYPELOC(CLASS, PARENT)
2084#define TYPELOC(CLASS, PARENT) \
2085 case TypeLoc::CLASS: \
2086 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2087#include "clang/AST/TypeLocNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +00002088 }
Mike Stump1eb44332009-09-09 15:08:12 +00002089
John McCalla2becad2009-10-21 00:40:46 +00002090 llvm::llvm_unreachable("unhandled type loc!");
2091 return QualType();
2092}
2093
2094/// FIXME: By default, this routine adds type qualifiers only to types
2095/// that can have qualifiers, and silently suppresses those qualifiers
2096/// that are not permitted (e.g., qualifiers on reference or function
2097/// types). This is the right thing for template instantiation, but
2098/// probably not for other clients.
2099template<typename Derived>
2100QualType
2101TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2102 QualifiedTypeLoc T) {
Douglas Gregora4923eb2009-11-16 21:35:15 +00002103 Qualifiers Quals = T.getType().getLocalQualifiers();
John McCalla2becad2009-10-21 00:40:46 +00002104
2105 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2106 if (Result.isNull())
2107 return QualType();
2108
2109 // Silently suppress qualifiers if the result type can't be qualified.
2110 // FIXME: this is the right thing for template instantiation, but
2111 // probably not for other clients.
2112 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregor577f75a2009-08-04 16:50:30 +00002113 return Result;
Mike Stump1eb44332009-09-09 15:08:12 +00002114
John McCalla2becad2009-10-21 00:40:46 +00002115 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2116
2117 TLB.push<QualifiedTypeLoc>(Result);
2118
2119 // No location information to preserve.
2120
2121 return Result;
2122}
2123
2124template <class TyLoc> static inline
2125QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2126 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2127 NewT.setNameLoc(T.getNameLoc());
2128 return T.getType();
2129}
2130
2131// Ugly metaprogramming macros because I couldn't be bothered to make
2132// the equivalent template version work.
2133#define TransformPointerLikeType(TypeClass) do { \
2134 QualType PointeeType \
2135 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2136 if (PointeeType.isNull()) \
2137 return QualType(); \
2138 \
2139 QualType Result = TL.getType(); \
2140 if (getDerived().AlwaysRebuild() || \
2141 PointeeType != TL.getPointeeLoc().getType()) { \
John McCall85737a72009-10-30 00:06:24 +00002142 Result = getDerived().Rebuild##TypeClass(PointeeType, \
2143 TL.getSigilLoc()); \
John McCalla2becad2009-10-21 00:40:46 +00002144 if (Result.isNull()) \
2145 return QualType(); \
2146 } \
2147 \
2148 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2149 NewT.setSigilLoc(TL.getSigilLoc()); \
2150 \
2151 return Result; \
2152} while(0)
2153
John McCalla2becad2009-10-21 00:40:46 +00002154template<typename Derived>
2155QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2156 BuiltinTypeLoc T) {
2157 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002158}
Mike Stump1eb44332009-09-09 15:08:12 +00002159
Douglas Gregor577f75a2009-08-04 16:50:30 +00002160template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002161QualType
John McCalla2becad2009-10-21 00:40:46 +00002162TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2163 FixedWidthIntTypeLoc T) {
2164 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002165}
Argyrios Kyrtzidis1bb8a452009-08-19 01:28:17 +00002166
Douglas Gregor577f75a2009-08-04 16:50:30 +00002167template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002168QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2169 ComplexTypeLoc T) {
2170 // FIXME: recurse?
2171 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002172}
Mike Stump1eb44332009-09-09 15:08:12 +00002173
Douglas Gregor577f75a2009-08-04 16:50:30 +00002174template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002175QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2176 PointerTypeLoc TL) {
2177 TransformPointerLikeType(PointerType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002178}
Mike Stump1eb44332009-09-09 15:08:12 +00002179
2180template<typename Derived>
2181QualType
John McCalla2becad2009-10-21 00:40:46 +00002182TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2183 BlockPointerTypeLoc TL) {
2184 TransformPointerLikeType(BlockPointerType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002185}
2186
John McCall85737a72009-10-30 00:06:24 +00002187/// Transforms a reference type. Note that somewhat paradoxically we
2188/// don't care whether the type itself is an l-value type or an r-value
2189/// type; we only care if the type was *written* as an l-value type
2190/// or an r-value type.
2191template<typename Derived>
2192QualType
2193TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
2194 ReferenceTypeLoc TL) {
2195 const ReferenceType *T = TL.getTypePtr();
2196
2197 // Note that this works with the pointee-as-written.
2198 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
2199 if (PointeeType.isNull())
2200 return QualType();
2201
2202 QualType Result = TL.getType();
2203 if (getDerived().AlwaysRebuild() ||
2204 PointeeType != T->getPointeeTypeAsWritten()) {
2205 Result = getDerived().RebuildReferenceType(PointeeType,
2206 T->isSpelledAsLValue(),
2207 TL.getSigilLoc());
2208 if (Result.isNull())
2209 return QualType();
2210 }
2211
2212 // r-value references can be rebuilt as l-value references.
2213 ReferenceTypeLoc NewTL;
2214 if (isa<LValueReferenceType>(Result))
2215 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
2216 else
2217 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
2218 NewTL.setSigilLoc(TL.getSigilLoc());
2219
2220 return Result;
2221}
2222
Mike Stump1eb44332009-09-09 15:08:12 +00002223template<typename Derived>
2224QualType
John McCalla2becad2009-10-21 00:40:46 +00002225TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2226 LValueReferenceTypeLoc TL) {
John McCall85737a72009-10-30 00:06:24 +00002227 return TransformReferenceType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002228}
2229
Mike Stump1eb44332009-09-09 15:08:12 +00002230template<typename Derived>
2231QualType
John McCalla2becad2009-10-21 00:40:46 +00002232TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2233 RValueReferenceTypeLoc TL) {
John McCall85737a72009-10-30 00:06:24 +00002234 return TransformReferenceType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002235}
Mike Stump1eb44332009-09-09 15:08:12 +00002236
Douglas Gregor577f75a2009-08-04 16:50:30 +00002237template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002238QualType
John McCalla2becad2009-10-21 00:40:46 +00002239TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2240 MemberPointerTypeLoc TL) {
2241 MemberPointerType *T = TL.getTypePtr();
2242
2243 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002244 if (PointeeType.isNull())
2245 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002246
John McCalla2becad2009-10-21 00:40:46 +00002247 // TODO: preserve source information for this.
2248 QualType ClassType
2249 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002250 if (ClassType.isNull())
2251 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002252
John McCalla2becad2009-10-21 00:40:46 +00002253 QualType Result = TL.getType();
2254 if (getDerived().AlwaysRebuild() ||
2255 PointeeType != T->getPointeeType() ||
2256 ClassType != QualType(T->getClass(), 0)) {
John McCall85737a72009-10-30 00:06:24 +00002257 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
2258 TL.getStarLoc());
John McCalla2becad2009-10-21 00:40:46 +00002259 if (Result.isNull())
2260 return QualType();
2261 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00002262
John McCalla2becad2009-10-21 00:40:46 +00002263 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2264 NewTL.setSigilLoc(TL.getSigilLoc());
2265
2266 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002267}
2268
Mike Stump1eb44332009-09-09 15:08:12 +00002269template<typename Derived>
2270QualType
John McCalla2becad2009-10-21 00:40:46 +00002271TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2272 ConstantArrayTypeLoc TL) {
2273 ConstantArrayType *T = TL.getTypePtr();
2274 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002275 if (ElementType.isNull())
2276 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002277
John McCalla2becad2009-10-21 00:40:46 +00002278 QualType Result = TL.getType();
2279 if (getDerived().AlwaysRebuild() ||
2280 ElementType != T->getElementType()) {
2281 Result = getDerived().RebuildConstantArrayType(ElementType,
2282 T->getSizeModifier(),
2283 T->getSize(),
John McCall85737a72009-10-30 00:06:24 +00002284 T->getIndexTypeCVRQualifiers(),
2285 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002286 if (Result.isNull())
2287 return QualType();
2288 }
2289
2290 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2291 NewTL.setLBracketLoc(TL.getLBracketLoc());
2292 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00002293
John McCalla2becad2009-10-21 00:40:46 +00002294 Expr *Size = TL.getSizeExpr();
2295 if (Size) {
2296 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2297 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2298 }
2299 NewTL.setSizeExpr(Size);
2300
2301 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002302}
Mike Stump1eb44332009-09-09 15:08:12 +00002303
Douglas Gregor577f75a2009-08-04 16:50:30 +00002304template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002305QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCalla2becad2009-10-21 00:40:46 +00002306 TypeLocBuilder &TLB,
2307 IncompleteArrayTypeLoc TL) {
2308 IncompleteArrayType *T = TL.getTypePtr();
2309 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002310 if (ElementType.isNull())
2311 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002312
John McCalla2becad2009-10-21 00:40:46 +00002313 QualType Result = TL.getType();
2314 if (getDerived().AlwaysRebuild() ||
2315 ElementType != T->getElementType()) {
2316 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002317 T->getSizeModifier(),
John McCall85737a72009-10-30 00:06:24 +00002318 T->getIndexTypeCVRQualifiers(),
2319 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002320 if (Result.isNull())
2321 return QualType();
2322 }
2323
2324 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2325 NewTL.setLBracketLoc(TL.getLBracketLoc());
2326 NewTL.setRBracketLoc(TL.getRBracketLoc());
2327 NewTL.setSizeExpr(0);
2328
2329 return Result;
2330}
2331
2332template<typename Derived>
2333QualType
2334TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2335 VariableArrayTypeLoc TL) {
2336 VariableArrayType *T = TL.getTypePtr();
2337 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2338 if (ElementType.isNull())
2339 return QualType();
2340
2341 // Array bounds are not potentially evaluated contexts
2342 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2343
2344 Sema::OwningExprResult SizeResult
2345 = getDerived().TransformExpr(T->getSizeExpr());
2346 if (SizeResult.isInvalid())
2347 return QualType();
2348
2349 Expr *Size = static_cast<Expr*>(SizeResult.get());
2350
2351 QualType Result = TL.getType();
2352 if (getDerived().AlwaysRebuild() ||
2353 ElementType != T->getElementType() ||
2354 Size != T->getSizeExpr()) {
2355 Result = getDerived().RebuildVariableArrayType(ElementType,
2356 T->getSizeModifier(),
2357 move(SizeResult),
2358 T->getIndexTypeCVRQualifiers(),
John McCall85737a72009-10-30 00:06:24 +00002359 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002360 if (Result.isNull())
2361 return QualType();
2362 }
2363 else SizeResult.take();
2364
2365 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2366 NewTL.setLBracketLoc(TL.getLBracketLoc());
2367 NewTL.setRBracketLoc(TL.getRBracketLoc());
2368 NewTL.setSizeExpr(Size);
2369
2370 return Result;
2371}
2372
2373template<typename Derived>
2374QualType
2375TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2376 DependentSizedArrayTypeLoc TL) {
2377 DependentSizedArrayType *T = TL.getTypePtr();
2378 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2379 if (ElementType.isNull())
2380 return QualType();
2381
2382 // Array bounds are not potentially evaluated contexts
2383 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2384
2385 Sema::OwningExprResult SizeResult
2386 = getDerived().TransformExpr(T->getSizeExpr());
2387 if (SizeResult.isInvalid())
2388 return QualType();
2389
2390 Expr *Size = static_cast<Expr*>(SizeResult.get());
2391
2392 QualType Result = TL.getType();
2393 if (getDerived().AlwaysRebuild() ||
2394 ElementType != T->getElementType() ||
2395 Size != T->getSizeExpr()) {
2396 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2397 T->getSizeModifier(),
2398 move(SizeResult),
2399 T->getIndexTypeCVRQualifiers(),
John McCall85737a72009-10-30 00:06:24 +00002400 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002401 if (Result.isNull())
2402 return QualType();
2403 }
2404 else SizeResult.take();
2405
2406 // We might have any sort of array type now, but fortunately they
2407 // all have the same location layout.
2408 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2409 NewTL.setLBracketLoc(TL.getLBracketLoc());
2410 NewTL.setRBracketLoc(TL.getRBracketLoc());
2411 NewTL.setSizeExpr(Size);
2412
2413 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002414}
Mike Stump1eb44332009-09-09 15:08:12 +00002415
2416template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002417QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCalla2becad2009-10-21 00:40:46 +00002418 TypeLocBuilder &TLB,
2419 DependentSizedExtVectorTypeLoc TL) {
2420 DependentSizedExtVectorType *T = TL.getTypePtr();
2421
2422 // FIXME: ext vector locs should be nested
Douglas Gregor577f75a2009-08-04 16:50:30 +00002423 QualType ElementType = getDerived().TransformType(T->getElementType());
2424 if (ElementType.isNull())
2425 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002426
Douglas Gregor670444e2009-08-04 22:27:00 +00002427 // Vector sizes are not potentially evaluated contexts
2428 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2429
Douglas Gregor577f75a2009-08-04 16:50:30 +00002430 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2431 if (Size.isInvalid())
2432 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002433
John McCalla2becad2009-10-21 00:40:46 +00002434 QualType Result = TL.getType();
2435 if (getDerived().AlwaysRebuild() ||
John McCalleee91c32009-10-23 17:55:45 +00002436 ElementType != T->getElementType() ||
2437 Size.get() != T->getSizeExpr()) {
John McCalla2becad2009-10-21 00:40:46 +00002438 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002439 move(Size),
2440 T->getAttributeLoc());
John McCalla2becad2009-10-21 00:40:46 +00002441 if (Result.isNull())
2442 return QualType();
2443 }
2444 else Size.take();
2445
2446 // Result might be dependent or not.
2447 if (isa<DependentSizedExtVectorType>(Result)) {
2448 DependentSizedExtVectorTypeLoc NewTL
2449 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2450 NewTL.setNameLoc(TL.getNameLoc());
2451 } else {
2452 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2453 NewTL.setNameLoc(TL.getNameLoc());
2454 }
2455
2456 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002457}
Mike Stump1eb44332009-09-09 15:08:12 +00002458
2459template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002460QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2461 VectorTypeLoc TL) {
2462 VectorType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002463 QualType ElementType = getDerived().TransformType(T->getElementType());
2464 if (ElementType.isNull())
2465 return QualType();
2466
John McCalla2becad2009-10-21 00:40:46 +00002467 QualType Result = TL.getType();
2468 if (getDerived().AlwaysRebuild() ||
2469 ElementType != T->getElementType()) {
2470 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2471 if (Result.isNull())
2472 return QualType();
2473 }
2474
2475 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2476 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00002477
John McCalla2becad2009-10-21 00:40:46 +00002478 return Result;
2479}
2480
2481template<typename Derived>
2482QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2483 ExtVectorTypeLoc TL) {
2484 VectorType *T = TL.getTypePtr();
2485 QualType ElementType = getDerived().TransformType(T->getElementType());
2486 if (ElementType.isNull())
2487 return QualType();
2488
2489 QualType Result = TL.getType();
2490 if (getDerived().AlwaysRebuild() ||
2491 ElementType != T->getElementType()) {
2492 Result = getDerived().RebuildExtVectorType(ElementType,
2493 T->getNumElements(),
2494 /*FIXME*/ SourceLocation());
2495 if (Result.isNull())
2496 return QualType();
2497 }
2498
2499 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2500 NewTL.setNameLoc(TL.getNameLoc());
2501
2502 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002503}
Mike Stump1eb44332009-09-09 15:08:12 +00002504
2505template<typename Derived>
2506QualType
John McCalla2becad2009-10-21 00:40:46 +00002507TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2508 FunctionProtoTypeLoc TL) {
2509 FunctionProtoType *T = TL.getTypePtr();
2510 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002511 if (ResultType.isNull())
2512 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002513
John McCalla2becad2009-10-21 00:40:46 +00002514 // Transform the parameters.
Douglas Gregor577f75a2009-08-04 16:50:30 +00002515 llvm::SmallVector<QualType, 4> ParamTypes;
John McCalla2becad2009-10-21 00:40:46 +00002516 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2517 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2518 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump1eb44332009-09-09 15:08:12 +00002519
John McCalla2becad2009-10-21 00:40:46 +00002520 QualType NewType;
2521 ParmVarDecl *NewParm;
2522
2523 if (OldParm) {
2524 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2525 assert(OldDI->getType() == T->getArgType(i));
2526
2527 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2528 if (!NewDI)
2529 return QualType();
2530
2531 if (NewDI == OldDI)
2532 NewParm = OldParm;
2533 else
2534 NewParm = ParmVarDecl::Create(SemaRef.Context,
2535 OldParm->getDeclContext(),
2536 OldParm->getLocation(),
2537 OldParm->getIdentifier(),
2538 NewDI->getType(),
2539 NewDI,
2540 OldParm->getStorageClass(),
2541 /* DefArg */ NULL);
2542 NewType = NewParm->getType();
2543
2544 // Deal with the possibility that we don't have a parameter
2545 // declaration for this parameter.
2546 } else {
2547 NewParm = 0;
2548
2549 QualType OldType = T->getArgType(i);
2550 NewType = getDerived().TransformType(OldType);
2551 if (NewType.isNull())
2552 return QualType();
2553 }
2554
2555 ParamTypes.push_back(NewType);
2556 ParamDecls.push_back(NewParm);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002557 }
Mike Stump1eb44332009-09-09 15:08:12 +00002558
John McCalla2becad2009-10-21 00:40:46 +00002559 QualType Result = TL.getType();
2560 if (getDerived().AlwaysRebuild() ||
2561 ResultType != T->getResultType() ||
2562 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2563 Result = getDerived().RebuildFunctionProtoType(ResultType,
2564 ParamTypes.data(),
2565 ParamTypes.size(),
2566 T->isVariadic(),
2567 T->getTypeQuals());
2568 if (Result.isNull())
2569 return QualType();
2570 }
Mike Stump1eb44332009-09-09 15:08:12 +00002571
John McCalla2becad2009-10-21 00:40:46 +00002572 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2573 NewTL.setLParenLoc(TL.getLParenLoc());
2574 NewTL.setRParenLoc(TL.getRParenLoc());
2575 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2576 NewTL.setArg(i, ParamDecls[i]);
2577
2578 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002579}
Mike Stump1eb44332009-09-09 15:08:12 +00002580
Douglas Gregor577f75a2009-08-04 16:50:30 +00002581template<typename Derived>
2582QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCalla2becad2009-10-21 00:40:46 +00002583 TypeLocBuilder &TLB,
2584 FunctionNoProtoTypeLoc TL) {
2585 FunctionNoProtoType *T = TL.getTypePtr();
2586 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2587 if (ResultType.isNull())
2588 return QualType();
2589
2590 QualType Result = TL.getType();
2591 if (getDerived().AlwaysRebuild() ||
2592 ResultType != T->getResultType())
2593 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2594
2595 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2596 NewTL.setLParenLoc(TL.getLParenLoc());
2597 NewTL.setRParenLoc(TL.getRParenLoc());
2598
2599 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002600}
Mike Stump1eb44332009-09-09 15:08:12 +00002601
Douglas Gregor577f75a2009-08-04 16:50:30 +00002602template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002603QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2604 TypedefTypeLoc TL) {
2605 TypedefType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002606 TypedefDecl *Typedef
2607 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2608 if (!Typedef)
2609 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002610
John McCalla2becad2009-10-21 00:40:46 +00002611 QualType Result = TL.getType();
2612 if (getDerived().AlwaysRebuild() ||
2613 Typedef != T->getDecl()) {
2614 Result = getDerived().RebuildTypedefType(Typedef);
2615 if (Result.isNull())
2616 return QualType();
2617 }
Mike Stump1eb44332009-09-09 15:08:12 +00002618
John McCalla2becad2009-10-21 00:40:46 +00002619 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2620 NewTL.setNameLoc(TL.getNameLoc());
2621
2622 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002623}
Mike Stump1eb44332009-09-09 15:08:12 +00002624
Douglas Gregor577f75a2009-08-04 16:50:30 +00002625template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002626QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2627 TypeOfExprTypeLoc TL) {
2628 TypeOfExprType *T = TL.getTypePtr();
2629
Douglas Gregor670444e2009-08-04 22:27:00 +00002630 // typeof expressions are not potentially evaluated contexts
2631 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002632
Douglas Gregor577f75a2009-08-04 16:50:30 +00002633 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2634 if (E.isInvalid())
2635 return QualType();
2636
John McCalla2becad2009-10-21 00:40:46 +00002637 QualType Result = TL.getType();
2638 if (getDerived().AlwaysRebuild() ||
2639 E.get() != T->getUnderlyingExpr()) {
2640 Result = getDerived().RebuildTypeOfExprType(move(E));
2641 if (Result.isNull())
2642 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002643 }
John McCalla2becad2009-10-21 00:40:46 +00002644 else E.take();
Mike Stump1eb44332009-09-09 15:08:12 +00002645
John McCalla2becad2009-10-21 00:40:46 +00002646 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2647 NewTL.setNameLoc(TL.getNameLoc());
2648
2649 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002650}
Mike Stump1eb44332009-09-09 15:08:12 +00002651
2652template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002653QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2654 TypeOfTypeLoc TL) {
2655 TypeOfType *T = TL.getTypePtr();
2656
2657 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregor577f75a2009-08-04 16:50:30 +00002658 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2659 if (Underlying.isNull())
2660 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002661
John McCalla2becad2009-10-21 00:40:46 +00002662 QualType Result = TL.getType();
2663 if (getDerived().AlwaysRebuild() ||
2664 Underlying != T->getUnderlyingType()) {
2665 Result = getDerived().RebuildTypeOfType(Underlying);
2666 if (Result.isNull())
2667 return QualType();
2668 }
Mike Stump1eb44332009-09-09 15:08:12 +00002669
John McCalla2becad2009-10-21 00:40:46 +00002670 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2671 NewTL.setNameLoc(TL.getNameLoc());
2672
2673 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002674}
Mike Stump1eb44332009-09-09 15:08:12 +00002675
2676template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002677QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2678 DecltypeTypeLoc TL) {
2679 DecltypeType *T = TL.getTypePtr();
2680
Douglas Gregor670444e2009-08-04 22:27:00 +00002681 // decltype expressions are not potentially evaluated contexts
2682 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002683
Douglas Gregor577f75a2009-08-04 16:50:30 +00002684 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2685 if (E.isInvalid())
2686 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002687
John McCalla2becad2009-10-21 00:40:46 +00002688 QualType Result = TL.getType();
2689 if (getDerived().AlwaysRebuild() ||
2690 E.get() != T->getUnderlyingExpr()) {
2691 Result = getDerived().RebuildDecltypeType(move(E));
2692 if (Result.isNull())
2693 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002694 }
John McCalla2becad2009-10-21 00:40:46 +00002695 else E.take();
Mike Stump1eb44332009-09-09 15:08:12 +00002696
John McCalla2becad2009-10-21 00:40:46 +00002697 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2698 NewTL.setNameLoc(TL.getNameLoc());
2699
2700 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002701}
2702
2703template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002704QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2705 RecordTypeLoc TL) {
2706 RecordType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002707 RecordDecl *Record
John McCalla2becad2009-10-21 00:40:46 +00002708 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002709 if (!Record)
2710 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002711
John McCalla2becad2009-10-21 00:40:46 +00002712 QualType Result = TL.getType();
2713 if (getDerived().AlwaysRebuild() ||
2714 Record != T->getDecl()) {
2715 Result = getDerived().RebuildRecordType(Record);
2716 if (Result.isNull())
2717 return QualType();
2718 }
Mike Stump1eb44332009-09-09 15:08:12 +00002719
John McCalla2becad2009-10-21 00:40:46 +00002720 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2721 NewTL.setNameLoc(TL.getNameLoc());
2722
2723 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002724}
Mike Stump1eb44332009-09-09 15:08:12 +00002725
2726template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002727QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2728 EnumTypeLoc TL) {
2729 EnumType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002730 EnumDecl *Enum
John McCalla2becad2009-10-21 00:40:46 +00002731 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002732 if (!Enum)
2733 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002734
John McCalla2becad2009-10-21 00:40:46 +00002735 QualType Result = TL.getType();
2736 if (getDerived().AlwaysRebuild() ||
2737 Enum != T->getDecl()) {
2738 Result = getDerived().RebuildEnumType(Enum);
2739 if (Result.isNull())
2740 return QualType();
2741 }
Mike Stump1eb44332009-09-09 15:08:12 +00002742
John McCalla2becad2009-10-21 00:40:46 +00002743 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2744 NewTL.setNameLoc(TL.getNameLoc());
2745
2746 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002747}
John McCall7da24312009-09-05 00:15:47 +00002748
2749template <typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002750QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2751 ElaboratedTypeLoc TL) {
2752 ElaboratedType *T = TL.getTypePtr();
2753
2754 // FIXME: this should be a nested type.
John McCall7da24312009-09-05 00:15:47 +00002755 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2756 if (Underlying.isNull())
2757 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002758
John McCalla2becad2009-10-21 00:40:46 +00002759 QualType Result = TL.getType();
2760 if (getDerived().AlwaysRebuild() ||
2761 Underlying != T->getUnderlyingType()) {
2762 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2763 if (Result.isNull())
2764 return QualType();
2765 }
Mike Stump1eb44332009-09-09 15:08:12 +00002766
John McCalla2becad2009-10-21 00:40:46 +00002767 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2768 NewTL.setNameLoc(TL.getNameLoc());
2769
2770 return Result;
John McCall7da24312009-09-05 00:15:47 +00002771}
Mike Stump1eb44332009-09-09 15:08:12 +00002772
2773
Douglas Gregor577f75a2009-08-04 16:50:30 +00002774template<typename Derived>
2775QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCalla2becad2009-10-21 00:40:46 +00002776 TypeLocBuilder &TLB,
2777 TemplateTypeParmTypeLoc TL) {
2778 return TransformTypeSpecType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002779}
2780
Mike Stump1eb44332009-09-09 15:08:12 +00002781template<typename Derived>
John McCall49a832b2009-10-18 09:09:24 +00002782QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCalla2becad2009-10-21 00:40:46 +00002783 TypeLocBuilder &TLB,
2784 SubstTemplateTypeParmTypeLoc TL) {
2785 return TransformTypeSpecType(TLB, TL);
John McCall49a832b2009-10-18 09:09:24 +00002786}
2787
2788template<typename Derived>
Douglas Gregordd62b152009-10-19 22:04:39 +00002789inline QualType
2790TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCalla2becad2009-10-21 00:40:46 +00002791 TypeLocBuilder &TLB,
2792 TemplateSpecializationTypeLoc TL) {
John McCall833ca992009-10-29 08:12:44 +00002793 return TransformTemplateSpecializationType(TLB, TL, QualType());
2794}
John McCalla2becad2009-10-21 00:40:46 +00002795
John McCall833ca992009-10-29 08:12:44 +00002796template<typename Derived>
2797QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2798 const TemplateSpecializationType *TST,
2799 QualType ObjectType) {
2800 // FIXME: this entire method is a temporary workaround; callers
2801 // should be rewritten to provide real type locs.
John McCalla2becad2009-10-21 00:40:46 +00002802
John McCall833ca992009-10-29 08:12:44 +00002803 // Fake up a TemplateSpecializationTypeLoc.
2804 TypeLocBuilder TLB;
2805 TemplateSpecializationTypeLoc TL
2806 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2807
John McCall828bff22009-10-29 18:45:58 +00002808 SourceLocation BaseLoc = getDerived().getBaseLocation();
2809
2810 TL.setTemplateNameLoc(BaseLoc);
2811 TL.setLAngleLoc(BaseLoc);
2812 TL.setRAngleLoc(BaseLoc);
John McCall833ca992009-10-29 08:12:44 +00002813 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2814 const TemplateArgument &TA = TST->getArg(i);
2815 TemplateArgumentLoc TAL;
2816 getDerived().InventTemplateArgumentLoc(TA, TAL);
2817 TL.setArgLocInfo(i, TAL.getLocInfo());
2818 }
2819
2820 TypeLocBuilder IgnoredTLB;
2821 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregordd62b152009-10-19 22:04:39 +00002822}
2823
2824template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002825QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall833ca992009-10-29 08:12:44 +00002826 TypeLocBuilder &TLB,
2827 TemplateSpecializationTypeLoc TL,
2828 QualType ObjectType) {
2829 const TemplateSpecializationType *T = TL.getTypePtr();
2830
Mike Stump1eb44332009-09-09 15:08:12 +00002831 TemplateName Template
Douglas Gregordd62b152009-10-19 22:04:39 +00002832 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002833 if (Template.isNull())
2834 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002835
John McCalld5532b62009-11-23 01:53:49 +00002836 TemplateArgumentListInfo NewTemplateArgs;
2837 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
2838 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
2839
2840 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
2841 TemplateArgumentLoc Loc;
2842 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i), Loc))
Douglas Gregor577f75a2009-08-04 16:50:30 +00002843 return QualType();
John McCalld5532b62009-11-23 01:53:49 +00002844 NewTemplateArgs.addArgument(Loc);
2845 }
Mike Stump1eb44332009-09-09 15:08:12 +00002846
John McCall833ca992009-10-29 08:12:44 +00002847 // FIXME: maybe don't rebuild if all the template arguments are the same.
2848
2849 QualType Result =
2850 getDerived().RebuildTemplateSpecializationType(Template,
2851 TL.getTemplateNameLoc(),
John McCalld5532b62009-11-23 01:53:49 +00002852 NewTemplateArgs);
John McCall833ca992009-10-29 08:12:44 +00002853
2854 if (!Result.isNull()) {
2855 TemplateSpecializationTypeLoc NewTL
2856 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2857 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2858 NewTL.setLAngleLoc(TL.getLAngleLoc());
2859 NewTL.setRAngleLoc(TL.getRAngleLoc());
2860 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2861 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002862 }
Mike Stump1eb44332009-09-09 15:08:12 +00002863
John McCall833ca992009-10-29 08:12:44 +00002864 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002865}
Mike Stump1eb44332009-09-09 15:08:12 +00002866
2867template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002868QualType
2869TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2870 QualifiedNameTypeLoc TL) {
2871 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002872 NestedNameSpecifier *NNS
2873 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2874 SourceRange());
2875 if (!NNS)
2876 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002877
Douglas Gregor577f75a2009-08-04 16:50:30 +00002878 QualType Named = getDerived().TransformType(T->getNamedType());
2879 if (Named.isNull())
2880 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002881
John McCalla2becad2009-10-21 00:40:46 +00002882 QualType Result = TL.getType();
2883 if (getDerived().AlwaysRebuild() ||
2884 NNS != T->getQualifier() ||
2885 Named != T->getNamedType()) {
2886 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2887 if (Result.isNull())
2888 return QualType();
2889 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00002890
John McCalla2becad2009-10-21 00:40:46 +00002891 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2892 NewTL.setNameLoc(TL.getNameLoc());
2893
2894 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002895}
Mike Stump1eb44332009-09-09 15:08:12 +00002896
2897template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002898QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2899 TypenameTypeLoc TL) {
2900 TypenameType *T = TL.getTypePtr();
John McCall833ca992009-10-29 08:12:44 +00002901
2902 /* FIXME: preserve source information better than this */
2903 SourceRange SR(TL.getNameLoc());
2904
Douglas Gregor577f75a2009-08-04 16:50:30 +00002905 NestedNameSpecifier *NNS
John McCall833ca992009-10-29 08:12:44 +00002906 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002907 if (!NNS)
2908 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002909
John McCalla2becad2009-10-21 00:40:46 +00002910 QualType Result;
2911
Douglas Gregor577f75a2009-08-04 16:50:30 +00002912 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002913 QualType NewTemplateId
Douglas Gregor577f75a2009-08-04 16:50:30 +00002914 = getDerived().TransformType(QualType(TemplateId, 0));
2915 if (NewTemplateId.isNull())
2916 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002917
Douglas Gregor577f75a2009-08-04 16:50:30 +00002918 if (!getDerived().AlwaysRebuild() &&
2919 NNS == T->getQualifier() &&
2920 NewTemplateId == QualType(TemplateId, 0))
2921 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002922
John McCalla2becad2009-10-21 00:40:46 +00002923 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2924 } else {
John McCall833ca992009-10-29 08:12:44 +00002925 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002926 }
John McCalla2becad2009-10-21 00:40:46 +00002927 if (Result.isNull())
2928 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002929
John McCalla2becad2009-10-21 00:40:46 +00002930 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2931 NewTL.setNameLoc(TL.getNameLoc());
2932
2933 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002934}
Mike Stump1eb44332009-09-09 15:08:12 +00002935
Douglas Gregor577f75a2009-08-04 16:50:30 +00002936template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002937QualType
2938TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2939 ObjCInterfaceTypeLoc TL) {
John McCall54e14c42009-10-22 22:37:11 +00002940 assert(false && "TransformObjCInterfaceType unimplemented");
2941 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002942}
Mike Stump1eb44332009-09-09 15:08:12 +00002943
2944template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002945QualType
2946TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2947 ObjCObjectPointerTypeLoc TL) {
John McCall54e14c42009-10-22 22:37:11 +00002948 assert(false && "TransformObjCObjectPointerType unimplemented");
2949 return QualType();
Argyrios Kyrtzidis24fab412009-09-29 19:42:55 +00002950}
2951
Douglas Gregor577f75a2009-08-04 16:50:30 +00002952//===----------------------------------------------------------------------===//
Douglas Gregor43959a92009-08-20 07:17:43 +00002953// Statement transformation
2954//===----------------------------------------------------------------------===//
2955template<typename Derived>
2956Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002957TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2958 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002959}
2960
2961template<typename Derived>
2962Sema::OwningStmtResult
2963TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2964 return getDerived().TransformCompoundStmt(S, false);
2965}
2966
2967template<typename Derived>
2968Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002969TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregor43959a92009-08-20 07:17:43 +00002970 bool IsStmtExpr) {
2971 bool SubStmtChanged = false;
2972 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2973 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2974 B != BEnd; ++B) {
2975 OwningStmtResult Result = getDerived().TransformStmt(*B);
2976 if (Result.isInvalid())
2977 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00002978
Douglas Gregor43959a92009-08-20 07:17:43 +00002979 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2980 Statements.push_back(Result.takeAs<Stmt>());
2981 }
Mike Stump1eb44332009-09-09 15:08:12 +00002982
Douglas Gregor43959a92009-08-20 07:17:43 +00002983 if (!getDerived().AlwaysRebuild() &&
2984 !SubStmtChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00002985 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002986
2987 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2988 move_arg(Statements),
2989 S->getRBracLoc(),
2990 IsStmtExpr);
2991}
Mike Stump1eb44332009-09-09 15:08:12 +00002992
Douglas Gregor43959a92009-08-20 07:17:43 +00002993template<typename Derived>
2994Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002995TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Eli Friedman264c1f82009-11-19 03:14:00 +00002996 OwningExprResult LHS(SemaRef), RHS(SemaRef);
2997 {
2998 // The case value expressions are not potentially evaluated.
2999 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003000
Eli Friedman264c1f82009-11-19 03:14:00 +00003001 // Transform the left-hand case value.
3002 LHS = getDerived().TransformExpr(S->getLHS());
3003 if (LHS.isInvalid())
3004 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003005
Eli Friedman264c1f82009-11-19 03:14:00 +00003006 // Transform the right-hand case value (for the GNU case-range extension).
3007 RHS = getDerived().TransformExpr(S->getRHS());
3008 if (RHS.isInvalid())
3009 return SemaRef.StmtError();
3010 }
Mike Stump1eb44332009-09-09 15:08:12 +00003011
Douglas Gregor43959a92009-08-20 07:17:43 +00003012 // Build the case statement.
3013 // Case statements are always rebuilt so that they will attached to their
3014 // transformed switch statement.
3015 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
3016 move(LHS),
3017 S->getEllipsisLoc(),
3018 move(RHS),
3019 S->getColonLoc());
3020 if (Case.isInvalid())
3021 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003022
Douglas Gregor43959a92009-08-20 07:17:43 +00003023 // Transform the statement following the case
3024 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3025 if (SubStmt.isInvalid())
3026 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003027
Douglas Gregor43959a92009-08-20 07:17:43 +00003028 // Attach the body to the case statement
3029 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
3030}
3031
3032template<typename Derived>
3033Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003034TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003035 // Transform the statement following the default case
3036 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3037 if (SubStmt.isInvalid())
3038 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003039
Douglas Gregor43959a92009-08-20 07:17:43 +00003040 // Default statements are always rebuilt
3041 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3042 move(SubStmt));
3043}
Mike Stump1eb44332009-09-09 15:08:12 +00003044
Douglas Gregor43959a92009-08-20 07:17:43 +00003045template<typename Derived>
3046Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003047TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003048 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3049 if (SubStmt.isInvalid())
3050 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003051
Douglas Gregor43959a92009-08-20 07:17:43 +00003052 // FIXME: Pass the real colon location in.
3053 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3054 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3055 move(SubStmt));
3056}
Mike Stump1eb44332009-09-09 15:08:12 +00003057
Douglas Gregor43959a92009-08-20 07:17:43 +00003058template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003059Sema::OwningStmtResult
3060TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003061 // Transform the condition
Douglas Gregor8cfe5a72009-11-23 23:44:04 +00003062 OwningExprResult Cond(SemaRef);
3063 VarDecl *ConditionVar = 0;
3064 if (S->getConditionVariable()) {
3065 ConditionVar
3066 = cast_or_null<VarDecl>(
3067 getDerived().TransformDefinition(S->getConditionVariable()));
3068 if (!ConditionVar)
3069 return SemaRef.StmtError();
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003070 } else {
Douglas Gregor8cfe5a72009-11-23 23:44:04 +00003071 Cond = getDerived().TransformExpr(S->getCond());
3072
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003073 if (Cond.isInvalid())
3074 return SemaRef.StmtError();
3075 }
Douglas Gregor8cfe5a72009-11-23 23:44:04 +00003076
Douglas Gregor43959a92009-08-20 07:17:43 +00003077 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00003078
Douglas Gregor43959a92009-08-20 07:17:43 +00003079 // Transform the "then" branch.
3080 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3081 if (Then.isInvalid())
3082 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003083
Douglas Gregor43959a92009-08-20 07:17:43 +00003084 // Transform the "else" branch.
3085 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3086 if (Else.isInvalid())
3087 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003088
Douglas Gregor43959a92009-08-20 07:17:43 +00003089 if (!getDerived().AlwaysRebuild() &&
3090 FullCond->get() == S->getCond() &&
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003091 ConditionVar == S->getConditionVariable() &&
Douglas Gregor43959a92009-08-20 07:17:43 +00003092 Then.get() == S->getThen() &&
3093 Else.get() == S->getElse())
Mike Stump1eb44332009-09-09 15:08:12 +00003094 return SemaRef.Owned(S->Retain());
3095
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003096 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
3097 move(Then),
Mike Stump1eb44332009-09-09 15:08:12 +00003098 S->getElseLoc(), move(Else));
Douglas Gregor43959a92009-08-20 07:17:43 +00003099}
3100
3101template<typename Derived>
3102Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003103TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003104 // Transform the condition.
Douglas Gregord3d53012009-11-24 17:07:59 +00003105 OwningExprResult Cond(SemaRef);
3106 VarDecl *ConditionVar = 0;
3107 if (S->getConditionVariable()) {
3108 ConditionVar
3109 = cast_or_null<VarDecl>(
3110 getDerived().TransformDefinition(S->getConditionVariable()));
3111 if (!ConditionVar)
3112 return SemaRef.StmtError();
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003113 } else {
Douglas Gregord3d53012009-11-24 17:07:59 +00003114 Cond = getDerived().TransformExpr(S->getCond());
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003115
3116 if (Cond.isInvalid())
3117 return SemaRef.StmtError();
3118 }
Mike Stump1eb44332009-09-09 15:08:12 +00003119
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003120 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
3121
Douglas Gregor43959a92009-08-20 07:17:43 +00003122 // Rebuild the switch statement.
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003123 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(FullCond,
3124 ConditionVar);
Douglas Gregor43959a92009-08-20 07:17:43 +00003125 if (Switch.isInvalid())
3126 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003127
Douglas Gregor43959a92009-08-20 07:17:43 +00003128 // Transform the body of the switch statement.
3129 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3130 if (Body.isInvalid())
3131 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003132
Douglas Gregor43959a92009-08-20 07:17:43 +00003133 // Complete the switch statement.
3134 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3135 move(Body));
3136}
Mike Stump1eb44332009-09-09 15:08:12 +00003137
Douglas Gregor43959a92009-08-20 07:17:43 +00003138template<typename Derived>
3139Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003140TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003141 // Transform the condition
Douglas Gregor5656e142009-11-24 21:15:44 +00003142 OwningExprResult Cond(SemaRef);
3143 VarDecl *ConditionVar = 0;
3144 if (S->getConditionVariable()) {
3145 ConditionVar
3146 = cast_or_null<VarDecl>(
3147 getDerived().TransformDefinition(S->getConditionVariable()));
3148 if (!ConditionVar)
3149 return SemaRef.StmtError();
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003150 } else {
Douglas Gregor5656e142009-11-24 21:15:44 +00003151 Cond = getDerived().TransformExpr(S->getCond());
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003152
3153 if (Cond.isInvalid())
3154 return SemaRef.StmtError();
3155 }
Mike Stump1eb44332009-09-09 15:08:12 +00003156
Douglas Gregor43959a92009-08-20 07:17:43 +00003157 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00003158
Douglas Gregor43959a92009-08-20 07:17:43 +00003159 // Transform the body
3160 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3161 if (Body.isInvalid())
3162 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003163
Douglas Gregor43959a92009-08-20 07:17:43 +00003164 if (!getDerived().AlwaysRebuild() &&
3165 FullCond->get() == S->getCond() &&
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003166 ConditionVar == S->getConditionVariable() &&
Douglas Gregor43959a92009-08-20 07:17:43 +00003167 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003168 return SemaRef.Owned(S->Retain());
3169
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003170 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, ConditionVar,
3171 move(Body));
Douglas Gregor43959a92009-08-20 07:17:43 +00003172}
Mike Stump1eb44332009-09-09 15:08:12 +00003173
Douglas Gregor43959a92009-08-20 07:17:43 +00003174template<typename Derived>
3175Sema::OwningStmtResult
3176TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3177 // Transform the condition
3178 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3179 if (Cond.isInvalid())
3180 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003181
Douglas Gregor43959a92009-08-20 07:17:43 +00003182 // Transform the body
3183 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3184 if (Body.isInvalid())
3185 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003186
Douglas Gregor43959a92009-08-20 07:17:43 +00003187 if (!getDerived().AlwaysRebuild() &&
3188 Cond.get() == S->getCond() &&
3189 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003190 return SemaRef.Owned(S->Retain());
3191
Douglas Gregor43959a92009-08-20 07:17:43 +00003192 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3193 /*FIXME:*/S->getWhileLoc(), move(Cond),
3194 S->getRParenLoc());
3195}
Mike Stump1eb44332009-09-09 15:08:12 +00003196
Douglas Gregor43959a92009-08-20 07:17:43 +00003197template<typename Derived>
3198Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003199TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003200 // Transform the initialization statement
3201 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3202 if (Init.isInvalid())
3203 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003204
Douglas Gregor43959a92009-08-20 07:17:43 +00003205 // Transform the condition
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003206 OwningExprResult Cond(SemaRef);
3207 VarDecl *ConditionVar = 0;
3208 if (S->getConditionVariable()) {
3209 ConditionVar
3210 = cast_or_null<VarDecl>(
3211 getDerived().TransformDefinition(S->getConditionVariable()));
3212 if (!ConditionVar)
3213 return SemaRef.StmtError();
3214 } else {
3215 Cond = getDerived().TransformExpr(S->getCond());
3216
3217 if (Cond.isInvalid())
3218 return SemaRef.StmtError();
3219 }
Mike Stump1eb44332009-09-09 15:08:12 +00003220
Douglas Gregor43959a92009-08-20 07:17:43 +00003221 // Transform the increment
3222 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3223 if (Inc.isInvalid())
3224 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003225
Douglas Gregor43959a92009-08-20 07:17:43 +00003226 // Transform the body
3227 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3228 if (Body.isInvalid())
3229 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003230
Douglas Gregor43959a92009-08-20 07:17:43 +00003231 if (!getDerived().AlwaysRebuild() &&
3232 Init.get() == S->getInit() &&
3233 Cond.get() == S->getCond() &&
3234 Inc.get() == S->getInc() &&
3235 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003236 return SemaRef.Owned(S->Retain());
3237
Douglas Gregor43959a92009-08-20 07:17:43 +00003238 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
Douglas Gregor99e9b4d2009-11-25 00:27:52 +00003239 move(Init), getSema().FullExpr(Cond),
3240 ConditionVar,
3241 getSema().FullExpr(Inc),
Douglas Gregor43959a92009-08-20 07:17:43 +00003242 S->getRParenLoc(), move(Body));
3243}
3244
3245template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003246Sema::OwningStmtResult
3247TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003248 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump1eb44332009-09-09 15:08:12 +00003249 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregor43959a92009-08-20 07:17:43 +00003250 S->getLabel());
3251}
3252
3253template<typename Derived>
3254Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003255TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003256 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3257 if (Target.isInvalid())
3258 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003259
Douglas Gregor43959a92009-08-20 07:17:43 +00003260 if (!getDerived().AlwaysRebuild() &&
3261 Target.get() == S->getTarget())
Mike Stump1eb44332009-09-09 15:08:12 +00003262 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003263
3264 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3265 move(Target));
3266}
3267
3268template<typename Derived>
3269Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003270TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3271 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003272}
Mike Stump1eb44332009-09-09 15:08:12 +00003273
Douglas Gregor43959a92009-08-20 07:17:43 +00003274template<typename Derived>
3275Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003276TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3277 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003278}
Mike Stump1eb44332009-09-09 15:08:12 +00003279
Douglas Gregor43959a92009-08-20 07:17:43 +00003280template<typename Derived>
3281Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003282TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003283 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3284 if (Result.isInvalid())
3285 return SemaRef.StmtError();
3286
Mike Stump1eb44332009-09-09 15:08:12 +00003287 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregor43959a92009-08-20 07:17:43 +00003288 // to tell whether the return type of the function has changed.
3289 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3290}
Mike Stump1eb44332009-09-09 15:08:12 +00003291
Douglas Gregor43959a92009-08-20 07:17:43 +00003292template<typename Derived>
3293Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003294TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003295 bool DeclChanged = false;
3296 llvm::SmallVector<Decl *, 4> Decls;
3297 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3298 D != DEnd; ++D) {
3299 Decl *Transformed = getDerived().TransformDefinition(*D);
3300 if (!Transformed)
3301 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003302
Douglas Gregor43959a92009-08-20 07:17:43 +00003303 if (Transformed != *D)
3304 DeclChanged = true;
Mike Stump1eb44332009-09-09 15:08:12 +00003305
Douglas Gregor43959a92009-08-20 07:17:43 +00003306 Decls.push_back(Transformed);
3307 }
Mike Stump1eb44332009-09-09 15:08:12 +00003308
Douglas Gregor43959a92009-08-20 07:17:43 +00003309 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003310 return SemaRef.Owned(S->Retain());
3311
3312 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregor43959a92009-08-20 07:17:43 +00003313 S->getStartLoc(), S->getEndLoc());
3314}
Mike Stump1eb44332009-09-09 15:08:12 +00003315
Douglas Gregor43959a92009-08-20 07:17:43 +00003316template<typename Derived>
3317Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003318TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003319 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00003320 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003321}
3322
3323template<typename Derived>
3324Sema::OwningStmtResult
3325TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3326 // FIXME: Implement!
3327 assert(false && "Inline assembly cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00003328 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003329}
3330
3331
3332template<typename Derived>
3333Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003334TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003335 // FIXME: Implement this
3336 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003337 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003338}
Mike Stump1eb44332009-09-09 15:08:12 +00003339
Douglas Gregor43959a92009-08-20 07:17:43 +00003340template<typename Derived>
3341Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003342TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003343 // FIXME: Implement this
3344 assert(false && "Cannot transform an Objective-C @catch statement");
3345 return SemaRef.Owned(S->Retain());
3346}
Mike Stump1eb44332009-09-09 15:08:12 +00003347
Douglas Gregor43959a92009-08-20 07:17:43 +00003348template<typename Derived>
3349Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003350TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003351 // FIXME: Implement this
3352 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003353 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003354}
Mike Stump1eb44332009-09-09 15:08:12 +00003355
Douglas Gregor43959a92009-08-20 07:17:43 +00003356template<typename Derived>
3357Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003358TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003359 // FIXME: Implement this
3360 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003361 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003362}
Mike Stump1eb44332009-09-09 15:08:12 +00003363
Douglas Gregor43959a92009-08-20 07:17:43 +00003364template<typename Derived>
3365Sema::OwningStmtResult
3366TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00003367 ObjCAtSynchronizedStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003368 // FIXME: Implement this
3369 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003370 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003371}
3372
3373template<typename Derived>
3374Sema::OwningStmtResult
3375TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00003376 ObjCForCollectionStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003377 // FIXME: Implement this
3378 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003379 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003380}
3381
3382
3383template<typename Derived>
3384Sema::OwningStmtResult
3385TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3386 // Transform the exception declaration, if any.
3387 VarDecl *Var = 0;
3388 if (S->getExceptionDecl()) {
3389 VarDecl *ExceptionDecl = S->getExceptionDecl();
3390 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3391 ExceptionDecl->getDeclName());
3392
3393 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3394 if (T.isNull())
3395 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003396
Douglas Gregor43959a92009-08-20 07:17:43 +00003397 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3398 T,
3399 ExceptionDecl->getDeclaratorInfo(),
3400 ExceptionDecl->getIdentifier(),
3401 ExceptionDecl->getLocation(),
3402 /*FIXME: Inaccurate*/
3403 SourceRange(ExceptionDecl->getLocation()));
3404 if (!Var || Var->isInvalidDecl()) {
3405 if (Var)
3406 Var->Destroy(SemaRef.Context);
3407 return SemaRef.StmtError();
3408 }
3409 }
Mike Stump1eb44332009-09-09 15:08:12 +00003410
Douglas Gregor43959a92009-08-20 07:17:43 +00003411 // Transform the actual exception handler.
3412 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3413 if (Handler.isInvalid()) {
3414 if (Var)
3415 Var->Destroy(SemaRef.Context);
3416 return SemaRef.StmtError();
3417 }
Mike Stump1eb44332009-09-09 15:08:12 +00003418
Douglas Gregor43959a92009-08-20 07:17:43 +00003419 if (!getDerived().AlwaysRebuild() &&
3420 !Var &&
3421 Handler.get() == S->getHandlerBlock())
Mike Stump1eb44332009-09-09 15:08:12 +00003422 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003423
3424 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3425 Var,
3426 move(Handler));
3427}
Mike Stump1eb44332009-09-09 15:08:12 +00003428
Douglas Gregor43959a92009-08-20 07:17:43 +00003429template<typename Derived>
3430Sema::OwningStmtResult
3431TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3432 // Transform the try block itself.
Mike Stump1eb44332009-09-09 15:08:12 +00003433 OwningStmtResult TryBlock
Douglas Gregor43959a92009-08-20 07:17:43 +00003434 = getDerived().TransformCompoundStmt(S->getTryBlock());
3435 if (TryBlock.isInvalid())
3436 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003437
Douglas Gregor43959a92009-08-20 07:17:43 +00003438 // Transform the handlers.
3439 bool HandlerChanged = false;
3440 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3441 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +00003442 OwningStmtResult Handler
Douglas Gregor43959a92009-08-20 07:17:43 +00003443 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3444 if (Handler.isInvalid())
3445 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003446
Douglas Gregor43959a92009-08-20 07:17:43 +00003447 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3448 Handlers.push_back(Handler.takeAs<Stmt>());
3449 }
Mike Stump1eb44332009-09-09 15:08:12 +00003450
Douglas Gregor43959a92009-08-20 07:17:43 +00003451 if (!getDerived().AlwaysRebuild() &&
3452 TryBlock.get() == S->getTryBlock() &&
3453 !HandlerChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003454 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003455
3456 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump1eb44332009-09-09 15:08:12 +00003457 move_arg(Handlers));
Douglas Gregor43959a92009-08-20 07:17:43 +00003458}
Mike Stump1eb44332009-09-09 15:08:12 +00003459
Douglas Gregor43959a92009-08-20 07:17:43 +00003460//===----------------------------------------------------------------------===//
Douglas Gregorb98b1992009-08-11 05:31:07 +00003461// Expression transformation
3462//===----------------------------------------------------------------------===//
Mike Stump1eb44332009-09-09 15:08:12 +00003463template<typename Derived>
3464Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003465TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E,
3466 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003467 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003468}
Mike Stump1eb44332009-09-09 15:08:12 +00003469
3470template<typename Derived>
3471Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003472TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E,
3473 bool isAddressOfOperand) {
Douglas Gregora2813ce2009-10-23 18:54:35 +00003474 NestedNameSpecifier *Qualifier = 0;
3475 if (E->getQualifier()) {
3476 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3477 E->getQualifierRange());
3478 if (!Qualifier)
3479 return SemaRef.ExprError();
3480 }
3481
Mike Stump1eb44332009-09-09 15:08:12 +00003482 NamedDecl *ND
Douglas Gregorb98b1992009-08-11 05:31:07 +00003483 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3484 if (!ND)
3485 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003486
Douglas Gregora2813ce2009-10-23 18:54:35 +00003487 if (!getDerived().AlwaysRebuild() &&
3488 Qualifier == E->getQualifier() &&
3489 ND == E->getDecl() &&
3490 !E->hasExplicitTemplateArgumentList())
Mike Stump1eb44332009-09-09 15:08:12 +00003491 return SemaRef.Owned(E->Retain());
3492
Douglas Gregora2813ce2009-10-23 18:54:35 +00003493 // FIXME: We're losing the explicit template arguments in this transformation.
3494
John McCall833ca992009-10-29 08:12:44 +00003495 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora2813ce2009-10-23 18:54:35 +00003496 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall833ca992009-10-29 08:12:44 +00003497 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3498 TransArgs[I]))
Douglas Gregora2813ce2009-10-23 18:54:35 +00003499 return SemaRef.ExprError();
Douglas Gregora2813ce2009-10-23 18:54:35 +00003500 }
3501
3502 // FIXME: Pass the qualifier/qualifier range along.
3503 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003504 ND, E->getLocation(),
3505 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003506}
Mike Stump1eb44332009-09-09 15:08:12 +00003507
Douglas Gregorb98b1992009-08-11 05:31:07 +00003508template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003509Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003510TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E,
3511 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003512 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003513}
Mike Stump1eb44332009-09-09 15:08:12 +00003514
Douglas Gregorb98b1992009-08-11 05:31:07 +00003515template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003516Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003517TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E,
3518 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003519 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003520}
Mike Stump1eb44332009-09-09 15:08:12 +00003521
Douglas Gregorb98b1992009-08-11 05:31:07 +00003522template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003523Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003524TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E,
3525 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003526 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003527}
Mike Stump1eb44332009-09-09 15:08:12 +00003528
Douglas Gregorb98b1992009-08-11 05:31:07 +00003529template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003530Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003531TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E,
3532 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003533 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003534}
Mike Stump1eb44332009-09-09 15:08:12 +00003535
Douglas Gregorb98b1992009-08-11 05:31:07 +00003536template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003537Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003538TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E,
3539 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003540 return SemaRef.Owned(E->Retain());
3541}
3542
3543template<typename Derived>
3544Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003545TreeTransform<Derived>::TransformParenExpr(ParenExpr *E,
3546 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003547 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3548 if (SubExpr.isInvalid())
3549 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003550
Douglas Gregorb98b1992009-08-11 05:31:07 +00003551 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003552 return SemaRef.Owned(E->Retain());
3553
3554 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003555 E->getRParen());
3556}
3557
Mike Stump1eb44332009-09-09 15:08:12 +00003558template<typename Derived>
3559Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003560TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E,
3561 bool isAddressOfOperand) {
3562 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr(),
3563 E->getOpcode() == UnaryOperator::AddrOf);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003564 if (SubExpr.isInvalid())
3565 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003566
Douglas Gregorb98b1992009-08-11 05:31:07 +00003567 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003568 return SemaRef.Owned(E->Retain());
3569
Douglas Gregorb98b1992009-08-11 05:31:07 +00003570 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3571 E->getOpcode(),
3572 move(SubExpr));
3573}
Mike Stump1eb44332009-09-09 15:08:12 +00003574
Douglas Gregorb98b1992009-08-11 05:31:07 +00003575template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003576Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003577TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
3578 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003579 if (E->isArgumentType()) {
John McCall5ab75172009-11-04 07:28:41 +00003580 DeclaratorInfo *OldT = E->getArgumentTypeInfo();
Douglas Gregor5557b252009-10-28 00:29:27 +00003581
John McCall5ab75172009-11-04 07:28:41 +00003582 DeclaratorInfo *NewT = getDerived().TransformType(OldT);
3583 if (!NewT)
Douglas Gregorb98b1992009-08-11 05:31:07 +00003584 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003585
John McCall5ab75172009-11-04 07:28:41 +00003586 if (!getDerived().AlwaysRebuild() && OldT == NewT)
Douglas Gregorb98b1992009-08-11 05:31:07 +00003587 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003588
John McCall5ab75172009-11-04 07:28:41 +00003589 return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003590 E->isSizeOf(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003591 E->getSourceRange());
3592 }
Mike Stump1eb44332009-09-09 15:08:12 +00003593
Douglas Gregorb98b1992009-08-11 05:31:07 +00003594 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00003595 {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003596 // C++0x [expr.sizeof]p1:
3597 // The operand is either an expression, which is an unevaluated operand
3598 // [...]
3599 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003600
Douglas Gregorb98b1992009-08-11 05:31:07 +00003601 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3602 if (SubExpr.isInvalid())
3603 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003604
Douglas Gregorb98b1992009-08-11 05:31:07 +00003605 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3606 return SemaRef.Owned(E->Retain());
3607 }
Mike Stump1eb44332009-09-09 15:08:12 +00003608
Douglas Gregorb98b1992009-08-11 05:31:07 +00003609 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3610 E->isSizeOf(),
3611 E->getSourceRange());
3612}
Mike Stump1eb44332009-09-09 15:08:12 +00003613
Douglas Gregorb98b1992009-08-11 05:31:07 +00003614template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003615Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003616TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E,
3617 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003618 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3619 if (LHS.isInvalid())
3620 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003621
Douglas Gregorb98b1992009-08-11 05:31:07 +00003622 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3623 if (RHS.isInvalid())
3624 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003625
3626
Douglas Gregorb98b1992009-08-11 05:31:07 +00003627 if (!getDerived().AlwaysRebuild() &&
3628 LHS.get() == E->getLHS() &&
3629 RHS.get() == E->getRHS())
3630 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003631
Douglas Gregorb98b1992009-08-11 05:31:07 +00003632 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3633 /*FIXME:*/E->getLHS()->getLocStart(),
3634 move(RHS),
3635 E->getRBracketLoc());
3636}
Mike Stump1eb44332009-09-09 15:08:12 +00003637
3638template<typename Derived>
3639Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003640TreeTransform<Derived>::TransformCallExpr(CallExpr *E,
3641 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003642 // Transform the callee.
3643 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3644 if (Callee.isInvalid())
3645 return SemaRef.ExprError();
3646
3647 // Transform arguments.
3648 bool ArgChanged = false;
3649 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3650 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3651 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3652 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3653 if (Arg.isInvalid())
3654 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003655
Douglas Gregorb98b1992009-08-11 05:31:07 +00003656 // FIXME: Wrong source location information for the ','.
3657 FakeCommaLocs.push_back(
3658 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump1eb44332009-09-09 15:08:12 +00003659
3660 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003661 Args.push_back(Arg.takeAs<Expr>());
3662 }
Mike Stump1eb44332009-09-09 15:08:12 +00003663
Douglas Gregorb98b1992009-08-11 05:31:07 +00003664 if (!getDerived().AlwaysRebuild() &&
3665 Callee.get() == E->getCallee() &&
3666 !ArgChanged)
3667 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003668
Douglas Gregorb98b1992009-08-11 05:31:07 +00003669 // FIXME: Wrong source location information for the '('.
Mike Stump1eb44332009-09-09 15:08:12 +00003670 SourceLocation FakeLParenLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003671 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3672 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3673 move_arg(Args),
3674 FakeCommaLocs.data(),
3675 E->getRParenLoc());
3676}
Mike Stump1eb44332009-09-09 15:08:12 +00003677
3678template<typename Derived>
3679Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003680TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
3681 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003682 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3683 if (Base.isInvalid())
3684 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003685
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003686 NestedNameSpecifier *Qualifier = 0;
3687 if (E->hasQualifier()) {
Mike Stump1eb44332009-09-09 15:08:12 +00003688 Qualifier
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003689 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3690 E->getQualifierRange());
Douglas Gregorc4bf26f2009-09-01 00:37:14 +00003691 if (Qualifier == 0)
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003692 return SemaRef.ExprError();
3693 }
Mike Stump1eb44332009-09-09 15:08:12 +00003694
3695 NamedDecl *Member
Douglas Gregorb98b1992009-08-11 05:31:07 +00003696 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3697 if (!Member)
3698 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003699
Douglas Gregorb98b1992009-08-11 05:31:07 +00003700 if (!getDerived().AlwaysRebuild() &&
3701 Base.get() == E->getBase() &&
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003702 Qualifier == E->getQualifier() &&
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003703 Member == E->getMemberDecl() &&
3704 !E->hasExplicitTemplateArgumentList())
Mike Stump1eb44332009-09-09 15:08:12 +00003705 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003706
John McCalld5532b62009-11-23 01:53:49 +00003707 TemplateArgumentListInfo TransArgs;
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003708 if (E->hasExplicitTemplateArgumentList()) {
John McCalld5532b62009-11-23 01:53:49 +00003709 TransArgs.setLAngleLoc(E->getLAngleLoc());
3710 TransArgs.setRAngleLoc(E->getRAngleLoc());
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003711 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCalld5532b62009-11-23 01:53:49 +00003712 TemplateArgumentLoc Loc;
3713 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003714 return SemaRef.ExprError();
John McCalld5532b62009-11-23 01:53:49 +00003715 TransArgs.addArgument(Loc);
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003716 }
3717 }
3718
Douglas Gregorb98b1992009-08-11 05:31:07 +00003719 // FIXME: Bogus source location for the operator
3720 SourceLocation FakeOperatorLoc
3721 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3722
3723 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3724 E->isArrow(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003725 Qualifier,
3726 E->getQualifierRange(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003727 E->getMemberLoc(),
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003728 Member,
John McCalld5532b62009-11-23 01:53:49 +00003729 (E->hasExplicitTemplateArgumentList()
3730 ? &TransArgs : 0),
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003731 0);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003732}
Mike Stump1eb44332009-09-09 15:08:12 +00003733
Douglas Gregorb98b1992009-08-11 05:31:07 +00003734template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003735Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003736TreeTransform<Derived>::TransformCastExpr(CastExpr *E,
3737 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003738 assert(false && "Cannot transform abstract class");
3739 return SemaRef.Owned(E->Retain());
3740}
3741
3742template<typename Derived>
3743Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003744TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E,
3745 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003746 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3747 if (LHS.isInvalid())
3748 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003749
Douglas Gregorb98b1992009-08-11 05:31:07 +00003750 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3751 if (RHS.isInvalid())
3752 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003753
Douglas Gregorb98b1992009-08-11 05:31:07 +00003754 if (!getDerived().AlwaysRebuild() &&
3755 LHS.get() == E->getLHS() &&
3756 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00003757 return SemaRef.Owned(E->Retain());
3758
Douglas Gregorb98b1992009-08-11 05:31:07 +00003759 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3760 move(LHS), move(RHS));
3761}
3762
Mike Stump1eb44332009-09-09 15:08:12 +00003763template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003764Sema::OwningExprResult
3765TreeTransform<Derived>::TransformCompoundAssignOperator(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003766 CompoundAssignOperator *E,
3767 bool isAddressOfOperand) {
3768 return getDerived().TransformBinaryOperator(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003769}
Mike Stump1eb44332009-09-09 15:08:12 +00003770
Douglas Gregorb98b1992009-08-11 05:31:07 +00003771template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003772Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003773TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E,
3774 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003775 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3776 if (Cond.isInvalid())
3777 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003778
Douglas Gregorb98b1992009-08-11 05:31:07 +00003779 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3780 if (LHS.isInvalid())
3781 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003782
Douglas Gregorb98b1992009-08-11 05:31:07 +00003783 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3784 if (RHS.isInvalid())
3785 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003786
Douglas Gregorb98b1992009-08-11 05:31:07 +00003787 if (!getDerived().AlwaysRebuild() &&
3788 Cond.get() == E->getCond() &&
3789 LHS.get() == E->getLHS() &&
3790 RHS.get() == E->getRHS())
3791 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003792
3793 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003794 E->getQuestionLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003795 move(LHS),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003796 E->getColonLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003797 move(RHS));
3798}
Mike Stump1eb44332009-09-09 15:08:12 +00003799
3800template<typename Derived>
3801Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003802TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E,
3803 bool isAddressOfOperand) {
Douglas Gregor5557b252009-10-28 00:29:27 +00003804 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3805
3806 // FIXME: Will we ever have type information here? It seems like we won't,
3807 // so do we even need to transform the type?
Douglas Gregorb98b1992009-08-11 05:31:07 +00003808 QualType T = getDerived().TransformType(E->getType());
3809 if (T.isNull())
3810 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003811
Douglas Gregorb98b1992009-08-11 05:31:07 +00003812 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3813 if (SubExpr.isInvalid())
3814 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003815
Douglas Gregorb98b1992009-08-11 05:31:07 +00003816 if (!getDerived().AlwaysRebuild() &&
3817 T == E->getType() &&
3818 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003819 return SemaRef.Owned(E->Retain());
3820
Douglas Gregorb98b1992009-08-11 05:31:07 +00003821 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump1eb44332009-09-09 15:08:12 +00003822 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003823 E->isLvalueCast());
3824}
Mike Stump1eb44332009-09-09 15:08:12 +00003825
Douglas Gregorb98b1992009-08-11 05:31:07 +00003826template<typename Derived>
3827Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003828TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E,
3829 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003830 assert(false && "Cannot transform abstract class");
3831 return SemaRef.Owned(E->Retain());
3832}
3833
3834template<typename Derived>
3835Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003836TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E,
3837 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003838 QualType T;
3839 {
3840 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003841 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003842 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3843 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003844
Douglas Gregorb98b1992009-08-11 05:31:07 +00003845 T = getDerived().TransformType(E->getTypeAsWritten());
3846 if (T.isNull())
3847 return SemaRef.ExprError();
3848 }
Mike Stump1eb44332009-09-09 15:08:12 +00003849
Douglas Gregorb98b1992009-08-11 05:31:07 +00003850 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3851 if (SubExpr.isInvalid())
3852 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003853
Douglas Gregorb98b1992009-08-11 05:31:07 +00003854 if (!getDerived().AlwaysRebuild() &&
3855 T == E->getTypeAsWritten() &&
3856 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003857 return SemaRef.Owned(E->Retain());
3858
Douglas Gregorb98b1992009-08-11 05:31:07 +00003859 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3860 E->getRParenLoc(),
3861 move(SubExpr));
3862}
Mike Stump1eb44332009-09-09 15:08:12 +00003863
Douglas Gregorb98b1992009-08-11 05:31:07 +00003864template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003865Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003866TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E,
3867 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003868 QualType T;
3869 {
3870 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003871 SourceLocation FakeTypeLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003872 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3873 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003874
Douglas Gregorb98b1992009-08-11 05:31:07 +00003875 T = getDerived().TransformType(E->getType());
3876 if (T.isNull())
3877 return SemaRef.ExprError();
3878 }
Mike Stump1eb44332009-09-09 15:08:12 +00003879
Douglas Gregorb98b1992009-08-11 05:31:07 +00003880 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3881 if (Init.isInvalid())
3882 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003883
Douglas Gregorb98b1992009-08-11 05:31:07 +00003884 if (!getDerived().AlwaysRebuild() &&
3885 T == E->getType() &&
3886 Init.get() == E->getInitializer())
Mike Stump1eb44332009-09-09 15:08:12 +00003887 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003888
3889 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3890 /*FIXME:*/E->getInitializer()->getLocEnd(),
3891 move(Init));
3892}
Mike Stump1eb44332009-09-09 15:08:12 +00003893
Douglas Gregorb98b1992009-08-11 05:31:07 +00003894template<typename Derived>
3895Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003896TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E,
3897 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003898 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3899 if (Base.isInvalid())
3900 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003901
Douglas Gregorb98b1992009-08-11 05:31:07 +00003902 if (!getDerived().AlwaysRebuild() &&
3903 Base.get() == E->getBase())
Mike Stump1eb44332009-09-09 15:08:12 +00003904 return SemaRef.Owned(E->Retain());
3905
Douglas Gregorb98b1992009-08-11 05:31:07 +00003906 // FIXME: Bad source location
Mike Stump1eb44332009-09-09 15:08:12 +00003907 SourceLocation FakeOperatorLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003908 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3909 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3910 E->getAccessorLoc(),
3911 E->getAccessor());
3912}
Mike Stump1eb44332009-09-09 15:08:12 +00003913
Douglas Gregorb98b1992009-08-11 05:31:07 +00003914template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003915Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003916TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E,
3917 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003918 bool InitChanged = false;
Mike Stump1eb44332009-09-09 15:08:12 +00003919
Douglas Gregorb98b1992009-08-11 05:31:07 +00003920 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3921 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3922 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3923 if (Init.isInvalid())
3924 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003925
Douglas Gregorb98b1992009-08-11 05:31:07 +00003926 InitChanged = InitChanged || Init.get() != E->getInit(I);
3927 Inits.push_back(Init.takeAs<Expr>());
3928 }
Mike Stump1eb44332009-09-09 15:08:12 +00003929
Douglas Gregorb98b1992009-08-11 05:31:07 +00003930 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003931 return SemaRef.Owned(E->Retain());
3932
Douglas Gregorb98b1992009-08-11 05:31:07 +00003933 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
Douglas Gregore48319a2009-11-09 17:16:50 +00003934 E->getRBraceLoc(), E->getType());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003935}
Mike Stump1eb44332009-09-09 15:08:12 +00003936
Douglas Gregorb98b1992009-08-11 05:31:07 +00003937template<typename Derived>
3938Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003939TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E,
3940 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003941 Designation Desig;
Mike Stump1eb44332009-09-09 15:08:12 +00003942
Douglas Gregor43959a92009-08-20 07:17:43 +00003943 // transform the initializer value
Douglas Gregorb98b1992009-08-11 05:31:07 +00003944 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3945 if (Init.isInvalid())
3946 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003947
Douglas Gregor43959a92009-08-20 07:17:43 +00003948 // transform the designators.
Douglas Gregorb98b1992009-08-11 05:31:07 +00003949 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3950 bool ExprChanged = false;
3951 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3952 DEnd = E->designators_end();
3953 D != DEnd; ++D) {
3954 if (D->isFieldDesignator()) {
3955 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3956 D->getDotLoc(),
3957 D->getFieldLoc()));
3958 continue;
3959 }
Mike Stump1eb44332009-09-09 15:08:12 +00003960
Douglas Gregorb98b1992009-08-11 05:31:07 +00003961 if (D->isArrayDesignator()) {
3962 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3963 if (Index.isInvalid())
3964 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003965
3966 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003967 D->getLBracketLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003968
Douglas Gregorb98b1992009-08-11 05:31:07 +00003969 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3970 ArrayExprs.push_back(Index.release());
3971 continue;
3972 }
Mike Stump1eb44332009-09-09 15:08:12 +00003973
Douglas Gregorb98b1992009-08-11 05:31:07 +00003974 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump1eb44332009-09-09 15:08:12 +00003975 OwningExprResult Start
Douglas Gregorb98b1992009-08-11 05:31:07 +00003976 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3977 if (Start.isInvalid())
3978 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003979
Douglas Gregorb98b1992009-08-11 05:31:07 +00003980 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3981 if (End.isInvalid())
3982 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003983
3984 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003985 End.get(),
3986 D->getLBracketLoc(),
3987 D->getEllipsisLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003988
Douglas Gregorb98b1992009-08-11 05:31:07 +00003989 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3990 End.get() != E->getArrayRangeEnd(*D);
Mike Stump1eb44332009-09-09 15:08:12 +00003991
Douglas Gregorb98b1992009-08-11 05:31:07 +00003992 ArrayExprs.push_back(Start.release());
3993 ArrayExprs.push_back(End.release());
3994 }
Mike Stump1eb44332009-09-09 15:08:12 +00003995
Douglas Gregorb98b1992009-08-11 05:31:07 +00003996 if (!getDerived().AlwaysRebuild() &&
3997 Init.get() == E->getInit() &&
3998 !ExprChanged)
3999 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004000
Douglas Gregorb98b1992009-08-11 05:31:07 +00004001 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
4002 E->getEqualOrColonLoc(),
4003 E->usesGNUSyntax(), move(Init));
4004}
Mike Stump1eb44332009-09-09 15:08:12 +00004005
Douglas Gregorb98b1992009-08-11 05:31:07 +00004006template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004007Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00004008TreeTransform<Derived>::TransformImplicitValueInitExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004009 ImplicitValueInitExpr *E,
4010 bool isAddressOfOperand) {
Douglas Gregor5557b252009-10-28 00:29:27 +00004011 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4012
4013 // FIXME: Will we ever have proper type location here? Will we actually
4014 // need to transform the type?
Douglas Gregorb98b1992009-08-11 05:31:07 +00004015 QualType T = getDerived().TransformType(E->getType());
4016 if (T.isNull())
4017 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004018
Douglas Gregorb98b1992009-08-11 05:31:07 +00004019 if (!getDerived().AlwaysRebuild() &&
4020 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00004021 return SemaRef.Owned(E->Retain());
4022
Douglas Gregorb98b1992009-08-11 05:31:07 +00004023 return getDerived().RebuildImplicitValueInitExpr(T);
4024}
Mike Stump1eb44332009-09-09 15:08:12 +00004025
Douglas Gregorb98b1992009-08-11 05:31:07 +00004026template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004027Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004028TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E,
4029 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004030 // FIXME: Do we want the type as written?
4031 QualType T;
Mike Stump1eb44332009-09-09 15:08:12 +00004032
Douglas Gregorb98b1992009-08-11 05:31:07 +00004033 {
4034 // FIXME: Source location isn't quite accurate.
4035 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
4036 T = getDerived().TransformType(E->getType());
4037 if (T.isNull())
4038 return SemaRef.ExprError();
4039 }
Mike Stump1eb44332009-09-09 15:08:12 +00004040
Douglas Gregorb98b1992009-08-11 05:31:07 +00004041 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4042 if (SubExpr.isInvalid())
4043 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004044
Douglas Gregorb98b1992009-08-11 05:31:07 +00004045 if (!getDerived().AlwaysRebuild() &&
4046 T == E->getType() &&
4047 SubExpr.get() == E->getSubExpr())
4048 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004049
Douglas Gregorb98b1992009-08-11 05:31:07 +00004050 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
4051 T, E->getRParenLoc());
4052}
4053
4054template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004055Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004056TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E,
4057 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004058 bool ArgumentChanged = false;
4059 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
4060 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
4061 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
4062 if (Init.isInvalid())
4063 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004064
Douglas Gregorb98b1992009-08-11 05:31:07 +00004065 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
4066 Inits.push_back(Init.takeAs<Expr>());
4067 }
Mike Stump1eb44332009-09-09 15:08:12 +00004068
Douglas Gregorb98b1992009-08-11 05:31:07 +00004069 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
4070 move_arg(Inits),
4071 E->getRParenLoc());
4072}
Mike Stump1eb44332009-09-09 15:08:12 +00004073
Douglas Gregorb98b1992009-08-11 05:31:07 +00004074/// \brief Transform an address-of-label expression.
4075///
4076/// By default, the transformation of an address-of-label expression always
4077/// rebuilds the expression, so that the label identifier can be resolved to
4078/// the corresponding label statement by semantic analysis.
4079template<typename Derived>
4080Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004081TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E,
4082 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004083 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
4084 E->getLabel());
4085}
Mike Stump1eb44332009-09-09 15:08:12 +00004086
4087template<typename Derived>
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004088Sema::OwningExprResult
4089TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E,
4090 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004091 OwningStmtResult SubStmt
Douglas Gregorb98b1992009-08-11 05:31:07 +00004092 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
4093 if (SubStmt.isInvalid())
4094 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004095
Douglas Gregorb98b1992009-08-11 05:31:07 +00004096 if (!getDerived().AlwaysRebuild() &&
4097 SubStmt.get() == E->getSubStmt())
4098 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004099
4100 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004101 move(SubStmt),
4102 E->getRParenLoc());
4103}
Mike Stump1eb44332009-09-09 15:08:12 +00004104
Douglas Gregorb98b1992009-08-11 05:31:07 +00004105template<typename Derived>
4106Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004107TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E,
4108 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004109 QualType T1, T2;
4110 {
4111 // FIXME: Source location isn't quite accurate.
4112 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004113
Douglas Gregorb98b1992009-08-11 05:31:07 +00004114 T1 = getDerived().TransformType(E->getArgType1());
4115 if (T1.isNull())
4116 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004117
Douglas Gregorb98b1992009-08-11 05:31:07 +00004118 T2 = getDerived().TransformType(E->getArgType2());
4119 if (T2.isNull())
4120 return SemaRef.ExprError();
4121 }
4122
4123 if (!getDerived().AlwaysRebuild() &&
4124 T1 == E->getArgType1() &&
4125 T2 == E->getArgType2())
Mike Stump1eb44332009-09-09 15:08:12 +00004126 return SemaRef.Owned(E->Retain());
4127
Douglas Gregorb98b1992009-08-11 05:31:07 +00004128 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
4129 T1, T2, E->getRParenLoc());
4130}
Mike Stump1eb44332009-09-09 15:08:12 +00004131
Douglas Gregorb98b1992009-08-11 05:31:07 +00004132template<typename Derived>
4133Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004134TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E,
4135 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004136 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4137 if (Cond.isInvalid())
4138 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004139
Douglas Gregorb98b1992009-08-11 05:31:07 +00004140 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4141 if (LHS.isInvalid())
4142 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004143
Douglas Gregorb98b1992009-08-11 05:31:07 +00004144 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4145 if (RHS.isInvalid())
4146 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004147
Douglas Gregorb98b1992009-08-11 05:31:07 +00004148 if (!getDerived().AlwaysRebuild() &&
4149 Cond.get() == E->getCond() &&
4150 LHS.get() == E->getLHS() &&
4151 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00004152 return SemaRef.Owned(E->Retain());
4153
Douglas Gregorb98b1992009-08-11 05:31:07 +00004154 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4155 move(Cond), move(LHS), move(RHS),
4156 E->getRParenLoc());
4157}
Mike Stump1eb44332009-09-09 15:08:12 +00004158
Douglas Gregorb98b1992009-08-11 05:31:07 +00004159template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004160Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004161TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E,
4162 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004163 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004164}
4165
4166template<typename Derived>
4167Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004168TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E,
4169 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004170 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4171 if (Callee.isInvalid())
4172 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004173
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004174 OwningExprResult First
4175 = getDerived().TransformExpr(E->getArg(0),
4176 E->getNumArgs() == 1 && E->getOperator() == OO_Amp);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004177 if (First.isInvalid())
4178 return SemaRef.ExprError();
4179
4180 OwningExprResult Second(SemaRef);
4181 if (E->getNumArgs() == 2) {
4182 Second = getDerived().TransformExpr(E->getArg(1));
4183 if (Second.isInvalid())
4184 return SemaRef.ExprError();
4185 }
Mike Stump1eb44332009-09-09 15:08:12 +00004186
Douglas Gregorb98b1992009-08-11 05:31:07 +00004187 if (!getDerived().AlwaysRebuild() &&
4188 Callee.get() == E->getCallee() &&
4189 First.get() == E->getArg(0) &&
Mike Stump1eb44332009-09-09 15:08:12 +00004190 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4191 return SemaRef.Owned(E->Retain());
4192
Douglas Gregorb98b1992009-08-11 05:31:07 +00004193 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4194 E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00004195 move(Callee),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004196 move(First),
4197 move(Second));
4198}
Mike Stump1eb44332009-09-09 15:08:12 +00004199
Douglas Gregorb98b1992009-08-11 05:31:07 +00004200template<typename Derived>
4201Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004202TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E,
4203 bool isAddressOfOperand) {
4204 return getDerived().TransformCallExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004205}
Mike Stump1eb44332009-09-09 15:08:12 +00004206
Douglas Gregorb98b1992009-08-11 05:31:07 +00004207template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004208Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004209TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E,
4210 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004211 QualType ExplicitTy;
4212 {
4213 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00004214 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004215 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4216 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004217
Douglas Gregorb98b1992009-08-11 05:31:07 +00004218 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4219 if (ExplicitTy.isNull())
4220 return SemaRef.ExprError();
4221 }
Mike Stump1eb44332009-09-09 15:08:12 +00004222
Douglas Gregorb98b1992009-08-11 05:31:07 +00004223 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4224 if (SubExpr.isInvalid())
4225 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004226
Douglas Gregorb98b1992009-08-11 05:31:07 +00004227 if (!getDerived().AlwaysRebuild() &&
4228 ExplicitTy == E->getTypeAsWritten() &&
4229 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004230 return SemaRef.Owned(E->Retain());
4231
Douglas Gregorb98b1992009-08-11 05:31:07 +00004232 // FIXME: Poor source location information here.
Mike Stump1eb44332009-09-09 15:08:12 +00004233 SourceLocation FakeLAngleLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004234 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4235 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4236 SourceLocation FakeRParenLoc
4237 = SemaRef.PP.getLocForEndOfToken(
4238 E->getSubExpr()->getSourceRange().getEnd());
4239 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00004240 E->getStmtClass(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004241 FakeLAngleLoc,
4242 ExplicitTy,
4243 FakeRAngleLoc,
4244 FakeRAngleLoc,
4245 move(SubExpr),
4246 FakeRParenLoc);
4247}
Mike Stump1eb44332009-09-09 15:08:12 +00004248
Douglas Gregorb98b1992009-08-11 05:31:07 +00004249template<typename Derived>
4250Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004251TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E,
4252 bool isAddressOfOperand) {
4253 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004254}
Mike Stump1eb44332009-09-09 15:08:12 +00004255
4256template<typename Derived>
4257Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004258TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E,
4259 bool isAddressOfOperand) {
4260 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Mike Stump1eb44332009-09-09 15:08:12 +00004261}
4262
Douglas Gregorb98b1992009-08-11 05:31:07 +00004263template<typename Derived>
4264Sema::OwningExprResult
4265TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004266 CXXReinterpretCastExpr *E,
4267 bool isAddressOfOperand) {
4268 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004269}
Mike Stump1eb44332009-09-09 15:08:12 +00004270
Douglas Gregorb98b1992009-08-11 05:31:07 +00004271template<typename Derived>
4272Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004273TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E,
4274 bool isAddressOfOperand) {
4275 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004276}
Mike Stump1eb44332009-09-09 15:08:12 +00004277
Douglas Gregorb98b1992009-08-11 05:31:07 +00004278template<typename Derived>
4279Sema::OwningExprResult
4280TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004281 CXXFunctionalCastExpr *E,
4282 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004283 QualType ExplicitTy;
4284 {
4285 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004286
Douglas Gregorb98b1992009-08-11 05:31:07 +00004287 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4288 if (ExplicitTy.isNull())
4289 return SemaRef.ExprError();
4290 }
Mike Stump1eb44332009-09-09 15:08:12 +00004291
Douglas Gregorb98b1992009-08-11 05:31:07 +00004292 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4293 if (SubExpr.isInvalid())
4294 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004295
Douglas Gregorb98b1992009-08-11 05:31:07 +00004296 if (!getDerived().AlwaysRebuild() &&
4297 ExplicitTy == E->getTypeAsWritten() &&
4298 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004299 return SemaRef.Owned(E->Retain());
4300
Douglas Gregorb98b1992009-08-11 05:31:07 +00004301 // FIXME: The end of the type's source range is wrong
4302 return getDerived().RebuildCXXFunctionalCastExpr(
4303 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4304 ExplicitTy,
4305 /*FIXME:*/E->getSubExpr()->getLocStart(),
4306 move(SubExpr),
4307 E->getRParenLoc());
4308}
Mike Stump1eb44332009-09-09 15:08:12 +00004309
Douglas Gregorb98b1992009-08-11 05:31:07 +00004310template<typename Derived>
4311Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004312TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E,
4313 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004314 if (E->isTypeOperand()) {
4315 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004316
Douglas Gregorb98b1992009-08-11 05:31:07 +00004317 QualType T = getDerived().TransformType(E->getTypeOperand());
4318 if (T.isNull())
4319 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004320
Douglas Gregorb98b1992009-08-11 05:31:07 +00004321 if (!getDerived().AlwaysRebuild() &&
4322 T == E->getTypeOperand())
4323 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004324
Douglas Gregorb98b1992009-08-11 05:31:07 +00004325 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4326 /*FIXME:*/E->getLocStart(),
4327 T,
4328 E->getLocEnd());
4329 }
Mike Stump1eb44332009-09-09 15:08:12 +00004330
Douglas Gregorb98b1992009-08-11 05:31:07 +00004331 // We don't know whether the expression is potentially evaluated until
4332 // after we perform semantic analysis, so the expression is potentially
4333 // potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00004334 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004335 Action::PotentiallyPotentiallyEvaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00004336
Douglas Gregorb98b1992009-08-11 05:31:07 +00004337 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4338 if (SubExpr.isInvalid())
4339 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004340
Douglas Gregorb98b1992009-08-11 05:31:07 +00004341 if (!getDerived().AlwaysRebuild() &&
4342 SubExpr.get() == E->getExprOperand())
Mike Stump1eb44332009-09-09 15:08:12 +00004343 return SemaRef.Owned(E->Retain());
4344
Douglas Gregorb98b1992009-08-11 05:31:07 +00004345 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4346 /*FIXME:*/E->getLocStart(),
4347 move(SubExpr),
4348 E->getLocEnd());
4349}
4350
4351template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004352Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004353TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E,
4354 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004355 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004356}
Mike Stump1eb44332009-09-09 15:08:12 +00004357
Douglas Gregorb98b1992009-08-11 05:31:07 +00004358template<typename Derived>
4359Sema::OwningExprResult
4360TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004361 CXXNullPtrLiteralExpr *E,
4362 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004363 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004364}
Mike Stump1eb44332009-09-09 15:08:12 +00004365
Douglas Gregorb98b1992009-08-11 05:31:07 +00004366template<typename Derived>
4367Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004368TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E,
4369 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004370 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004371
Douglas Gregorb98b1992009-08-11 05:31:07 +00004372 QualType T = getDerived().TransformType(E->getType());
4373 if (T.isNull())
4374 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004375
Douglas Gregorb98b1992009-08-11 05:31:07 +00004376 if (!getDerived().AlwaysRebuild() &&
4377 T == E->getType())
4378 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004379
Douglas Gregorb98b1992009-08-11 05:31:07 +00004380 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4381}
Mike Stump1eb44332009-09-09 15:08:12 +00004382
Douglas Gregorb98b1992009-08-11 05:31:07 +00004383template<typename Derived>
4384Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004385TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E,
4386 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004387 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4388 if (SubExpr.isInvalid())
4389 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004390
Douglas Gregorb98b1992009-08-11 05:31:07 +00004391 if (!getDerived().AlwaysRebuild() &&
4392 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004393 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004394
4395 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4396}
Mike Stump1eb44332009-09-09 15:08:12 +00004397
Douglas Gregorb98b1992009-08-11 05:31:07 +00004398template<typename Derived>
4399Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004400TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
4401 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004402 ParmVarDecl *Param
Douglas Gregorb98b1992009-08-11 05:31:07 +00004403 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4404 if (!Param)
4405 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004406
Douglas Gregorb98b1992009-08-11 05:31:07 +00004407 if (getDerived().AlwaysRebuild() &&
4408 Param == E->getParam())
4409 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004410
Douglas Gregorb98b1992009-08-11 05:31:07 +00004411 return getDerived().RebuildCXXDefaultArgExpr(Param);
4412}
Mike Stump1eb44332009-09-09 15:08:12 +00004413
Douglas Gregorb98b1992009-08-11 05:31:07 +00004414template<typename Derived>
4415Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004416TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E,
4417 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004418 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4419
4420 QualType T = getDerived().TransformType(E->getType());
4421 if (T.isNull())
4422 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004423
Douglas Gregorb98b1992009-08-11 05:31:07 +00004424 if (!getDerived().AlwaysRebuild() &&
4425 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00004426 return SemaRef.Owned(E->Retain());
4427
4428 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004429 /*FIXME:*/E->getTypeBeginLoc(),
4430 T,
4431 E->getRParenLoc());
4432}
Mike Stump1eb44332009-09-09 15:08:12 +00004433
Douglas Gregorb98b1992009-08-11 05:31:07 +00004434template<typename Derived>
4435Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004436TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E,
4437 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004438 // Transform the type that we're allocating
4439 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4440 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4441 if (AllocType.isNull())
4442 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004443
Douglas Gregorb98b1992009-08-11 05:31:07 +00004444 // Transform the size of the array we're allocating (if any).
4445 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4446 if (ArraySize.isInvalid())
4447 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004448
Douglas Gregorb98b1992009-08-11 05:31:07 +00004449 // Transform the placement arguments (if any).
4450 bool ArgumentChanged = false;
4451 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4452 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4453 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4454 if (Arg.isInvalid())
4455 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004456
Douglas Gregorb98b1992009-08-11 05:31:07 +00004457 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4458 PlacementArgs.push_back(Arg.take());
4459 }
Mike Stump1eb44332009-09-09 15:08:12 +00004460
Douglas Gregor43959a92009-08-20 07:17:43 +00004461 // transform the constructor arguments (if any).
Douglas Gregorb98b1992009-08-11 05:31:07 +00004462 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4463 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4464 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4465 if (Arg.isInvalid())
4466 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004467
Douglas Gregorb98b1992009-08-11 05:31:07 +00004468 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4469 ConstructorArgs.push_back(Arg.take());
4470 }
Mike Stump1eb44332009-09-09 15:08:12 +00004471
Douglas Gregorb98b1992009-08-11 05:31:07 +00004472 if (!getDerived().AlwaysRebuild() &&
4473 AllocType == E->getAllocatedType() &&
4474 ArraySize.get() == E->getArraySize() &&
4475 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004476 return SemaRef.Owned(E->Retain());
4477
Douglas Gregorb98b1992009-08-11 05:31:07 +00004478 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4479 E->isGlobalNew(),
4480 /*FIXME:*/E->getLocStart(),
4481 move_arg(PlacementArgs),
4482 /*FIXME:*/E->getLocStart(),
4483 E->isParenTypeId(),
4484 AllocType,
4485 /*FIXME:*/E->getLocStart(),
4486 /*FIXME:*/SourceRange(),
4487 move(ArraySize),
4488 /*FIXME:*/E->getLocStart(),
4489 move_arg(ConstructorArgs),
Mike Stump1eb44332009-09-09 15:08:12 +00004490 E->getLocEnd());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004491}
Mike Stump1eb44332009-09-09 15:08:12 +00004492
Douglas Gregorb98b1992009-08-11 05:31:07 +00004493template<typename Derived>
4494Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004495TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E,
4496 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004497 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4498 if (Operand.isInvalid())
4499 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004500
Douglas Gregorb98b1992009-08-11 05:31:07 +00004501 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00004502 Operand.get() == E->getArgument())
4503 return SemaRef.Owned(E->Retain());
4504
Douglas Gregorb98b1992009-08-11 05:31:07 +00004505 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4506 E->isGlobalDelete(),
4507 E->isArrayForm(),
4508 move(Operand));
4509}
Mike Stump1eb44332009-09-09 15:08:12 +00004510
Douglas Gregorb98b1992009-08-11 05:31:07 +00004511template<typename Derived>
4512Sema::OwningExprResult
Douglas Gregora71d8192009-09-04 17:36:40 +00004513TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004514 CXXPseudoDestructorExpr *E,
4515 bool isAddressOfOperand) {
Douglas Gregora71d8192009-09-04 17:36:40 +00004516 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4517 if (Base.isInvalid())
4518 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004519
Douglas Gregora71d8192009-09-04 17:36:40 +00004520 NestedNameSpecifier *Qualifier
4521 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4522 E->getQualifierRange());
4523 if (E->getQualifier() && !Qualifier)
4524 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004525
Douglas Gregora71d8192009-09-04 17:36:40 +00004526 QualType DestroyedType;
4527 {
4528 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4529 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4530 if (DestroyedType.isNull())
4531 return SemaRef.ExprError();
4532 }
Mike Stump1eb44332009-09-09 15:08:12 +00004533
Douglas Gregora71d8192009-09-04 17:36:40 +00004534 if (!getDerived().AlwaysRebuild() &&
4535 Base.get() == E->getBase() &&
4536 Qualifier == E->getQualifier() &&
4537 DestroyedType == E->getDestroyedType())
4538 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004539
Douglas Gregora71d8192009-09-04 17:36:40 +00004540 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4541 E->getOperatorLoc(),
4542 E->isArrow(),
4543 E->getDestroyedTypeLoc(),
4544 DestroyedType,
4545 Qualifier,
4546 E->getQualifierRange());
4547}
Mike Stump1eb44332009-09-09 15:08:12 +00004548
Douglas Gregora71d8192009-09-04 17:36:40 +00004549template<typename Derived>
4550Sema::OwningExprResult
John McCallba135432009-11-21 08:51:07 +00004551TreeTransform<Derived>::TransformUnresolvedLookupExpr(
John McCallf7a1a742009-11-24 19:00:30 +00004552 UnresolvedLookupExpr *Old,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004553 bool isAddressOfOperand) {
John McCallf7a1a742009-11-24 19:00:30 +00004554 TemporaryBase Rebase(*this, Old->getNameLoc(), DeclarationName());
4555
4556 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
4557 Sema::LookupOrdinaryName);
4558
4559 // Transform all the decls.
4560 for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
4561 E = Old->decls_end(); I != E; ++I) {
4562 NamedDecl *InstD = static_cast<NamedDecl*>(getDerived().TransformDecl(*I));
4563 if (!InstD)
4564 return SemaRef.ExprError();
4565
4566 // Expand using declarations.
4567 if (isa<UsingDecl>(InstD)) {
4568 UsingDecl *UD = cast<UsingDecl>(InstD);
4569 for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
4570 E = UD->shadow_end(); I != E; ++I)
4571 R.addDecl(*I);
4572 continue;
4573 }
4574
4575 R.addDecl(InstD);
4576 }
4577
4578 // Resolve a kind, but don't do any further analysis. If it's
4579 // ambiguous, the callee needs to deal with it.
4580 R.resolveKind();
4581
4582 // Rebuild the nested-name qualifier, if present.
4583 CXXScopeSpec SS;
4584 NestedNameSpecifier *Qualifier = 0;
4585 if (Old->getQualifier()) {
4586 Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
4587 Old->getQualifierRange());
4588 if (!Qualifier)
4589 return SemaRef.ExprError();
4590
4591 SS.setScopeRep(Qualifier);
4592 SS.setRange(Old->getQualifierRange());
4593 }
4594
4595 // If we have no template arguments, it's a normal declaration name.
4596 if (!Old->hasExplicitTemplateArgs())
4597 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
4598
4599 // If we have template arguments, rebuild them, then rebuild the
4600 // templateid expression.
4601 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
4602 for (unsigned I = 0, N = Old->getNumTemplateArgs(); I != N; ++I) {
4603 TemplateArgumentLoc Loc;
4604 if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I], Loc))
4605 return SemaRef.ExprError();
4606 TransArgs.addArgument(Loc);
4607 }
4608
4609 return getDerived().RebuildTemplateIdExpr(SS, R, Old->requiresADL(),
4610 TransArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004611}
Mike Stump1eb44332009-09-09 15:08:12 +00004612
Douglas Gregorb98b1992009-08-11 05:31:07 +00004613template<typename Derived>
4614Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004615TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E,
4616 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004617 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004618
Douglas Gregorb98b1992009-08-11 05:31:07 +00004619 QualType T = getDerived().TransformType(E->getQueriedType());
4620 if (T.isNull())
4621 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004622
Douglas Gregorb98b1992009-08-11 05:31:07 +00004623 if (!getDerived().AlwaysRebuild() &&
4624 T == E->getQueriedType())
4625 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004626
Douglas Gregorb98b1992009-08-11 05:31:07 +00004627 // FIXME: Bad location information
4628 SourceLocation FakeLParenLoc
4629 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump1eb44332009-09-09 15:08:12 +00004630
4631 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004632 E->getLocStart(),
4633 /*FIXME:*/FakeLParenLoc,
4634 T,
4635 E->getLocEnd());
4636}
Mike Stump1eb44332009-09-09 15:08:12 +00004637
Douglas Gregorb98b1992009-08-11 05:31:07 +00004638template<typename Derived>
4639Sema::OwningExprResult
John McCall865d4472009-11-19 22:55:06 +00004640TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
4641 DependentScopeDeclRefExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004642 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004643 NestedNameSpecifier *NNS
Douglas Gregorf17bb742009-10-22 17:20:55 +00004644 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4645 E->getQualifierRange());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004646 if (!NNS)
4647 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004648
4649 DeclarationName Name
Douglas Gregor81499bb2009-09-03 22:13:48 +00004650 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4651 if (!Name)
4652 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004653
John McCallf7a1a742009-11-24 19:00:30 +00004654 if (!E->hasExplicitTemplateArgs()) {
4655 if (!getDerived().AlwaysRebuild() &&
4656 NNS == E->getQualifier() &&
4657 Name == E->getDeclName())
4658 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004659
John McCallf7a1a742009-11-24 19:00:30 +00004660 return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
4661 E->getQualifierRange(),
4662 Name, E->getLocation(),
4663 /*TemplateArgs*/ 0);
Douglas Gregorf17bb742009-10-22 17:20:55 +00004664 }
John McCalld5532b62009-11-23 01:53:49 +00004665
4666 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004667 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCalld5532b62009-11-23 01:53:49 +00004668 TemplateArgumentLoc Loc;
4669 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
Douglas Gregorb98b1992009-08-11 05:31:07 +00004670 return SemaRef.ExprError();
John McCalld5532b62009-11-23 01:53:49 +00004671 TransArgs.addArgument(Loc);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004672 }
4673
John McCallf7a1a742009-11-24 19:00:30 +00004674 return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
4675 E->getQualifierRange(),
4676 Name, E->getLocation(),
4677 &TransArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004678}
4679
4680template<typename Derived>
4681Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004682TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E,
4683 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004684 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4685
4686 QualType T = getDerived().TransformType(E->getType());
4687 if (T.isNull())
4688 return SemaRef.ExprError();
4689
4690 CXXConstructorDecl *Constructor
4691 = cast_or_null<CXXConstructorDecl>(
4692 getDerived().TransformDecl(E->getConstructor()));
4693 if (!Constructor)
4694 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004695
Douglas Gregorb98b1992009-08-11 05:31:07 +00004696 bool ArgumentChanged = false;
4697 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00004698 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004699 ArgEnd = E->arg_end();
4700 Arg != ArgEnd; ++Arg) {
4701 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4702 if (TransArg.isInvalid())
4703 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004704
Douglas Gregorb98b1992009-08-11 05:31:07 +00004705 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4706 Args.push_back(TransArg.takeAs<Expr>());
4707 }
4708
4709 if (!getDerived().AlwaysRebuild() &&
4710 T == E->getType() &&
4711 Constructor == E->getConstructor() &&
4712 !ArgumentChanged)
4713 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004714
Douglas Gregorb98b1992009-08-11 05:31:07 +00004715 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4716 move_arg(Args));
4717}
Mike Stump1eb44332009-09-09 15:08:12 +00004718
Douglas Gregorb98b1992009-08-11 05:31:07 +00004719/// \brief Transform a C++ temporary-binding expression.
4720///
Mike Stump1eb44332009-09-09 15:08:12 +00004721/// The transformation of a temporary-binding expression always attempts to
4722/// bind a new temporary variable to its subexpression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004723/// subexpression itself did not change, because the temporary variable itself
4724/// must be unique.
4725template<typename Derived>
4726Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004727TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
4728 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004729 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4730 if (SubExpr.isInvalid())
4731 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004732
Douglas Gregorb98b1992009-08-11 05:31:07 +00004733 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4734}
Mike Stump1eb44332009-09-09 15:08:12 +00004735
4736/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregorb98b1992009-08-11 05:31:07 +00004737/// be destroyed after the expression is evaluated.
4738///
Mike Stump1eb44332009-09-09 15:08:12 +00004739/// The transformation of a full expression always attempts to build a new
4740/// CXXExprWithTemporaries expression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004741/// subexpression itself did not change, because it will need to capture the
4742/// the new temporary variables introduced in the subexpression.
4743template<typename Derived>
4744Sema::OwningExprResult
4745TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004746 CXXExprWithTemporaries *E,
4747 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004748 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4749 if (SubExpr.isInvalid())
4750 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004751
Douglas Gregorb98b1992009-08-11 05:31:07 +00004752 return SemaRef.Owned(
4753 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4754 E->shouldDestroyTemporaries()));
4755}
Mike Stump1eb44332009-09-09 15:08:12 +00004756
Douglas Gregorb98b1992009-08-11 05:31:07 +00004757template<typename Derived>
4758Sema::OwningExprResult
4759TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004760 CXXTemporaryObjectExpr *E,
4761 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004762 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4763 QualType T = getDerived().TransformType(E->getType());
4764 if (T.isNull())
4765 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004766
Douglas Gregorb98b1992009-08-11 05:31:07 +00004767 CXXConstructorDecl *Constructor
4768 = cast_or_null<CXXConstructorDecl>(
4769 getDerived().TransformDecl(E->getConstructor()));
4770 if (!Constructor)
4771 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004772
Douglas Gregorb98b1992009-08-11 05:31:07 +00004773 bool ArgumentChanged = false;
4774 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4775 Args.reserve(E->getNumArgs());
Mike Stump1eb44332009-09-09 15:08:12 +00004776 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004777 ArgEnd = E->arg_end();
4778 Arg != ArgEnd; ++Arg) {
4779 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4780 if (TransArg.isInvalid())
4781 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004782
Douglas Gregorb98b1992009-08-11 05:31:07 +00004783 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4784 Args.push_back((Expr *)TransArg.release());
4785 }
Mike Stump1eb44332009-09-09 15:08:12 +00004786
Douglas Gregorb98b1992009-08-11 05:31:07 +00004787 if (!getDerived().AlwaysRebuild() &&
4788 T == E->getType() &&
4789 Constructor == E->getConstructor() &&
4790 !ArgumentChanged)
4791 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004792
Douglas Gregorb98b1992009-08-11 05:31:07 +00004793 // FIXME: Bogus location information
4794 SourceLocation CommaLoc;
4795 if (Args.size() > 1) {
4796 Expr *First = (Expr *)Args[0];
Mike Stump1eb44332009-09-09 15:08:12 +00004797 CommaLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004798 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4799 }
4800 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4801 T,
4802 /*FIXME:*/E->getTypeBeginLoc(),
4803 move_arg(Args),
4804 &CommaLoc,
4805 E->getLocEnd());
4806}
Mike Stump1eb44332009-09-09 15:08:12 +00004807
Douglas Gregorb98b1992009-08-11 05:31:07 +00004808template<typename Derived>
4809Sema::OwningExprResult
4810TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004811 CXXUnresolvedConstructExpr *E,
4812 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004813 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4814 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4815 if (T.isNull())
4816 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004817
Douglas Gregorb98b1992009-08-11 05:31:07 +00004818 bool ArgumentChanged = false;
4819 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4820 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4821 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4822 ArgEnd = E->arg_end();
4823 Arg != ArgEnd; ++Arg) {
4824 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4825 if (TransArg.isInvalid())
4826 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004827
Douglas Gregorb98b1992009-08-11 05:31:07 +00004828 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4829 FakeCommaLocs.push_back(
4830 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4831 Args.push_back(TransArg.takeAs<Expr>());
4832 }
Mike Stump1eb44332009-09-09 15:08:12 +00004833
Douglas Gregorb98b1992009-08-11 05:31:07 +00004834 if (!getDerived().AlwaysRebuild() &&
4835 T == E->getTypeAsWritten() &&
4836 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004837 return SemaRef.Owned(E->Retain());
4838
Douglas Gregorb98b1992009-08-11 05:31:07 +00004839 // FIXME: we're faking the locations of the commas
4840 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4841 T,
4842 E->getLParenLoc(),
4843 move_arg(Args),
4844 FakeCommaLocs.data(),
4845 E->getRParenLoc());
4846}
Mike Stump1eb44332009-09-09 15:08:12 +00004847
Douglas Gregorb98b1992009-08-11 05:31:07 +00004848template<typename Derived>
4849Sema::OwningExprResult
John McCall865d4472009-11-19 22:55:06 +00004850TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
4851 CXXDependentScopeMemberExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004852 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004853 // Transform the base of the expression.
4854 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4855 if (Base.isInvalid())
4856 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004857
Douglas Gregor6cd21982009-10-20 05:58:46 +00004858 // Start the member reference and compute the object's type.
Douglas Gregora38c6872009-09-03 16:14:30 +00004859 Sema::TypeTy *ObjectType = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00004860 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregora38c6872009-09-03 16:14:30 +00004861 E->getOperatorLoc(),
4862 E->isArrow()? tok::arrow : tok::period,
4863 ObjectType);
4864 if (Base.isInvalid())
4865 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004866
Douglas Gregor6cd21982009-10-20 05:58:46 +00004867 // Transform the first part of the nested-name-specifier that qualifies
4868 // the member name.
Douglas Gregorc68afe22009-09-03 21:38:09 +00004869 NamedDecl *FirstQualifierInScope
Douglas Gregor6cd21982009-10-20 05:58:46 +00004870 = getDerived().TransformFirstQualifierInScope(
4871 E->getFirstQualifierFoundInScope(),
4872 E->getQualifierRange().getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00004873
Douglas Gregora38c6872009-09-03 16:14:30 +00004874 NestedNameSpecifier *Qualifier = 0;
4875 if (E->getQualifier()) {
4876 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4877 E->getQualifierRange(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00004878 QualType::getFromOpaquePtr(ObjectType),
4879 FirstQualifierInScope);
Douglas Gregora38c6872009-09-03 16:14:30 +00004880 if (!Qualifier)
4881 return SemaRef.ExprError();
4882 }
Mike Stump1eb44332009-09-09 15:08:12 +00004883
4884 DeclarationName Name
Douglas Gregordd62b152009-10-19 22:04:39 +00004885 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4886 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregor81499bb2009-09-03 22:13:48 +00004887 if (!Name)
4888 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004889
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004890 if (!E->hasExplicitTemplateArgumentList()) {
4891 // This is a reference to a member without an explicitly-specified
4892 // template argument list. Optimize for this common case.
4893 if (!getDerived().AlwaysRebuild() &&
4894 Base.get() == E->getBase() &&
4895 Qualifier == E->getQualifier() &&
4896 Name == E->getMember() &&
4897 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump1eb44332009-09-09 15:08:12 +00004898 return SemaRef.Owned(E->Retain());
4899
John McCall865d4472009-11-19 22:55:06 +00004900 return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004901 E->isArrow(),
4902 E->getOperatorLoc(),
4903 Qualifier,
4904 E->getQualifierRange(),
4905 Name,
4906 E->getMemberLoc(),
4907 FirstQualifierInScope);
4908 }
4909
4910 // FIXME: This is an ugly hack, which forces the same template name to
4911 // be looked up multiple times. Yuck!
Douglas Gregorca1bdd72009-11-04 00:56:37 +00004912 TemporaryBase Rebase(*this, E->getMemberLoc(), DeclarationName());
4913 TemplateName OrigTemplateName;
4914 if (const IdentifierInfo *II = Name.getAsIdentifierInfo())
4915 OrigTemplateName = SemaRef.Context.getDependentTemplateName(0, II);
4916 else
4917 OrigTemplateName
4918 = SemaRef.Context.getDependentTemplateName(0,
4919 Name.getCXXOverloadedOperator());
Mike Stump1eb44332009-09-09 15:08:12 +00004920
4921 TemplateName Template
4922 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004923 QualType::getFromOpaquePtr(ObjectType));
4924 if (Template.isNull())
4925 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004926
John McCalld5532b62009-11-23 01:53:49 +00004927 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004928 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCalld5532b62009-11-23 01:53:49 +00004929 TemplateArgumentLoc Loc;
4930 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004931 return SemaRef.ExprError();
John McCalld5532b62009-11-23 01:53:49 +00004932 TransArgs.addArgument(Loc);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004933 }
Mike Stump1eb44332009-09-09 15:08:12 +00004934
John McCall865d4472009-11-19 22:55:06 +00004935 return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004936 E->isArrow(),
4937 E->getOperatorLoc(),
Douglas Gregora38c6872009-09-03 16:14:30 +00004938 Qualifier,
4939 E->getQualifierRange(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004940 Template,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004941 E->getMemberLoc(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004942 FirstQualifierInScope,
John McCalld5532b62009-11-23 01:53:49 +00004943 TransArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004944}
4945
4946template<typename Derived>
4947Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004948TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E,
4949 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004950 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004951}
4952
Mike Stump1eb44332009-09-09 15:08:12 +00004953template<typename Derived>
4954Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004955TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E,
4956 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004957 // FIXME: poor source location
4958 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4959 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4960 if (EncodedType.isNull())
4961 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004962
Douglas Gregorb98b1992009-08-11 05:31:07 +00004963 if (!getDerived().AlwaysRebuild() &&
4964 EncodedType == E->getEncodedType())
Mike Stump1eb44332009-09-09 15:08:12 +00004965 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004966
4967 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4968 EncodedType,
4969 E->getRParenLoc());
4970}
Mike Stump1eb44332009-09-09 15:08:12 +00004971
Douglas Gregorb98b1992009-08-11 05:31:07 +00004972template<typename Derived>
4973Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004974TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E,
4975 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004976 // FIXME: Implement this!
4977 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004978 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004979}
4980
Mike Stump1eb44332009-09-09 15:08:12 +00004981template<typename Derived>
4982Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004983TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E,
4984 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004985 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004986}
4987
Mike Stump1eb44332009-09-09 15:08:12 +00004988template<typename Derived>
4989Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004990TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E,
4991 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004992 ObjCProtocolDecl *Protocol
Douglas Gregorb98b1992009-08-11 05:31:07 +00004993 = cast_or_null<ObjCProtocolDecl>(
4994 getDerived().TransformDecl(E->getProtocol()));
4995 if (!Protocol)
4996 return SemaRef.ExprError();
4997
4998 if (!getDerived().AlwaysRebuild() &&
4999 Protocol == E->getProtocol())
Mike Stump1eb44332009-09-09 15:08:12 +00005000 return SemaRef.Owned(E->Retain());
5001
Douglas Gregorb98b1992009-08-11 05:31:07 +00005002 return getDerived().RebuildObjCProtocolExpr(Protocol,
5003 E->getAtLoc(),
5004 /*FIXME:*/E->getAtLoc(),
5005 /*FIXME:*/E->getAtLoc(),
5006 E->getRParenLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00005007
Douglas Gregorb98b1992009-08-11 05:31:07 +00005008}
5009
Mike Stump1eb44332009-09-09 15:08:12 +00005010template<typename Derived>
5011Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005012TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E,
5013 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005014 // FIXME: Implement this!
5015 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005016 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005017}
5018
Mike Stump1eb44332009-09-09 15:08:12 +00005019template<typename Derived>
5020Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005021TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E,
5022 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005023 // FIXME: Implement this!
5024 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005025 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005026}
5027
Mike Stump1eb44332009-09-09 15:08:12 +00005028template<typename Derived>
5029Sema::OwningExprResult
Fariborz Jahanian09105f52009-08-20 17:02:02 +00005030TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005031 ObjCImplicitSetterGetterRefExpr *E,
5032 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005033 // FIXME: Implement this!
5034 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005035 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005036}
5037
Mike Stump1eb44332009-09-09 15:08:12 +00005038template<typename Derived>
5039Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005040TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E,
5041 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005042 // FIXME: Implement this!
5043 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005044 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005045}
5046
Mike Stump1eb44332009-09-09 15:08:12 +00005047template<typename Derived>
5048Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005049TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E,
5050 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005051 // FIXME: Implement this!
5052 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005053 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005054}
5055
Mike Stump1eb44332009-09-09 15:08:12 +00005056template<typename Derived>
5057Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005058TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E,
5059 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005060 bool ArgumentChanged = false;
5061 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
5062 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
5063 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
5064 if (SubExpr.isInvalid())
5065 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005066
Douglas Gregorb98b1992009-08-11 05:31:07 +00005067 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
5068 SubExprs.push_back(SubExpr.takeAs<Expr>());
5069 }
Mike Stump1eb44332009-09-09 15:08:12 +00005070
Douglas Gregorb98b1992009-08-11 05:31:07 +00005071 if (!getDerived().AlwaysRebuild() &&
5072 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00005073 return SemaRef.Owned(E->Retain());
5074
Douglas Gregorb98b1992009-08-11 05:31:07 +00005075 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
5076 move_arg(SubExprs),
5077 E->getRParenLoc());
5078}
5079
Mike Stump1eb44332009-09-09 15:08:12 +00005080template<typename Derived>
5081Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005082TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E,
5083 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005084 // FIXME: Implement this!
5085 assert(false && "Cannot transform block expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005086 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005087}
5088
Mike Stump1eb44332009-09-09 15:08:12 +00005089template<typename Derived>
5090Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005091TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E,
5092 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005093 // FIXME: Implement this!
5094 assert(false && "Cannot transform block-related expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005095 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005096}
Mike Stump1eb44332009-09-09 15:08:12 +00005097
Douglas Gregorb98b1992009-08-11 05:31:07 +00005098//===----------------------------------------------------------------------===//
Douglas Gregor577f75a2009-08-04 16:50:30 +00005099// Type reconstruction
5100//===----------------------------------------------------------------------===//
5101
Mike Stump1eb44332009-09-09 15:08:12 +00005102template<typename Derived>
John McCall85737a72009-10-30 00:06:24 +00005103QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
5104 SourceLocation Star) {
5105 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005106 getDerived().getBaseEntity());
5107}
5108
Mike Stump1eb44332009-09-09 15:08:12 +00005109template<typename Derived>
John McCall85737a72009-10-30 00:06:24 +00005110QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
5111 SourceLocation Star) {
5112 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005113 getDerived().getBaseEntity());
5114}
5115
Mike Stump1eb44332009-09-09 15:08:12 +00005116template<typename Derived>
5117QualType
John McCall85737a72009-10-30 00:06:24 +00005118TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
5119 bool WrittenAsLValue,
5120 SourceLocation Sigil) {
5121 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
5122 Sigil, getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005123}
5124
5125template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005126QualType
John McCall85737a72009-10-30 00:06:24 +00005127TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
5128 QualType ClassType,
5129 SourceLocation Sigil) {
John McCall0953e762009-09-24 19:53:00 +00005130 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
John McCall85737a72009-10-30 00:06:24 +00005131 Sigil, getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005132}
5133
5134template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005135QualType
John McCall85737a72009-10-30 00:06:24 +00005136TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType,
5137 SourceLocation Sigil) {
5138 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Sigil,
John McCalla2becad2009-10-21 00:40:46 +00005139 getDerived().getBaseEntity());
5140}
5141
5142template<typename Derived>
5143QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00005144TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
5145 ArrayType::ArraySizeModifier SizeMod,
5146 const llvm::APInt *Size,
5147 Expr *SizeExpr,
5148 unsigned IndexTypeQuals,
5149 SourceRange BracketsRange) {
5150 if (SizeExpr || !Size)
5151 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
5152 IndexTypeQuals, BracketsRange,
5153 getDerived().getBaseEntity());
Mike Stump1eb44332009-09-09 15:08:12 +00005154
5155 QualType Types[] = {
5156 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
5157 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
5158 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregor577f75a2009-08-04 16:50:30 +00005159 };
5160 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
5161 QualType SizeType;
5162 for (unsigned I = 0; I != NumTypes; ++I)
5163 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
5164 SizeType = Types[I];
5165 break;
5166 }
Mike Stump1eb44332009-09-09 15:08:12 +00005167
Douglas Gregor577f75a2009-08-04 16:50:30 +00005168 if (SizeType.isNull())
5169 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump1eb44332009-09-09 15:08:12 +00005170
Douglas Gregor577f75a2009-08-04 16:50:30 +00005171 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00005172 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005173 IndexTypeQuals, BracketsRange,
Mike Stump1eb44332009-09-09 15:08:12 +00005174 getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005175}
Mike Stump1eb44332009-09-09 15:08:12 +00005176
Douglas Gregor577f75a2009-08-04 16:50:30 +00005177template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005178QualType
5179TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005180 ArrayType::ArraySizeModifier SizeMod,
5181 const llvm::APInt &Size,
John McCall85737a72009-10-30 00:06:24 +00005182 unsigned IndexTypeQuals,
5183 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005184 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
John McCall85737a72009-10-30 00:06:24 +00005185 IndexTypeQuals, BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005186}
5187
5188template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005189QualType
Mike Stump1eb44332009-09-09 15:08:12 +00005190TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005191 ArrayType::ArraySizeModifier SizeMod,
John McCall85737a72009-10-30 00:06:24 +00005192 unsigned IndexTypeQuals,
5193 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005194 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
John McCall85737a72009-10-30 00:06:24 +00005195 IndexTypeQuals, BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005196}
Mike Stump1eb44332009-09-09 15:08:12 +00005197
Douglas Gregor577f75a2009-08-04 16:50:30 +00005198template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005199QualType
5200TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005201 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005202 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005203 unsigned IndexTypeQuals,
5204 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005205 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005206 SizeExpr.takeAs<Expr>(),
5207 IndexTypeQuals, BracketsRange);
5208}
5209
5210template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005211QualType
5212TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005213 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005214 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005215 unsigned IndexTypeQuals,
5216 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005217 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005218 SizeExpr.takeAs<Expr>(),
5219 IndexTypeQuals, BracketsRange);
5220}
5221
5222template<typename Derived>
5223QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5224 unsigned NumElements) {
5225 // FIXME: semantic checking!
5226 return SemaRef.Context.getVectorType(ElementType, NumElements);
5227}
Mike Stump1eb44332009-09-09 15:08:12 +00005228
Douglas Gregor577f75a2009-08-04 16:50:30 +00005229template<typename Derived>
5230QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5231 unsigned NumElements,
5232 SourceLocation AttributeLoc) {
5233 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5234 NumElements, true);
5235 IntegerLiteral *VectorSize
Mike Stump1eb44332009-09-09 15:08:12 +00005236 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005237 AttributeLoc);
5238 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5239 AttributeLoc);
5240}
Mike Stump1eb44332009-09-09 15:08:12 +00005241
Douglas Gregor577f75a2009-08-04 16:50:30 +00005242template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005243QualType
5244TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005245 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005246 SourceLocation AttributeLoc) {
5247 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5248}
Mike Stump1eb44332009-09-09 15:08:12 +00005249
Douglas Gregor577f75a2009-08-04 16:50:30 +00005250template<typename Derived>
5251QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +00005252 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005253 unsigned NumParamTypes,
Mike Stump1eb44332009-09-09 15:08:12 +00005254 bool Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005255 unsigned Quals) {
Mike Stump1eb44332009-09-09 15:08:12 +00005256 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005257 Quals,
5258 getDerived().getBaseLocation(),
5259 getDerived().getBaseEntity());
5260}
Mike Stump1eb44332009-09-09 15:08:12 +00005261
Douglas Gregor577f75a2009-08-04 16:50:30 +00005262template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00005263QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5264 return SemaRef.Context.getFunctionNoProtoType(T);
5265}
5266
5267template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00005268QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00005269 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5270}
5271
5272template<typename Derived>
5273QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5274 return SemaRef.Context.getTypeOfType(Underlying);
5275}
5276
5277template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00005278QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00005279 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5280}
5281
5282template<typename Derived>
5283QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall833ca992009-10-29 08:12:44 +00005284 TemplateName Template,
5285 SourceLocation TemplateNameLoc,
John McCalld5532b62009-11-23 01:53:49 +00005286 const TemplateArgumentListInfo &TemplateArgs) {
5287 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005288}
Mike Stump1eb44332009-09-09 15:08:12 +00005289
Douglas Gregordcee1a12009-08-06 05:28:30 +00005290template<typename Derived>
5291NestedNameSpecifier *
5292TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5293 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00005294 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00005295 QualType ObjectType,
John McCalld5532b62009-11-23 01:53:49 +00005296 NamedDecl *FirstQualifierInScope) {
Douglas Gregordcee1a12009-08-06 05:28:30 +00005297 CXXScopeSpec SS;
5298 // FIXME: The source location information is all wrong.
5299 SS.setRange(Range);
5300 SS.setScopeRep(Prefix);
5301 return static_cast<NestedNameSpecifier *>(
Mike Stump1eb44332009-09-09 15:08:12 +00005302 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregor495c35d2009-08-25 22:51:20 +00005303 Range.getEnd(), II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00005304 ObjectType,
5305 FirstQualifierInScope,
Douglas Gregor495c35d2009-08-25 22:51:20 +00005306 false));
Douglas Gregordcee1a12009-08-06 05:28:30 +00005307}
5308
5309template<typename Derived>
5310NestedNameSpecifier *
5311TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5312 SourceRange Range,
5313 NamespaceDecl *NS) {
5314 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5315}
5316
5317template<typename Derived>
5318NestedNameSpecifier *
5319TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5320 SourceRange Range,
5321 bool TemplateKW,
5322 QualType T) {
5323 if (T->isDependentType() || T->isRecordType() ||
5324 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
Douglas Gregora4923eb2009-11-16 21:35:15 +00005325 assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregordcee1a12009-08-06 05:28:30 +00005326 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5327 T.getTypePtr());
5328 }
Mike Stump1eb44332009-09-09 15:08:12 +00005329
Douglas Gregordcee1a12009-08-06 05:28:30 +00005330 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5331 return 0;
5332}
Mike Stump1eb44332009-09-09 15:08:12 +00005333
Douglas Gregord1067e52009-08-06 06:41:21 +00005334template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005335TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005336TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5337 bool TemplateKW,
5338 TemplateDecl *Template) {
Mike Stump1eb44332009-09-09 15:08:12 +00005339 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregord1067e52009-08-06 06:41:21 +00005340 Template);
5341}
5342
5343template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005344TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005345TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005346 const IdentifierInfo &II,
5347 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00005348 CXXScopeSpec SS;
5349 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump1eb44332009-09-09 15:08:12 +00005350 SS.setScopeRep(Qualifier);
Douglas Gregor014e88d2009-11-03 23:16:33 +00005351 UnqualifiedId Name;
5352 Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005353 return getSema().ActOnDependentTemplateName(
5354 /*FIXME:*/getDerived().getBaseLocation(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005355 SS,
Douglas Gregor014e88d2009-11-03 23:16:33 +00005356 Name,
Douglas Gregora481edb2009-11-20 23:39:24 +00005357 ObjectType.getAsOpaquePtr(),
5358 /*EnteringContext=*/false)
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005359 .template getAsVal<TemplateName>();
Douglas Gregord1067e52009-08-06 06:41:21 +00005360}
Mike Stump1eb44332009-09-09 15:08:12 +00005361
Douglas Gregorb98b1992009-08-11 05:31:07 +00005362template<typename Derived>
Douglas Gregorca1bdd72009-11-04 00:56:37 +00005363TemplateName
5364TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5365 OverloadedOperatorKind Operator,
5366 QualType ObjectType) {
5367 CXXScopeSpec SS;
5368 SS.setRange(SourceRange(getDerived().getBaseLocation()));
5369 SS.setScopeRep(Qualifier);
5370 UnqualifiedId Name;
5371 SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
5372 Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
5373 Operator, SymbolLocations);
5374 return getSema().ActOnDependentTemplateName(
5375 /*FIXME:*/getDerived().getBaseLocation(),
5376 SS,
5377 Name,
Douglas Gregora481edb2009-11-20 23:39:24 +00005378 ObjectType.getAsOpaquePtr(),
5379 /*EnteringContext=*/false)
Douglas Gregorca1bdd72009-11-04 00:56:37 +00005380 .template getAsVal<TemplateName>();
5381}
5382
5383template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005384Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00005385TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5386 SourceLocation OpLoc,
5387 ExprArg Callee,
5388 ExprArg First,
5389 ExprArg Second) {
5390 Expr *FirstExpr = (Expr *)First.get();
5391 Expr *SecondExpr = (Expr *)Second.get();
John McCallba135432009-11-21 08:51:07 +00005392 Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
Douglas Gregorb98b1992009-08-11 05:31:07 +00005393 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump1eb44332009-09-09 15:08:12 +00005394
Douglas Gregorb98b1992009-08-11 05:31:07 +00005395 // Determine whether this should be a builtin operation.
Sebastian Redlf322ed62009-10-29 20:17:01 +00005396 if (Op == OO_Subscript) {
5397 if (!FirstExpr->getType()->isOverloadableType() &&
5398 !SecondExpr->getType()->isOverloadableType())
5399 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
John McCallba135432009-11-21 08:51:07 +00005400 CalleeExpr->getLocStart(),
Sebastian Redlf322ed62009-10-29 20:17:01 +00005401 move(Second), OpLoc);
Eli Friedman1a3c75f2009-11-16 19:13:03 +00005402 } else if (Op == OO_Arrow) {
5403 // -> is never a builtin operation.
5404 return SemaRef.BuildOverloadedArrowExpr(0, move(First), OpLoc);
Sebastian Redlf322ed62009-10-29 20:17:01 +00005405 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005406 if (!FirstExpr->getType()->isOverloadableType()) {
5407 // The argument is not of overloadable type, so try to create a
5408 // built-in unary operation.
Mike Stump1eb44332009-09-09 15:08:12 +00005409 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00005410 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump1eb44332009-09-09 15:08:12 +00005411
Douglas Gregorb98b1992009-08-11 05:31:07 +00005412 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5413 }
5414 } else {
Mike Stump1eb44332009-09-09 15:08:12 +00005415 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00005416 !SecondExpr->getType()->isOverloadableType()) {
5417 // Neither of the arguments is an overloadable type, so try to
5418 // create a built-in binary operation.
5419 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00005420 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00005421 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5422 if (Result.isInvalid())
5423 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005424
Douglas Gregorb98b1992009-08-11 05:31:07 +00005425 First.release();
5426 Second.release();
5427 return move(Result);
5428 }
5429 }
Mike Stump1eb44332009-09-09 15:08:12 +00005430
5431 // Compute the transformed set of functions (and function templates) to be
Douglas Gregorb98b1992009-08-11 05:31:07 +00005432 // used during overload resolution.
5433 Sema::FunctionSet Functions;
Mike Stump1eb44332009-09-09 15:08:12 +00005434
John McCallba135432009-11-21 08:51:07 +00005435 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
5436 assert(ULE->requiresADL());
5437
5438 // FIXME: Do we have to check
5439 // IsAcceptableNonMemberOperatorCandidate for each of these?
5440 for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
5441 E = ULE->decls_end(); I != E; ++I)
5442 Functions.insert(AnyFunctionDecl::getFromNamedDecl(*I));
5443 } else {
5444 Functions.insert(AnyFunctionDecl::getFromNamedDecl(
5445 cast<DeclRefExpr>(CalleeExpr)->getDecl()));
5446 }
Mike Stump1eb44332009-09-09 15:08:12 +00005447
Douglas Gregorb98b1992009-08-11 05:31:07 +00005448 // Add any functions found via argument-dependent lookup.
5449 Expr *Args[2] = { FirstExpr, SecondExpr };
5450 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump1eb44332009-09-09 15:08:12 +00005451 DeclarationName OpName
Douglas Gregorb98b1992009-08-11 05:31:07 +00005452 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redl644be852009-10-23 19:23:15 +00005453 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5454 Functions);
Mike Stump1eb44332009-09-09 15:08:12 +00005455
Douglas Gregorb98b1992009-08-11 05:31:07 +00005456 // Create the overloaded operator invocation for unary operators.
5457 if (NumArgs == 1 || isPostIncDec) {
Mike Stump1eb44332009-09-09 15:08:12 +00005458 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00005459 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5460 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5461 }
Mike Stump1eb44332009-09-09 15:08:12 +00005462
Sebastian Redlf322ed62009-10-29 20:17:01 +00005463 if (Op == OO_Subscript)
John McCallba135432009-11-21 08:51:07 +00005464 return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
5465 OpLoc,
5466 move(First),
5467 move(Second));
Sebastian Redlf322ed62009-10-29 20:17:01 +00005468
Douglas Gregorb98b1992009-08-11 05:31:07 +00005469 // Create the overloaded operator invocation for binary operators.
Mike Stump1eb44332009-09-09 15:08:12 +00005470 BinaryOperator::Opcode Opc =
Douglas Gregorb98b1992009-08-11 05:31:07 +00005471 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00005472 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00005473 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5474 if (Result.isInvalid())
5475 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005476
Douglas Gregorb98b1992009-08-11 05:31:07 +00005477 First.release();
5478 Second.release();
Mike Stump1eb44332009-09-09 15:08:12 +00005479 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00005480}
Mike Stump1eb44332009-09-09 15:08:12 +00005481
Douglas Gregor577f75a2009-08-04 16:50:30 +00005482} // end namespace clang
5483
5484#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H