blob: 9a6b851d63a64db752b0d286d00649eed878ff86 [file] [log] [blame]
John McCall550e0c22009-10-21 00:40:46 +00001//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
Douglas Gregord6ff3322009-08-04 16:50:30 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements a semantic tree transformation that takes a given
10// AST and rebuilds it, possibly transforming some nodes in the process.
11//
12//===----------------------------------------------------------------------===/
13#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_SEMA_TREETRANSFORM_H
15
16#include "Sema.h"
Douglas Gregor1135c352009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregor2b6ca462009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor766b0bb2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregora16548e2009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregorebe10102009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
John McCall550e0c22009-10-21 00:40:46 +000025#include "clang/AST/TypeLocBuilder.h"
Douglas Gregora16548e2009-08-11 05:31:07 +000026#include "clang/Parse/Ownership.h"
27#include "clang/Parse/Designator.h"
28#include "clang/Lex/Preprocessor.h"
John McCall550e0c22009-10-21 00:40:46 +000029#include "llvm/Support/ErrorHandling.h"
Douglas Gregord6ff3322009-08-04 16:50:30 +000030#include <algorithm>
31
32namespace clang {
Mike Stump11289f42009-09-09 15:08:12 +000033
Douglas Gregord6ff3322009-08-04 16:50:30 +000034/// \brief A semantic tree transformation that allows one to transform one
35/// abstract syntax tree into another.
36///
Mike Stump11289f42009-09-09 15:08:12 +000037/// A new tree transformation is defined by creating a new subclass \c X of
38/// \c TreeTransform<X> and then overriding certain operations to provide
39/// behavior specific to that transformation. For example, template
Douglas Gregord6ff3322009-08-04 16:50:30 +000040/// instantiation is implemented as a tree transformation where the
41/// transformation of TemplateTypeParmType nodes involves substituting the
42/// template arguments for their corresponding template parameters; a similar
43/// transformation is performed for non-type template parameters and
44/// template template parameters.
45///
46/// This tree-transformation template uses static polymorphism to allow
Mike Stump11289f42009-09-09 15:08:12 +000047/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregord6ff3322009-08-04 16:50:30 +000048/// override any of the transformation or rebuild operators by providing an
49/// operation with the same signature as the default implementation. The
50/// overridding function should not be virtual.
51///
52/// Semantic tree transformations are split into two stages, either of which
53/// can be replaced by a subclass. The "transform" step transforms an AST node
54/// or the parts of an AST node using the various transformation functions,
55/// then passes the pieces on to the "rebuild" step, which constructs a new AST
56/// node of the appropriate kind from the pieces. The default transformation
57/// routines recursively transform the operands to composite AST nodes (e.g.,
58/// the pointee type of a PointerType node) and, if any of those operand nodes
59/// were changed by the transformation, invokes the rebuild operation to create
60/// a new AST node.
61///
Mike Stump11289f42009-09-09 15:08:12 +000062/// Subclasses can customize the transformation at various levels. The
Douglas Gregore922c772009-08-04 22:27:00 +000063/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregord6ff3322009-08-04 16:50:30 +000064/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
65/// TransformTemplateName(), or TransformTemplateArgument() with entirely
66/// new implementations.
67///
68/// For more fine-grained transformations, subclasses can replace any of the
69/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
Douglas Gregorebe10102009-08-20 07:17:43 +000070/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregord6ff3322009-08-04 16:50:30 +000071/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump11289f42009-09-09 15:08:12 +000072/// to substitute template arguments for their corresponding template
Douglas Gregord6ff3322009-08-04 16:50:30 +000073/// parameters. Additionally, subclasses can override the \c RebuildXXX
74/// functions to control how AST nodes are rebuilt when their operands change.
75/// By default, \c TreeTransform will invoke semantic analysis to rebuild
76/// AST nodes. However, certain other tree transformations (e.g, cloning) may
77/// be able to use more efficient rebuild steps.
78///
79/// There are a handful of other functions that can be overridden, allowing one
Mike Stump11289f42009-09-09 15:08:12 +000080/// to avoid traversing nodes that don't need any transformation
Douglas Gregord6ff3322009-08-04 16:50:30 +000081/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
82/// operands have not changed (\c AlwaysRebuild()), and customize the
83/// default locations and entity names used for type-checking
84/// (\c getBaseLocation(), \c getBaseEntity()).
Douglas Gregord6ff3322009-08-04 16:50:30 +000085template<typename Derived>
86class TreeTransform {
87protected:
88 Sema &SemaRef;
Mike Stump11289f42009-09-09 15:08:12 +000089
90public:
Douglas Gregora16548e2009-08-11 05:31:07 +000091 typedef Sema::OwningStmtResult OwningStmtResult;
92 typedef Sema::OwningExprResult OwningExprResult;
93 typedef Sema::StmtArg StmtArg;
94 typedef Sema::ExprArg ExprArg;
95 typedef Sema::MultiExprArg MultiExprArg;
Douglas Gregorebe10102009-08-20 07:17:43 +000096 typedef Sema::MultiStmtArg MultiStmtArg;
Mike Stump11289f42009-09-09 15:08:12 +000097
Douglas Gregord6ff3322009-08-04 16:50:30 +000098 /// \brief Initializes a new tree transformer.
99 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump11289f42009-09-09 15:08:12 +0000100
Douglas Gregord6ff3322009-08-04 16:50:30 +0000101 /// \brief Retrieves a reference to the derived class.
102 Derived &getDerived() { return static_cast<Derived&>(*this); }
103
104 /// \brief Retrieves a reference to the derived class.
Mike Stump11289f42009-09-09 15:08:12 +0000105 const Derived &getDerived() const {
106 return static_cast<const Derived&>(*this);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000107 }
108
109 /// \brief Retrieves a reference to the semantic analysis object used for
110 /// this tree transform.
111 Sema &getSema() const { return SemaRef; }
Mike Stump11289f42009-09-09 15:08:12 +0000112
Douglas Gregord6ff3322009-08-04 16:50:30 +0000113 /// \brief Whether the transformation should always rebuild AST nodes, even
114 /// if none of the children have changed.
115 ///
116 /// Subclasses may override this function to specify when the transformation
117 /// should rebuild all AST nodes.
118 bool AlwaysRebuild() { return false; }
Mike Stump11289f42009-09-09 15:08:12 +0000119
Douglas Gregord6ff3322009-08-04 16:50:30 +0000120 /// \brief Returns the location of the entity being transformed, if that
121 /// information was not available elsewhere in the AST.
122 ///
Mike Stump11289f42009-09-09 15:08:12 +0000123 /// By default, returns no source-location information. Subclasses can
Douglas Gregord6ff3322009-08-04 16:50:30 +0000124 /// provide an alternative implementation that provides better location
125 /// information.
126 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump11289f42009-09-09 15:08:12 +0000127
Douglas Gregord6ff3322009-08-04 16:50:30 +0000128 /// \brief Returns the name of the entity being transformed, if that
129 /// information was not available elsewhere in the AST.
130 ///
131 /// By default, returns an empty name. Subclasses can provide an alternative
132 /// implementation with a more precise name.
133 DeclarationName getBaseEntity() { return DeclarationName(); }
134
Douglas Gregora16548e2009-08-11 05:31:07 +0000135 /// \brief Sets the "base" location and entity when that
136 /// information is known based on another transformation.
137 ///
138 /// By default, the source location and entity are ignored. Subclasses can
139 /// override this function to provide a customized implementation.
140 void setBase(SourceLocation Loc, DeclarationName Entity) { }
Mike Stump11289f42009-09-09 15:08:12 +0000141
Douglas Gregora16548e2009-08-11 05:31:07 +0000142 /// \brief RAII object that temporarily sets the base location and entity
143 /// used for reporting diagnostics in types.
144 class TemporaryBase {
145 TreeTransform &Self;
146 SourceLocation OldLocation;
147 DeclarationName OldEntity;
Mike Stump11289f42009-09-09 15:08:12 +0000148
Douglas Gregora16548e2009-08-11 05:31:07 +0000149 public:
150 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump11289f42009-09-09 15:08:12 +0000151 DeclarationName Entity) : Self(Self) {
Douglas Gregora16548e2009-08-11 05:31:07 +0000152 OldLocation = Self.getDerived().getBaseLocation();
153 OldEntity = Self.getDerived().getBaseEntity();
154 Self.getDerived().setBase(Location, Entity);
155 }
Mike Stump11289f42009-09-09 15:08:12 +0000156
Douglas Gregora16548e2009-08-11 05:31:07 +0000157 ~TemporaryBase() {
158 Self.getDerived().setBase(OldLocation, OldEntity);
159 }
160 };
Mike Stump11289f42009-09-09 15:08:12 +0000161
162 /// \brief Determine whether the given type \p T has already been
Douglas Gregord6ff3322009-08-04 16:50:30 +0000163 /// transformed.
164 ///
165 /// Subclasses can provide an alternative implementation of this routine
Mike Stump11289f42009-09-09 15:08:12 +0000166 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregord6ff3322009-08-04 16:50:30 +0000167 /// not change. For example, template instantiation need not traverse
168 /// non-dependent types.
169 bool AlreadyTransformed(QualType T) {
170 return T.isNull();
171 }
172
173 /// \brief Transforms the given type into another type.
174 ///
John McCall550e0c22009-10-21 00:40:46 +0000175 /// By default, this routine transforms a type by creating a
176 /// DeclaratorInfo for it and delegating to the appropriate
177 /// function. This is expensive, but we don't mind, because
178 /// this method is deprecated anyway; all users should be
179 /// switched to storing DeclaratorInfos.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000180 ///
181 /// \returns the transformed type.
182 QualType TransformType(QualType T);
Mike Stump11289f42009-09-09 15:08:12 +0000183
John McCall550e0c22009-10-21 00:40:46 +0000184 /// \brief Transforms the given type-with-location into a new
185 /// type-with-location.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000186 ///
John McCall550e0c22009-10-21 00:40:46 +0000187 /// By default, this routine transforms a type by delegating to the
188 /// appropriate TransformXXXType to build a new type. Subclasses
189 /// may override this function (to take over all type
190 /// transformations) or some set of the TransformXXXType functions
191 /// to alter the transformation.
192 DeclaratorInfo *TransformType(DeclaratorInfo *DI);
193
194 /// \brief Transform the given type-with-location into a new
195 /// type, collecting location information in the given builder
196 /// as necessary.
197 ///
198 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
Mike Stump11289f42009-09-09 15:08:12 +0000199
Douglas Gregor766b0bb2009-08-06 22:17:10 +0000200 /// \brief Transform the given statement.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000201 ///
Mike Stump11289f42009-09-09 15:08:12 +0000202 /// By default, this routine transforms a statement by delegating to the
Douglas Gregorebe10102009-08-20 07:17:43 +0000203 /// appropriate TransformXXXStmt function to transform a specific kind of
204 /// statement or the TransformExpr() function to transform an expression.
205 /// Subclasses may override this function to transform statements using some
206 /// other mechanism.
207 ///
208 /// \returns the transformed statement.
Douglas Gregora16548e2009-08-11 05:31:07 +0000209 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump11289f42009-09-09 15:08:12 +0000210
Douglas Gregor766b0bb2009-08-06 22:17:10 +0000211 /// \brief Transform the given expression.
212 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000213 /// By default, this routine transforms an expression by delegating to the
214 /// appropriate TransformXXXExpr function to build a new expression.
215 /// Subclasses may override this function to transform expressions using some
216 /// other mechanism.
217 ///
218 /// \returns the transformed expression.
219 OwningExprResult TransformExpr(Expr *E) {
220 return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
221 }
222
223 /// \brief Transform the given expression.
224 ///
225 /// By default, this routine transforms an expression by delegating to the
226 /// appropriate TransformXXXExpr function to build a new expression.
227 /// Subclasses may override this function to transform expressions using some
228 /// other mechanism.
229 ///
230 /// \returns the transformed expression.
231 OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
Mike Stump11289f42009-09-09 15:08:12 +0000232
Douglas Gregord6ff3322009-08-04 16:50:30 +0000233 /// \brief Transform the given declaration, which is referenced from a type
234 /// or expression.
235 ///
Douglas Gregor1135c352009-08-06 05:28:30 +0000236 /// By default, acts as the identity function on declarations. Subclasses
237 /// may override this function to provide alternate behavior.
238 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregorebe10102009-08-20 07:17:43 +0000239
240 /// \brief Transform the definition of the given declaration.
241 ///
Mike Stump11289f42009-09-09 15:08:12 +0000242 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregorebe10102009-08-20 07:17:43 +0000243 /// Subclasses may override this function to provide alternate behavior.
244 Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
Mike Stump11289f42009-09-09 15:08:12 +0000245
Douglas Gregora5cb6da2009-10-20 05:58:46 +0000246 /// \brief Transform the given declaration, which was the first part of a
247 /// nested-name-specifier in a member access expression.
248 ///
249 /// This specific declaration transformation only applies to the first
250 /// identifier in a nested-name-specifier of a member access expression, e.g.,
251 /// the \c T in \c x->T::member
252 ///
253 /// By default, invokes TransformDecl() to transform the declaration.
254 /// Subclasses may override this function to provide alternate behavior.
255 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
256 return cast_or_null<NamedDecl>(getDerived().TransformDecl(D));
257 }
258
Douglas Gregord6ff3322009-08-04 16:50:30 +0000259 /// \brief Transform the given nested-name-specifier.
260 ///
Mike Stump11289f42009-09-09 15:08:12 +0000261 /// By default, transforms all of the types and declarations within the
Douglas Gregor1135c352009-08-06 05:28:30 +0000262 /// nested-name-specifier. Subclasses may override this function to provide
263 /// alternate behavior.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000264 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000265 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000266 QualType ObjectType = QualType(),
267 NamedDecl *FirstQualifierInScope = 0);
Mike Stump11289f42009-09-09 15:08:12 +0000268
Douglas Gregorf816bd72009-09-03 22:13:48 +0000269 /// \brief Transform the given declaration name.
270 ///
271 /// By default, transforms the types of conversion function, constructor,
272 /// and destructor names and then (if needed) rebuilds the declaration name.
273 /// Identifiers and selectors are returned unmodified. Sublcasses may
274 /// override this function to provide alternate behavior.
275 DeclarationName TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +0000276 SourceLocation Loc,
277 QualType ObjectType = QualType());
Mike Stump11289f42009-09-09 15:08:12 +0000278
Douglas Gregord6ff3322009-08-04 16:50:30 +0000279 /// \brief Transform the given template name.
Mike Stump11289f42009-09-09 15:08:12 +0000280 ///
Douglas Gregor71dc5092009-08-06 06:41:21 +0000281 /// By default, transforms the template name by transforming the declarations
Mike Stump11289f42009-09-09 15:08:12 +0000282 /// and nested-name-specifiers that occur within the template name.
Douglas Gregor71dc5092009-08-06 06:41:21 +0000283 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor308047d2009-09-09 00:23:06 +0000284 TemplateName TransformTemplateName(TemplateName Name,
285 QualType ObjectType = QualType());
Mike Stump11289f42009-09-09 15:08:12 +0000286
Douglas Gregord6ff3322009-08-04 16:50:30 +0000287 /// \brief Transform the given template argument.
288 ///
Mike Stump11289f42009-09-09 15:08:12 +0000289 /// By default, this operation transforms the type, expression, or
290 /// declaration stored within the template argument and constructs a
Douglas Gregore922c772009-08-04 22:27:00 +0000291 /// new template argument from the transformed result. Subclasses may
292 /// override this function to provide alternate behavior.
John McCall0ad16662009-10-29 08:12:44 +0000293 ///
294 /// Returns true if there was an error.
295 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
296 TemplateArgumentLoc &Output);
297
298 /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
299 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
300 TemplateArgumentLoc &ArgLoc);
301
302 /// \brief Fakes up a DeclaratorInfo for a type.
303 DeclaratorInfo *InventDeclaratorInfo(QualType T) {
304 return SemaRef.Context.getTrivialDeclaratorInfo(T,
305 getDerived().getBaseLocation());
306 }
Mike Stump11289f42009-09-09 15:08:12 +0000307
John McCall550e0c22009-10-21 00:40:46 +0000308#define ABSTRACT_TYPELOC(CLASS, PARENT)
309#define TYPELOC(CLASS, PARENT) \
310 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
311#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +0000312
John McCall70dd5f62009-10-30 00:06:24 +0000313 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
314
Douglas Gregorc59e5612009-10-19 22:04:39 +0000315 QualType
316 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
317 QualType ObjectType);
John McCall0ad16662009-10-29 08:12:44 +0000318
319 QualType
320 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
321 TemplateSpecializationTypeLoc TL,
322 QualType ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +0000323
Douglas Gregorebe10102009-08-20 07:17:43 +0000324 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump11289f42009-09-09 15:08:12 +0000325
Douglas Gregorebe10102009-08-20 07:17:43 +0000326#define STMT(Node, Parent) \
327 OwningStmtResult Transform##Node(Node *S);
Douglas Gregora16548e2009-08-11 05:31:07 +0000328#define EXPR(Node, Parent) \
Douglas Gregorc95a1fa2009-11-04 07:01:15 +0000329 OwningExprResult Transform##Node(Node *E, bool isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +0000330#define ABSTRACT_EXPR(Node, Parent)
331#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +0000332
Douglas Gregord6ff3322009-08-04 16:50:30 +0000333 /// \brief Build a new pointer type given its pointee type.
334 ///
335 /// By default, performs semantic analysis when building the pointer type.
336 /// Subclasses may override this routine to provide different behavior.
John McCall70dd5f62009-10-30 00:06:24 +0000337 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000338
339 /// \brief Build a new block pointer type given its pointee type.
340 ///
Mike Stump11289f42009-09-09 15:08:12 +0000341 /// By default, performs semantic analysis when building the block pointer
Douglas Gregord6ff3322009-08-04 16:50:30 +0000342 /// type. Subclasses may override this routine to provide different behavior.
John McCall70dd5f62009-10-30 00:06:24 +0000343 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000344
John McCall70dd5f62009-10-30 00:06:24 +0000345 /// \brief Build a new reference type given the type it references.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000346 ///
John McCall70dd5f62009-10-30 00:06:24 +0000347 /// By default, performs semantic analysis when building the
348 /// reference type. Subclasses may override this routine to provide
349 /// different behavior.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000350 ///
John McCall70dd5f62009-10-30 00:06:24 +0000351 /// \param LValue whether the type was written with an lvalue sigil
352 /// or an rvalue sigil.
353 QualType RebuildReferenceType(QualType ReferentType,
354 bool LValue,
355 SourceLocation Sigil);
Mike Stump11289f42009-09-09 15:08:12 +0000356
Douglas Gregord6ff3322009-08-04 16:50:30 +0000357 /// \brief Build a new member pointer type given the pointee type and the
358 /// class type it refers into.
359 ///
360 /// By default, performs semantic analysis when building the member pointer
361 /// type. Subclasses may override this routine to provide different behavior.
John McCall70dd5f62009-10-30 00:06:24 +0000362 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
363 SourceLocation Sigil);
Mike Stump11289f42009-09-09 15:08:12 +0000364
John McCall550e0c22009-10-21 00:40:46 +0000365 /// \brief Build a new Objective C object pointer type.
John McCall70dd5f62009-10-30 00:06:24 +0000366 QualType RebuildObjCObjectPointerType(QualType PointeeType,
367 SourceLocation Sigil);
John McCall550e0c22009-10-21 00:40:46 +0000368
Douglas Gregord6ff3322009-08-04 16:50:30 +0000369 /// \brief Build a new array type given the element type, size
370 /// modifier, size of the array (if known), size expression, and index type
371 /// qualifiers.
372 ///
373 /// By default, performs semantic analysis when building the array type.
374 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000375 /// Also by default, all of the other Rebuild*Array
Douglas Gregord6ff3322009-08-04 16:50:30 +0000376 QualType RebuildArrayType(QualType ElementType,
377 ArrayType::ArraySizeModifier SizeMod,
378 const llvm::APInt *Size,
379 Expr *SizeExpr,
380 unsigned IndexTypeQuals,
381 SourceRange BracketsRange);
Mike Stump11289f42009-09-09 15:08:12 +0000382
Douglas Gregord6ff3322009-08-04 16:50:30 +0000383 /// \brief Build a new constant array type given the element type, size
384 /// modifier, (known) size of the array, and index type qualifiers.
385 ///
386 /// By default, performs semantic analysis when building the array type.
387 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000388 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000389 ArrayType::ArraySizeModifier SizeMod,
390 const llvm::APInt &Size,
John McCall70dd5f62009-10-30 00:06:24 +0000391 unsigned IndexTypeQuals,
392 SourceRange BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000393
Douglas Gregord6ff3322009-08-04 16:50:30 +0000394 /// \brief Build a new incomplete array type given the element type, size
395 /// modifier, and index type qualifiers.
396 ///
397 /// By default, performs semantic analysis when building the array type.
398 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000399 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000400 ArrayType::ArraySizeModifier SizeMod,
John McCall70dd5f62009-10-30 00:06:24 +0000401 unsigned IndexTypeQuals,
402 SourceRange BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000403
Mike Stump11289f42009-09-09 15:08:12 +0000404 /// \brief Build a new variable-length array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000405 /// size modifier, size expression, and index type qualifiers.
406 ///
407 /// By default, performs semantic analysis when building the array type.
408 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000409 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000410 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000411 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000412 unsigned IndexTypeQuals,
413 SourceRange BracketsRange);
414
Mike Stump11289f42009-09-09 15:08:12 +0000415 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000416 /// size modifier, size expression, and index type qualifiers.
417 ///
418 /// By default, performs semantic analysis when building the array type.
419 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000420 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000421 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000422 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000423 unsigned IndexTypeQuals,
424 SourceRange BracketsRange);
425
426 /// \brief Build a new vector type given the element type and
427 /// number of elements.
428 ///
429 /// By default, performs semantic analysis when building the vector type.
430 /// Subclasses may override this routine to provide different behavior.
431 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump11289f42009-09-09 15:08:12 +0000432
Douglas Gregord6ff3322009-08-04 16:50:30 +0000433 /// \brief Build a new extended vector type given the element type and
434 /// number of elements.
435 ///
436 /// By default, performs semantic analysis when building the vector type.
437 /// Subclasses may override this routine to provide different behavior.
438 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
439 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000440
441 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregord6ff3322009-08-04 16:50:30 +0000442 /// given the element type and number of elements.
443 ///
444 /// By default, performs semantic analysis when building the vector type.
445 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000446 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +0000447 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000448 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000449
Douglas Gregord6ff3322009-08-04 16:50:30 +0000450 /// \brief Build a new function type.
451 ///
452 /// By default, performs semantic analysis when building the function type.
453 /// Subclasses may override this routine to provide different behavior.
454 QualType RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +0000455 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000456 unsigned NumParamTypes,
457 bool Variadic, unsigned Quals);
Mike Stump11289f42009-09-09 15:08:12 +0000458
John McCall550e0c22009-10-21 00:40:46 +0000459 /// \brief Build a new unprototyped function type.
460 QualType RebuildFunctionNoProtoType(QualType ResultType);
461
Douglas Gregord6ff3322009-08-04 16:50:30 +0000462 /// \brief Build a new typedef type.
463 QualType RebuildTypedefType(TypedefDecl *Typedef) {
464 return SemaRef.Context.getTypeDeclType(Typedef);
465 }
466
467 /// \brief Build a new class/struct/union type.
468 QualType RebuildRecordType(RecordDecl *Record) {
469 return SemaRef.Context.getTypeDeclType(Record);
470 }
471
472 /// \brief Build a new Enum type.
473 QualType RebuildEnumType(EnumDecl *Enum) {
474 return SemaRef.Context.getTypeDeclType(Enum);
475 }
John McCallfcc33b02009-09-05 00:15:47 +0000476
477 /// \brief Build a new elaborated type.
478 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
479 return SemaRef.Context.getElaboratedType(T, Tag);
480 }
Mike Stump11289f42009-09-09 15:08:12 +0000481
482 /// \brief Build a new typeof(expr) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000483 ///
484 /// By default, performs semantic analysis when building the typeof type.
485 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000486 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000487
Mike Stump11289f42009-09-09 15:08:12 +0000488 /// \brief Build a new typeof(type) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000489 ///
490 /// By default, builds a new TypeOfType with the given underlying type.
491 QualType RebuildTypeOfType(QualType Underlying);
492
Mike Stump11289f42009-09-09 15:08:12 +0000493 /// \brief Build a new C++0x decltype type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000494 ///
495 /// By default, performs semantic analysis when building the decltype type.
496 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000497 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump11289f42009-09-09 15:08:12 +0000498
Douglas Gregord6ff3322009-08-04 16:50:30 +0000499 /// \brief Build a new template specialization type.
500 ///
501 /// By default, performs semantic analysis when building the template
502 /// specialization type. Subclasses may override this routine to provide
503 /// different behavior.
504 QualType RebuildTemplateSpecializationType(TemplateName Template,
John McCall0ad16662009-10-29 08:12:44 +0000505 SourceLocation TemplateLoc,
506 SourceLocation LAngleLoc,
507 const TemplateArgumentLoc *Args,
508 unsigned NumArgs,
509 SourceLocation RAngleLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000510
Douglas Gregord6ff3322009-08-04 16:50:30 +0000511 /// \brief Build a new qualified name type.
512 ///
Mike Stump11289f42009-09-09 15:08:12 +0000513 /// By default, builds a new QualifiedNameType type from the
514 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregord6ff3322009-08-04 16:50:30 +0000515 /// this routine to provide different behavior.
516 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
517 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump11289f42009-09-09 15:08:12 +0000518 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000519
520 /// \brief Build a new typename type that refers to a template-id.
521 ///
522 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump11289f42009-09-09 15:08:12 +0000523 /// and the given type. Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000524 /// different behavior.
525 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
526 if (NNS->isDependent())
Mike Stump11289f42009-09-09 15:08:12 +0000527 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000528 cast<TemplateSpecializationType>(T));
Mike Stump11289f42009-09-09 15:08:12 +0000529
Douglas Gregord6ff3322009-08-04 16:50:30 +0000530 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump11289f42009-09-09 15:08:12 +0000531 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000532
533 /// \brief Build a new typename type that refers to an identifier.
534 ///
535 /// By default, performs semantic analysis when building the typename type
Mike Stump11289f42009-09-09 15:08:12 +0000536 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000537 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000538 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall0ad16662009-10-29 08:12:44 +0000539 const IdentifierInfo *Id,
540 SourceRange SR) {
541 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregor1135c352009-08-06 05:28:30 +0000542 }
Mike Stump11289f42009-09-09 15:08:12 +0000543
Douglas Gregor1135c352009-08-06 05:28:30 +0000544 /// \brief Build a new nested-name-specifier given the prefix and an
545 /// identifier that names the next step in the nested-name-specifier.
546 ///
547 /// By default, performs semantic analysis when building the new
548 /// nested-name-specifier. Subclasses may override this routine to provide
549 /// different behavior.
550 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
551 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000552 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000553 QualType ObjectType,
554 NamedDecl *FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +0000555
556 /// \brief Build a new nested-name-specifier given the prefix and the
557 /// namespace named in the next step in the nested-name-specifier.
558 ///
559 /// By default, performs semantic analysis when building the new
560 /// nested-name-specifier. Subclasses may override this routine to provide
561 /// different behavior.
562 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
563 SourceRange Range,
564 NamespaceDecl *NS);
565
566 /// \brief Build a new nested-name-specifier given the prefix and the
567 /// type named in the next step in the nested-name-specifier.
568 ///
569 /// By default, performs semantic analysis when building the new
570 /// nested-name-specifier. Subclasses may override this routine to provide
571 /// different behavior.
572 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
573 SourceRange Range,
574 bool TemplateKW,
575 QualType T);
Douglas Gregor71dc5092009-08-06 06:41:21 +0000576
577 /// \brief Build a new template name given a nested name specifier, a flag
578 /// indicating whether the "template" keyword was provided, and the template
579 /// that the template name refers to.
580 ///
581 /// By default, builds the new template name directly. Subclasses may override
582 /// this routine to provide different behavior.
583 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
584 bool TemplateKW,
585 TemplateDecl *Template);
586
587 /// \brief Build a new template name given a nested name specifier, a flag
588 /// indicating whether the "template" keyword was provided, and a set of
589 /// overloaded function templates.
590 ///
591 /// By default, builds the new template name directly. Subclasses may override
592 /// this routine to provide different behavior.
593 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
594 bool TemplateKW,
595 OverloadedFunctionDecl *Ovl);
Mike Stump11289f42009-09-09 15:08:12 +0000596
Douglas Gregor71dc5092009-08-06 06:41:21 +0000597 /// \brief Build a new template name given a nested name specifier and the
598 /// name that is referred to as a template.
599 ///
600 /// By default, performs semantic analysis to determine whether the name can
601 /// be resolved to a specific template, then builds the appropriate kind of
602 /// template name. Subclasses may override this routine to provide different
603 /// behavior.
604 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +0000605 const IdentifierInfo &II,
606 QualType ObjectType);
Mike Stump11289f42009-09-09 15:08:12 +0000607
Douglas Gregor71395fa2009-11-04 00:56:37 +0000608 /// \brief Build a new template name given a nested name specifier and the
609 /// overloaded operator name that is referred to as a template.
610 ///
611 /// By default, performs semantic analysis to determine whether the name can
612 /// be resolved to a specific template, then builds the appropriate kind of
613 /// template name. Subclasses may override this routine to provide different
614 /// behavior.
615 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
616 OverloadedOperatorKind Operator,
617 QualType ObjectType);
618
Douglas Gregorebe10102009-08-20 07:17:43 +0000619 /// \brief Build a new compound statement.
620 ///
621 /// By default, performs semantic analysis to build the new statement.
622 /// Subclasses may override this routine to provide different behavior.
623 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
624 MultiStmtArg Statements,
625 SourceLocation RBraceLoc,
626 bool IsStmtExpr) {
627 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
628 IsStmtExpr);
629 }
630
631 /// \brief Build a new case statement.
632 ///
633 /// By default, performs semantic analysis to build the new statement.
634 /// Subclasses may override this routine to provide different behavior.
635 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
636 ExprArg LHS,
637 SourceLocation EllipsisLoc,
638 ExprArg RHS,
639 SourceLocation ColonLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000640 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregorebe10102009-08-20 07:17:43 +0000641 ColonLoc);
642 }
Mike Stump11289f42009-09-09 15:08:12 +0000643
Douglas Gregorebe10102009-08-20 07:17:43 +0000644 /// \brief Attach the body to a new case statement.
645 ///
646 /// By default, performs semantic analysis to build the new statement.
647 /// Subclasses may override this routine to provide different behavior.
648 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
649 getSema().ActOnCaseStmtBody(S.get(), move(Body));
650 return move(S);
651 }
Mike Stump11289f42009-09-09 15:08:12 +0000652
Douglas Gregorebe10102009-08-20 07:17:43 +0000653 /// \brief Build a new default statement.
654 ///
655 /// By default, performs semantic analysis to build the new statement.
656 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000657 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000658 SourceLocation ColonLoc,
659 StmtArg SubStmt) {
Mike Stump11289f42009-09-09 15:08:12 +0000660 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregorebe10102009-08-20 07:17:43 +0000661 /*CurScope=*/0);
662 }
Mike Stump11289f42009-09-09 15:08:12 +0000663
Douglas Gregorebe10102009-08-20 07:17:43 +0000664 /// \brief Build a new label statement.
665 ///
666 /// By default, performs semantic analysis to build the new statement.
667 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000668 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000669 IdentifierInfo *Id,
670 SourceLocation ColonLoc,
671 StmtArg SubStmt) {
672 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
673 }
Mike Stump11289f42009-09-09 15:08:12 +0000674
Douglas Gregorebe10102009-08-20 07:17:43 +0000675 /// \brief Build a new "if" statement.
676 ///
677 /// By default, performs semantic analysis to build the new statement.
678 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000679 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
680 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000681 StmtArg Else) {
682 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
683 }
Mike Stump11289f42009-09-09 15:08:12 +0000684
Douglas Gregorebe10102009-08-20 07:17:43 +0000685 /// \brief Start building a new switch statement.
686 ///
687 /// By default, performs semantic analysis to build the new statement.
688 /// Subclasses may override this routine to provide different behavior.
689 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
690 return getSema().ActOnStartOfSwitchStmt(move(Cond));
691 }
Mike Stump11289f42009-09-09 15:08:12 +0000692
Douglas Gregorebe10102009-08-20 07:17:43 +0000693 /// \brief Attach the body to the switch statement.
694 ///
695 /// By default, performs semantic analysis to build the new statement.
696 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000697 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000698 StmtArg Switch, StmtArg Body) {
699 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
700 move(Body));
701 }
702
703 /// \brief Build a new while statement.
704 ///
705 /// By default, performs semantic analysis to build the new statement.
706 /// Subclasses may override this routine to provide different behavior.
707 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
708 Sema::FullExprArg Cond,
709 StmtArg Body) {
710 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
711 }
Mike Stump11289f42009-09-09 15:08:12 +0000712
Douglas Gregorebe10102009-08-20 07:17:43 +0000713 /// \brief Build a new do-while statement.
714 ///
715 /// By default, performs semantic analysis to build the new statement.
716 /// Subclasses may override this routine to provide different behavior.
717 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
718 SourceLocation WhileLoc,
719 SourceLocation LParenLoc,
720 ExprArg Cond,
721 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000722 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000723 move(Cond), RParenLoc);
724 }
725
726 /// \brief Build a new for statement.
727 ///
728 /// By default, performs semantic analysis to build the new statement.
729 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000730 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000731 SourceLocation LParenLoc,
732 StmtArg Init, ExprArg Cond, ExprArg Inc,
733 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump11289f42009-09-09 15:08:12 +0000734 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregorebe10102009-08-20 07:17:43 +0000735 move(Inc), RParenLoc, move(Body));
736 }
Mike Stump11289f42009-09-09 15:08:12 +0000737
Douglas Gregorebe10102009-08-20 07:17:43 +0000738 /// \brief Build a new goto statement.
739 ///
740 /// By default, performs semantic analysis to build the new statement.
741 /// Subclasses may override this routine to provide different behavior.
742 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
743 SourceLocation LabelLoc,
744 LabelStmt *Label) {
745 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
746 }
747
748 /// \brief Build a new indirect goto statement.
749 ///
750 /// By default, performs semantic analysis to build the new statement.
751 /// Subclasses may override this routine to provide different behavior.
752 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
753 SourceLocation StarLoc,
754 ExprArg Target) {
755 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
756 }
Mike Stump11289f42009-09-09 15:08:12 +0000757
Douglas Gregorebe10102009-08-20 07:17:43 +0000758 /// \brief Build a new return statement.
759 ///
760 /// By default, performs semantic analysis to build the new statement.
761 /// Subclasses may override this routine to provide different behavior.
762 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
763 ExprArg Result) {
Mike Stump11289f42009-09-09 15:08:12 +0000764
Douglas Gregorebe10102009-08-20 07:17:43 +0000765 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
766 }
Mike Stump11289f42009-09-09 15:08:12 +0000767
Douglas Gregorebe10102009-08-20 07:17:43 +0000768 /// \brief Build a new declaration statement.
769 ///
770 /// By default, performs semantic analysis to build the new statement.
771 /// Subclasses may override this routine to provide different behavior.
772 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump11289f42009-09-09 15:08:12 +0000773 SourceLocation StartLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000774 SourceLocation EndLoc) {
775 return getSema().Owned(
776 new (getSema().Context) DeclStmt(
777 DeclGroupRef::Create(getSema().Context,
778 Decls, NumDecls),
779 StartLoc, EndLoc));
780 }
Mike Stump11289f42009-09-09 15:08:12 +0000781
Douglas Gregorebe10102009-08-20 07:17:43 +0000782 /// \brief Build a new C++ exception declaration.
783 ///
784 /// By default, performs semantic analysis to build the new decaration.
785 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000786 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregorebe10102009-08-20 07:17:43 +0000787 DeclaratorInfo *Declarator,
788 IdentifierInfo *Name,
789 SourceLocation Loc,
790 SourceRange TypeRange) {
Mike Stump11289f42009-09-09 15:08:12 +0000791 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000792 TypeRange);
793 }
794
795 /// \brief Build a new C++ catch statement.
796 ///
797 /// By default, performs semantic analysis to build the new statement.
798 /// Subclasses may override this routine to provide different behavior.
799 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
800 VarDecl *ExceptionDecl,
801 StmtArg Handler) {
802 return getSema().Owned(
Mike Stump11289f42009-09-09 15:08:12 +0000803 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregorebe10102009-08-20 07:17:43 +0000804 Handler.takeAs<Stmt>()));
805 }
Mike Stump11289f42009-09-09 15:08:12 +0000806
Douglas Gregorebe10102009-08-20 07:17:43 +0000807 /// \brief Build a new C++ try statement.
808 ///
809 /// By default, performs semantic analysis to build the new statement.
810 /// Subclasses may override this routine to provide different behavior.
811 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
812 StmtArg TryBlock,
813 MultiStmtArg Handlers) {
814 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
815 }
Mike Stump11289f42009-09-09 15:08:12 +0000816
Douglas Gregora16548e2009-08-11 05:31:07 +0000817 /// \brief Build a new expression that references a declaration.
818 ///
819 /// By default, performs semantic analysis to build the new expression.
820 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000821 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
822 SourceRange QualifierRange,
Douglas Gregorc95a1fa2009-11-04 07:01:15 +0000823 NamedDecl *ND, SourceLocation Loc,
824 bool isAddressOfOperand) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000825 CXXScopeSpec SS;
826 SS.setScopeRep(Qualifier);
827 SS.setRange(QualifierRange);
Douglas Gregora16548e2009-08-11 05:31:07 +0000828 return getSema().BuildDeclarationNameExpr(Loc, ND,
829 /*FIXME:*/false,
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000830 &SS,
Douglas Gregorc95a1fa2009-11-04 07:01:15 +0000831 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +0000832 }
Mike Stump11289f42009-09-09 15:08:12 +0000833
Douglas Gregora16548e2009-08-11 05:31:07 +0000834 /// \brief Build a new expression in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +0000835 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000836 /// By default, performs semantic analysis to build the new expression.
837 /// Subclasses may override this routine to provide different behavior.
838 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
839 SourceLocation RParen) {
840 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
841 }
842
Douglas Gregorad8a3362009-09-04 17:36:40 +0000843 /// \brief Build a new pseudo-destructor expression.
Mike Stump11289f42009-09-09 15:08:12 +0000844 ///
Douglas Gregorad8a3362009-09-04 17:36:40 +0000845 /// By default, performs semantic analysis to build the new expression.
846 /// Subclasses may override this routine to provide different behavior.
847 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
848 SourceLocation OperatorLoc,
849 bool isArrow,
850 SourceLocation DestroyedTypeLoc,
851 QualType DestroyedType,
852 NestedNameSpecifier *Qualifier,
853 SourceRange QualifierRange) {
854 CXXScopeSpec SS;
855 if (Qualifier) {
856 SS.setRange(QualifierRange);
857 SS.setScopeRep(Qualifier);
858 }
859
Mike Stump11289f42009-09-09 15:08:12 +0000860 DeclarationName Name
Douglas Gregorad8a3362009-09-04 17:36:40 +0000861 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
862 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump11289f42009-09-09 15:08:12 +0000863
864 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorad8a3362009-09-04 17:36:40 +0000865 OperatorLoc,
866 isArrow? tok::arrow : tok::period,
867 DestroyedTypeLoc,
868 Name,
869 Sema::DeclPtrTy::make((Decl *)0),
870 &SS);
Mike Stump11289f42009-09-09 15:08:12 +0000871 }
872
Douglas Gregora16548e2009-08-11 05:31:07 +0000873 /// \brief Build a new unary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000874 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000875 /// By default, performs semantic analysis to build the new expression.
876 /// Subclasses may override this routine to provide different behavior.
877 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
878 UnaryOperator::Opcode Opc,
879 ExprArg SubExpr) {
880 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
881 }
Mike Stump11289f42009-09-09 15:08:12 +0000882
Douglas Gregora16548e2009-08-11 05:31:07 +0000883 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump11289f42009-09-09 15:08:12 +0000884 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000885 /// By default, performs semantic analysis to build the new expression.
886 /// Subclasses may override this routine to provide different behavior.
887 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
888 bool isSizeOf, SourceRange R) {
889 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
890 }
891
Mike Stump11289f42009-09-09 15:08:12 +0000892 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000893 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000894 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000895 /// By default, performs semantic analysis to build the new expression.
896 /// Subclasses may override this routine to provide different behavior.
897 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
898 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000899 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000900 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
901 OpLoc, isSizeOf, R);
902 if (Result.isInvalid())
903 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000904
Douglas Gregora16548e2009-08-11 05:31:07 +0000905 SubExpr.release();
906 return move(Result);
907 }
Mike Stump11289f42009-09-09 15:08:12 +0000908
Douglas Gregora16548e2009-08-11 05:31:07 +0000909 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000910 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000911 /// By default, performs semantic analysis to build the new expression.
912 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000913 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000914 SourceLocation LBracketLoc,
915 ExprArg RHS,
916 SourceLocation RBracketLoc) {
917 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000918 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000919 RBracketLoc);
920 }
921
922 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000923 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000924 /// By default, performs semantic analysis to build the new expression.
925 /// Subclasses may override this routine to provide different behavior.
926 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
927 MultiExprArg Args,
928 SourceLocation *CommaLocs,
929 SourceLocation RParenLoc) {
930 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
931 move(Args), CommaLocs, RParenLoc);
932 }
933
934 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000935 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000936 /// By default, performs semantic analysis to build the new expression.
937 /// Subclasses may override this routine to provide different behavior.
938 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000939 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000940 NestedNameSpecifier *Qualifier,
941 SourceRange QualifierRange,
942 SourceLocation MemberLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000943 NamedDecl *Member) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000944 if (!Member->getDeclName()) {
945 // We have a reference to an unnamed field.
946 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000947
948 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000949 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
950 Member, MemberLoc,
951 cast<FieldDecl>(Member)->getType());
952 return getSema().Owned(ME);
953 }
Mike Stump11289f42009-09-09 15:08:12 +0000954
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000955 CXXScopeSpec SS;
956 if (Qualifier) {
957 SS.setRange(QualifierRange);
958 SS.setScopeRep(Qualifier);
959 }
960
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000961 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000962 isArrow? tok::arrow : tok::period,
963 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000964 Member->getDeclName(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000965 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
966 &SS);
Douglas Gregora16548e2009-08-11 05:31:07 +0000967 }
Mike Stump11289f42009-09-09 15:08:12 +0000968
Douglas Gregora16548e2009-08-11 05:31:07 +0000969 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000970 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000971 /// By default, performs semantic analysis to build the new expression.
972 /// Subclasses may override this routine to provide different behavior.
973 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
974 BinaryOperator::Opcode Opc,
975 ExprArg LHS, ExprArg RHS) {
976 OwningExprResult Result
Mike Stump11289f42009-09-09 15:08:12 +0000977 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +0000978 (Expr *)RHS.get());
979 if (Result.isInvalid())
980 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000981
Douglas Gregora16548e2009-08-11 05:31:07 +0000982 LHS.release();
983 RHS.release();
984 return move(Result);
985 }
986
987 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000988 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000989 /// By default, performs semantic analysis to build the new expression.
990 /// Subclasses may override this routine to provide different behavior.
991 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
992 SourceLocation QuestionLoc,
993 ExprArg LHS,
994 SourceLocation ColonLoc,
995 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +0000996 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +0000997 move(LHS), move(RHS));
998 }
999
1000 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +00001001 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001002 /// By default, builds a new implicit cast without any semantic analysis.
1003 /// Subclasses may override this routine to provide different behavior.
1004 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
1005 ExprArg SubExpr, bool isLvalue) {
1006 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +00001007 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +00001008 (Expr *)SubExpr.release(),
1009 isLvalue);
1010 return getSema().Owned(ICE);
1011 }
1012
1013 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +00001014 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001015 /// By default, performs semantic analysis to build the new expression.
1016 /// Subclasses may override this routine to provide different behavior.
1017 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1018 QualType ExplicitTy,
1019 SourceLocation RParenLoc,
1020 ExprArg SubExpr) {
1021 return getSema().ActOnCastExpr(/*Scope=*/0,
1022 LParenLoc,
1023 ExplicitTy.getAsOpaquePtr(),
1024 RParenLoc,
1025 move(SubExpr));
1026 }
Mike Stump11289f42009-09-09 15:08:12 +00001027
Douglas Gregora16548e2009-08-11 05:31:07 +00001028 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +00001029 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001030 /// By default, performs semantic analysis to build the new expression.
1031 /// Subclasses may override this routine to provide different behavior.
1032 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1033 QualType T,
1034 SourceLocation RParenLoc,
1035 ExprArg Init) {
1036 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1037 RParenLoc, move(Init));
1038 }
Mike Stump11289f42009-09-09 15:08:12 +00001039
Douglas Gregora16548e2009-08-11 05:31:07 +00001040 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +00001041 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001042 /// By default, performs semantic analysis to build the new expression.
1043 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001044 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001045 SourceLocation OpLoc,
1046 SourceLocation AccessorLoc,
1047 IdentifierInfo &Accessor) {
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001048 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001049 tok::period, AccessorLoc,
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001050 DeclarationName(&Accessor),
Douglas Gregora16548e2009-08-11 05:31:07 +00001051 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1052 }
Mike Stump11289f42009-09-09 15:08:12 +00001053
Douglas Gregora16548e2009-08-11 05:31:07 +00001054 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001055 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001056 /// By default, performs semantic analysis to build the new expression.
1057 /// Subclasses may override this routine to provide different behavior.
1058 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1059 MultiExprArg Inits,
1060 SourceLocation RBraceLoc) {
1061 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1062 }
Mike Stump11289f42009-09-09 15:08:12 +00001063
Douglas Gregora16548e2009-08-11 05:31:07 +00001064 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001065 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001066 /// By default, performs semantic analysis to build the new expression.
1067 /// Subclasses may override this routine to provide different behavior.
1068 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1069 MultiExprArg ArrayExprs,
1070 SourceLocation EqualOrColonLoc,
1071 bool GNUSyntax,
1072 ExprArg Init) {
1073 OwningExprResult Result
1074 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1075 move(Init));
1076 if (Result.isInvalid())
1077 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001078
Douglas Gregora16548e2009-08-11 05:31:07 +00001079 ArrayExprs.release();
1080 return move(Result);
1081 }
Mike Stump11289f42009-09-09 15:08:12 +00001082
Douglas Gregora16548e2009-08-11 05:31:07 +00001083 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001084 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001085 /// By default, builds the implicit value initialization without performing
1086 /// any semantic analysis. Subclasses may override this routine to provide
1087 /// different behavior.
1088 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1089 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1090 }
Mike Stump11289f42009-09-09 15:08:12 +00001091
Douglas Gregora16548e2009-08-11 05:31:07 +00001092 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001093 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001094 /// By default, performs semantic analysis to build the new expression.
1095 /// Subclasses may override this routine to provide different behavior.
1096 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1097 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001098 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001099 RParenLoc);
1100 }
1101
1102 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001103 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001104 /// By default, performs semantic analysis to build the new expression.
1105 /// Subclasses may override this routine to provide different behavior.
1106 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1107 MultiExprArg SubExprs,
1108 SourceLocation RParenLoc) {
1109 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1110 }
Mike Stump11289f42009-09-09 15:08:12 +00001111
Douglas Gregora16548e2009-08-11 05:31:07 +00001112 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001113 ///
1114 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001115 /// rather than attempting to map the label statement itself.
1116 /// Subclasses may override this routine to provide different behavior.
1117 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1118 SourceLocation LabelLoc,
1119 LabelStmt *Label) {
1120 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1121 }
Mike Stump11289f42009-09-09 15:08:12 +00001122
Douglas Gregora16548e2009-08-11 05:31:07 +00001123 /// \brief Build a new GNU statement expression.
Mike Stump11289f42009-09-09 15:08:12 +00001124 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001125 /// By default, performs semantic analysis to build the new expression.
1126 /// Subclasses may override this routine to provide different behavior.
1127 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1128 StmtArg SubStmt,
1129 SourceLocation RParenLoc) {
1130 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1131 }
Mike Stump11289f42009-09-09 15:08:12 +00001132
Douglas Gregora16548e2009-08-11 05:31:07 +00001133 /// \brief Build a new __builtin_types_compatible_p expression.
1134 ///
1135 /// By default, performs semantic analysis to build the new expression.
1136 /// Subclasses may override this routine to provide different behavior.
1137 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1138 QualType T1, QualType T2,
1139 SourceLocation RParenLoc) {
1140 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1141 T1.getAsOpaquePtr(),
1142 T2.getAsOpaquePtr(),
1143 RParenLoc);
1144 }
Mike Stump11289f42009-09-09 15:08:12 +00001145
Douglas Gregora16548e2009-08-11 05:31:07 +00001146 /// \brief Build a new __builtin_choose_expr expression.
1147 ///
1148 /// By default, performs semantic analysis to build the new expression.
1149 /// Subclasses may override this routine to provide different behavior.
1150 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1151 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1152 SourceLocation RParenLoc) {
1153 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1154 move(Cond), move(LHS), move(RHS),
1155 RParenLoc);
1156 }
Mike Stump11289f42009-09-09 15:08:12 +00001157
Douglas Gregora16548e2009-08-11 05:31:07 +00001158 /// \brief Build a new overloaded operator call expression.
1159 ///
1160 /// By default, performs semantic analysis to build the new expression.
1161 /// The semantic analysis provides the behavior of template instantiation,
1162 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001163 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001164 /// argument-dependent lookup, etc. Subclasses may override this routine to
1165 /// provide different behavior.
1166 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1167 SourceLocation OpLoc,
1168 ExprArg Callee,
1169 ExprArg First,
1170 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001171
1172 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001173 /// reinterpret_cast.
1174 ///
1175 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001176 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001177 /// Subclasses may override this routine to provide different behavior.
1178 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1179 Stmt::StmtClass Class,
1180 SourceLocation LAngleLoc,
1181 QualType T,
1182 SourceLocation RAngleLoc,
1183 SourceLocation LParenLoc,
1184 ExprArg SubExpr,
1185 SourceLocation RParenLoc) {
1186 switch (Class) {
1187 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001188 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1189 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001190 move(SubExpr), RParenLoc);
1191
1192 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001193 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1194 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001195 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001196
Douglas Gregora16548e2009-08-11 05:31:07 +00001197 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001198 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1199 RAngleLoc, LParenLoc,
1200 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001201 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001202
Douglas Gregora16548e2009-08-11 05:31:07 +00001203 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001204 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1205 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001206 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001207
Douglas Gregora16548e2009-08-11 05:31:07 +00001208 default:
1209 assert(false && "Invalid C++ named cast");
1210 break;
1211 }
Mike Stump11289f42009-09-09 15:08:12 +00001212
Douglas Gregora16548e2009-08-11 05:31:07 +00001213 return getSema().ExprError();
1214 }
Mike Stump11289f42009-09-09 15:08:12 +00001215
Douglas Gregora16548e2009-08-11 05:31:07 +00001216 /// \brief Build a new C++ static_cast expression.
1217 ///
1218 /// By default, performs semantic analysis to build the new expression.
1219 /// Subclasses may override this routine to provide different behavior.
1220 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1221 SourceLocation LAngleLoc,
1222 QualType T,
1223 SourceLocation RAngleLoc,
1224 SourceLocation LParenLoc,
1225 ExprArg SubExpr,
1226 SourceLocation RParenLoc) {
1227 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001228 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001229 LParenLoc, move(SubExpr), RParenLoc);
1230 }
1231
1232 /// \brief Build a new C++ dynamic_cast expression.
1233 ///
1234 /// By default, performs semantic analysis to build the new expression.
1235 /// Subclasses may override this routine to provide different behavior.
1236 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1237 SourceLocation LAngleLoc,
1238 QualType T,
1239 SourceLocation RAngleLoc,
1240 SourceLocation LParenLoc,
1241 ExprArg SubExpr,
1242 SourceLocation RParenLoc) {
1243 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001244 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001245 LParenLoc, move(SubExpr), RParenLoc);
1246 }
1247
1248 /// \brief Build a new C++ reinterpret_cast expression.
1249 ///
1250 /// By default, performs semantic analysis to build the new expression.
1251 /// Subclasses may override this routine to provide different behavior.
1252 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1253 SourceLocation LAngleLoc,
1254 QualType T,
1255 SourceLocation RAngleLoc,
1256 SourceLocation LParenLoc,
1257 ExprArg SubExpr,
1258 SourceLocation RParenLoc) {
1259 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1260 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1261 LParenLoc, move(SubExpr), RParenLoc);
1262 }
1263
1264 /// \brief Build a new C++ const_cast expression.
1265 ///
1266 /// By default, performs semantic analysis to build the new expression.
1267 /// Subclasses may override this routine to provide different behavior.
1268 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1269 SourceLocation LAngleLoc,
1270 QualType T,
1271 SourceLocation RAngleLoc,
1272 SourceLocation LParenLoc,
1273 ExprArg SubExpr,
1274 SourceLocation RParenLoc) {
1275 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001276 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001277 LParenLoc, move(SubExpr), RParenLoc);
1278 }
Mike Stump11289f42009-09-09 15:08:12 +00001279
Douglas Gregora16548e2009-08-11 05:31:07 +00001280 /// \brief Build a new C++ functional-style cast expression.
1281 ///
1282 /// By default, performs semantic analysis to build the new expression.
1283 /// Subclasses may override this routine to provide different behavior.
1284 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1285 QualType T,
1286 SourceLocation LParenLoc,
1287 ExprArg SubExpr,
1288 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001289 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001290 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1291 T.getAsOpaquePtr(),
1292 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001293 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001294 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001295 RParenLoc);
1296 }
Mike Stump11289f42009-09-09 15:08:12 +00001297
Douglas Gregora16548e2009-08-11 05:31:07 +00001298 /// \brief Build a new C++ typeid(type) expression.
1299 ///
1300 /// By default, performs semantic analysis to build the new expression.
1301 /// Subclasses may override this routine to provide different behavior.
1302 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1303 SourceLocation LParenLoc,
1304 QualType T,
1305 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001306 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001307 T.getAsOpaquePtr(), RParenLoc);
1308 }
Mike Stump11289f42009-09-09 15:08:12 +00001309
Douglas Gregora16548e2009-08-11 05:31:07 +00001310 /// \brief Build a new C++ typeid(expr) expression.
1311 ///
1312 /// By default, performs semantic analysis to build the new expression.
1313 /// Subclasses may override this routine to provide different behavior.
1314 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1315 SourceLocation LParenLoc,
1316 ExprArg Operand,
1317 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001318 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001319 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1320 RParenLoc);
1321 if (Result.isInvalid())
1322 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001323
Douglas Gregora16548e2009-08-11 05:31:07 +00001324 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1325 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001326 }
1327
Douglas Gregora16548e2009-08-11 05:31:07 +00001328 /// \brief Build a new C++ "this" expression.
1329 ///
1330 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001331 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001332 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001333 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001334 QualType ThisType) {
1335 return getSema().Owned(
1336 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1337 }
1338
1339 /// \brief Build a new C++ throw expression.
1340 ///
1341 /// By default, performs semantic analysis to build the new expression.
1342 /// Subclasses may override this routine to provide different behavior.
1343 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1344 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1345 }
1346
1347 /// \brief Build a new C++ default-argument expression.
1348 ///
1349 /// By default, builds a new default-argument expression, which does not
1350 /// require any semantic analysis. Subclasses may override this routine to
1351 /// provide different behavior.
1352 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001353 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001354 }
1355
1356 /// \brief Build a new C++ zero-initialization expression.
1357 ///
1358 /// By default, performs semantic analysis to build the new expression.
1359 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001360 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001361 SourceLocation LParenLoc,
1362 QualType T,
1363 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001364 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1365 T.getAsOpaquePtr(), LParenLoc,
1366 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001367 0, RParenLoc);
1368 }
Mike Stump11289f42009-09-09 15:08:12 +00001369
Douglas Gregora16548e2009-08-11 05:31:07 +00001370 /// \brief Build a new C++ conditional declaration expression.
1371 ///
1372 /// By default, performs semantic analysis to build the new expression.
1373 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001374 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001375 SourceLocation EqLoc,
1376 VarDecl *Var) {
1377 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1378 EqLoc,
1379 Var));
1380 }
Mike Stump11289f42009-09-09 15:08:12 +00001381
Douglas Gregora16548e2009-08-11 05:31:07 +00001382 /// \brief Build a new C++ "new" expression.
1383 ///
1384 /// By default, performs semantic analysis to build the new expression.
1385 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001386 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001387 bool UseGlobal,
1388 SourceLocation PlacementLParen,
1389 MultiExprArg PlacementArgs,
1390 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001391 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001392 QualType AllocType,
1393 SourceLocation TypeLoc,
1394 SourceRange TypeRange,
1395 ExprArg ArraySize,
1396 SourceLocation ConstructorLParen,
1397 MultiExprArg ConstructorArgs,
1398 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001399 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001400 PlacementLParen,
1401 move(PlacementArgs),
1402 PlacementRParen,
1403 ParenTypeId,
1404 AllocType,
1405 TypeLoc,
1406 TypeRange,
1407 move(ArraySize),
1408 ConstructorLParen,
1409 move(ConstructorArgs),
1410 ConstructorRParen);
1411 }
Mike Stump11289f42009-09-09 15:08:12 +00001412
Douglas Gregora16548e2009-08-11 05:31:07 +00001413 /// \brief Build a new C++ "delete" expression.
1414 ///
1415 /// By default, performs semantic analysis to build the new expression.
1416 /// Subclasses may override this routine to provide different behavior.
1417 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1418 bool IsGlobalDelete,
1419 bool IsArrayForm,
1420 ExprArg Operand) {
1421 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1422 move(Operand));
1423 }
Mike Stump11289f42009-09-09 15:08:12 +00001424
Douglas Gregora16548e2009-08-11 05:31:07 +00001425 /// \brief Build a new unary type trait expression.
1426 ///
1427 /// By default, performs semantic analysis to build the new expression.
1428 /// Subclasses may override this routine to provide different behavior.
1429 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1430 SourceLocation StartLoc,
1431 SourceLocation LParenLoc,
1432 QualType T,
1433 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001434 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001435 T.getAsOpaquePtr(), RParenLoc);
1436 }
1437
Mike Stump11289f42009-09-09 15:08:12 +00001438 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001439 /// expression.
1440 ///
1441 /// By default, performs semantic analysis to build the new expression.
1442 /// Subclasses may override this routine to provide different behavior.
1443 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1444 SourceRange QualifierRange,
1445 DeclarationName Name,
1446 SourceLocation Location,
1447 bool IsAddressOfOperand) {
1448 CXXScopeSpec SS;
1449 SS.setRange(QualifierRange);
1450 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001451 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001452 Location,
1453 Name,
1454 /*Trailing lparen=*/false,
1455 &SS,
1456 IsAddressOfOperand);
1457 }
1458
1459 /// \brief Build a new template-id expression.
1460 ///
1461 /// By default, performs semantic analysis to build the new expression.
1462 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001463 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1464 SourceRange QualifierRange,
1465 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001466 SourceLocation TemplateLoc,
1467 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001468 TemplateArgumentLoc *TemplateArgs,
Douglas Gregora16548e2009-08-11 05:31:07 +00001469 unsigned NumTemplateArgs,
1470 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001471 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1472 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001473 LAngleLoc,
1474 TemplateArgs, NumTemplateArgs,
1475 RAngleLoc);
1476 }
1477
1478 /// \brief Build a new object-construction expression.
1479 ///
1480 /// By default, performs semantic analysis to build the new expression.
1481 /// Subclasses may override this routine to provide different behavior.
1482 OwningExprResult RebuildCXXConstructExpr(QualType T,
1483 CXXConstructorDecl *Constructor,
1484 bool IsElidable,
1485 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001486 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1487 SourceLocation(),
1488 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001489 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001490 }
1491
1492 /// \brief Build a new object-construction expression.
1493 ///
1494 /// By default, performs semantic analysis to build the new expression.
1495 /// Subclasses may override this routine to provide different behavior.
1496 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1497 QualType T,
1498 SourceLocation LParenLoc,
1499 MultiExprArg Args,
1500 SourceLocation *Commas,
1501 SourceLocation RParenLoc) {
1502 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1503 T.getAsOpaquePtr(),
1504 LParenLoc,
1505 move(Args),
1506 Commas,
1507 RParenLoc);
1508 }
1509
1510 /// \brief Build a new object-construction expression.
1511 ///
1512 /// By default, performs semantic analysis to build the new expression.
1513 /// Subclasses may override this routine to provide different behavior.
1514 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1515 QualType T,
1516 SourceLocation LParenLoc,
1517 MultiExprArg Args,
1518 SourceLocation *Commas,
1519 SourceLocation RParenLoc) {
1520 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1521 /*FIXME*/LParenLoc),
1522 T.getAsOpaquePtr(),
1523 LParenLoc,
1524 move(Args),
1525 Commas,
1526 RParenLoc);
1527 }
Mike Stump11289f42009-09-09 15:08:12 +00001528
Douglas Gregora16548e2009-08-11 05:31:07 +00001529 /// \brief Build a new member reference expression.
1530 ///
1531 /// By default, performs semantic analysis to build the new expression.
1532 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001533 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001534 bool IsArrow,
1535 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001536 NestedNameSpecifier *Qualifier,
1537 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001538 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001539 SourceLocation MemberLoc,
1540 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001541 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001542 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001543
Douglas Gregora16548e2009-08-11 05:31:07 +00001544 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001545 SS.setRange(QualifierRange);
1546 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001547
Douglas Gregor308047d2009-09-09 00:23:06 +00001548 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001549 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001550 MemberLoc,
1551 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001552 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001553 &SS,
1554 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001555 }
1556
Douglas Gregor308047d2009-09-09 00:23:06 +00001557 /// \brief Build a new member reference expression with explicit template
1558 /// arguments.
1559 ///
1560 /// By default, performs semantic analysis to build the new expression.
1561 /// Subclasses may override this routine to provide different behavior.
1562 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1563 bool IsArrow,
1564 SourceLocation OperatorLoc,
1565 NestedNameSpecifier *Qualifier,
1566 SourceRange QualifierRange,
1567 TemplateName Template,
1568 SourceLocation TemplateNameLoc,
1569 NamedDecl *FirstQualifierInScope,
1570 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001571 const TemplateArgumentLoc *TemplateArgs,
Douglas Gregor308047d2009-09-09 00:23:06 +00001572 unsigned NumTemplateArgs,
1573 SourceLocation RAngleLoc) {
1574 OwningExprResult Base = move(BaseE);
1575 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001576
Douglas Gregor308047d2009-09-09 00:23:06 +00001577 CXXScopeSpec SS;
1578 SS.setRange(QualifierRange);
1579 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001580
Douglas Gregor308047d2009-09-09 00:23:06 +00001581 // FIXME: We're going to end up looking up the template based on its name,
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001582 // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
Douglas Gregor308047d2009-09-09 00:23:06 +00001583 DeclarationName Name;
1584 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1585 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001586 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001587 = Template.getAsOverloadedFunctionDecl())
1588 Name = Ovl->getDeclName();
Douglas Gregor71395fa2009-11-04 00:56:37 +00001589 else {
1590 DependentTemplateName *DTN = Template.getAsDependentTemplateName();
1591 if (DTN->isIdentifier())
1592 Name = DTN->getIdentifier();
1593 else
1594 Name = SemaRef.Context.DeclarationNames.getCXXOperatorName(
1595 DTN->getOperator());
1596 }
Mike Stump11289f42009-09-09 15:08:12 +00001597 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001598 OperatorLoc, OpKind,
1599 TemplateNameLoc, Name, true,
1600 LAngleLoc, TemplateArgs,
1601 NumTemplateArgs, RAngleLoc,
1602 Sema::DeclPtrTy(), &SS);
1603 }
Mike Stump11289f42009-09-09 15:08:12 +00001604
Douglas Gregora16548e2009-08-11 05:31:07 +00001605 /// \brief Build a new Objective-C @encode expression.
1606 ///
1607 /// By default, performs semantic analysis to build the new expression.
1608 /// Subclasses may override this routine to provide different behavior.
1609 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1610 QualType T,
1611 SourceLocation RParenLoc) {
1612 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1613 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001614 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001615
1616 /// \brief Build a new Objective-C protocol expression.
1617 ///
1618 /// By default, performs semantic analysis to build the new expression.
1619 /// Subclasses may override this routine to provide different behavior.
1620 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1621 SourceLocation AtLoc,
1622 SourceLocation ProtoLoc,
1623 SourceLocation LParenLoc,
1624 SourceLocation RParenLoc) {
1625 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1626 Protocol->getIdentifier(),
1627 AtLoc,
1628 ProtoLoc,
1629 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001630 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001631 }
Mike Stump11289f42009-09-09 15:08:12 +00001632
Douglas Gregora16548e2009-08-11 05:31:07 +00001633 /// \brief Build a new shuffle vector expression.
1634 ///
1635 /// By default, performs semantic analysis to build the new expression.
1636 /// Subclasses may override this routine to provide different behavior.
1637 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1638 MultiExprArg SubExprs,
1639 SourceLocation RParenLoc) {
1640 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001641 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001642 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1643 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1644 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1645 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001646
Douglas Gregora16548e2009-08-11 05:31:07 +00001647 // Build a reference to the __builtin_shufflevector builtin
1648 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001649 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001650 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1651 BuiltinLoc, false, false);
1652 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001653
1654 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001655 unsigned NumSubExprs = SubExprs.size();
1656 Expr **Subs = (Expr **)SubExprs.release();
1657 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1658 Subs, NumSubExprs,
1659 Builtin->getResultType(),
1660 RParenLoc);
1661 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001662
Douglas Gregora16548e2009-08-11 05:31:07 +00001663 // Type-check the __builtin_shufflevector expression.
1664 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1665 if (Result.isInvalid())
1666 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001667
Douglas Gregora16548e2009-08-11 05:31:07 +00001668 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001669 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001670 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001671};
Douglas Gregora16548e2009-08-11 05:31:07 +00001672
Douglas Gregorebe10102009-08-20 07:17:43 +00001673template<typename Derived>
1674Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1675 if (!S)
1676 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001677
Douglas Gregorebe10102009-08-20 07:17:43 +00001678 switch (S->getStmtClass()) {
1679 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001680
Douglas Gregorebe10102009-08-20 07:17:43 +00001681 // Transform individual statement nodes
1682#define STMT(Node, Parent) \
1683 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1684#define EXPR(Node, Parent)
1685#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001686
Douglas Gregorebe10102009-08-20 07:17:43 +00001687 // Transform expressions by calling TransformExpr.
1688#define STMT(Node, Parent)
1689#define EXPR(Node, Parent) case Stmt::Node##Class:
1690#include "clang/AST/StmtNodes.def"
1691 {
1692 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1693 if (E.isInvalid())
1694 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001695
Douglas Gregorebe10102009-08-20 07:17:43 +00001696 return getSema().Owned(E.takeAs<Stmt>());
1697 }
Mike Stump11289f42009-09-09 15:08:12 +00001698 }
1699
Douglas Gregorebe10102009-08-20 07:17:43 +00001700 return SemaRef.Owned(S->Retain());
1701}
Mike Stump11289f42009-09-09 15:08:12 +00001702
1703
Douglas Gregore922c772009-08-04 22:27:00 +00001704template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001705Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1706 bool isAddressOfOperand) {
1707 if (!E)
1708 return SemaRef.Owned(E);
1709
1710 switch (E->getStmtClass()) {
1711 case Stmt::NoStmtClass: break;
1712#define STMT(Node, Parent) case Stmt::Node##Class: break;
1713#define EXPR(Node, Parent) \
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00001714 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E), \
1715 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00001716#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001717 }
1718
Douglas Gregora16548e2009-08-11 05:31:07 +00001719 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001720}
1721
1722template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001723NestedNameSpecifier *
1724TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001725 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001726 QualType ObjectType,
1727 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001728 if (!NNS)
1729 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001730
Douglas Gregorebe10102009-08-20 07:17:43 +00001731 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001732 NestedNameSpecifier *Prefix = NNS->getPrefix();
1733 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001734 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001735 ObjectType,
1736 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001737 if (!Prefix)
1738 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001739
1740 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001741 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001742 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001743 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001744 }
Mike Stump11289f42009-09-09 15:08:12 +00001745
Douglas Gregor1135c352009-08-06 05:28:30 +00001746 switch (NNS->getKind()) {
1747 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001748 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001749 "Identifier nested-name-specifier with no prefix or object type");
1750 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1751 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001752 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001753
1754 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001755 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001756 ObjectType,
1757 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001758
Douglas Gregor1135c352009-08-06 05:28:30 +00001759 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001760 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001761 = cast_or_null<NamespaceDecl>(
1762 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001763 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001764 Prefix == NNS->getPrefix() &&
1765 NS == NNS->getAsNamespace())
1766 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001767
Douglas Gregor1135c352009-08-06 05:28:30 +00001768 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1769 }
Mike Stump11289f42009-09-09 15:08:12 +00001770
Douglas Gregor1135c352009-08-06 05:28:30 +00001771 case NestedNameSpecifier::Global:
1772 // There is no meaningful transformation that one could perform on the
1773 // global scope.
1774 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001775
Douglas Gregor1135c352009-08-06 05:28:30 +00001776 case NestedNameSpecifier::TypeSpecWithTemplate:
1777 case NestedNameSpecifier::TypeSpec: {
Douglas Gregor07cc4ac2009-10-29 22:21:39 +00001778 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregor1135c352009-08-06 05:28:30 +00001779 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001780 if (T.isNull())
1781 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001782
Douglas Gregor1135c352009-08-06 05:28:30 +00001783 if (!getDerived().AlwaysRebuild() &&
1784 Prefix == NNS->getPrefix() &&
1785 T == QualType(NNS->getAsType(), 0))
1786 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001787
1788 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1789 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001790 T);
1791 }
1792 }
Mike Stump11289f42009-09-09 15:08:12 +00001793
Douglas Gregor1135c352009-08-06 05:28:30 +00001794 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001795 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001796}
1797
1798template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001799DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001800TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001801 SourceLocation Loc,
1802 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001803 if (!Name)
1804 return Name;
1805
1806 switch (Name.getNameKind()) {
1807 case DeclarationName::Identifier:
1808 case DeclarationName::ObjCZeroArgSelector:
1809 case DeclarationName::ObjCOneArgSelector:
1810 case DeclarationName::ObjCMultiArgSelector:
1811 case DeclarationName::CXXOperatorName:
1812 case DeclarationName::CXXUsingDirective:
1813 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001814
Douglas Gregorf816bd72009-09-03 22:13:48 +00001815 case DeclarationName::CXXConstructorName:
1816 case DeclarationName::CXXDestructorName:
1817 case DeclarationName::CXXConversionFunctionName: {
1818 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001819 QualType T;
1820 if (!ObjectType.isNull() &&
1821 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1822 TemplateSpecializationType *SpecType
1823 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1824 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1825 } else
1826 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001827 if (T.isNull())
1828 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001829
Douglas Gregorf816bd72009-09-03 22:13:48 +00001830 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001831 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001832 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001833 }
Mike Stump11289f42009-09-09 15:08:12 +00001834 }
1835
Douglas Gregorf816bd72009-09-03 22:13:48 +00001836 return DeclarationName();
1837}
1838
1839template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001840TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001841TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1842 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001843 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001844 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001845 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1846 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1847 if (!NNS)
1848 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001849
Douglas Gregor71dc5092009-08-06 06:41:21 +00001850 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001851 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001852 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1853 if (!TransTemplate)
1854 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001855
Douglas Gregor71dc5092009-08-06 06:41:21 +00001856 if (!getDerived().AlwaysRebuild() &&
1857 NNS == QTN->getQualifier() &&
1858 TransTemplate == Template)
1859 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001860
Douglas Gregor71dc5092009-08-06 06:41:21 +00001861 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1862 TransTemplate);
1863 }
Mike Stump11289f42009-09-09 15:08:12 +00001864
Douglas Gregor71dc5092009-08-06 06:41:21 +00001865 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1866 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001867 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001868 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1869 if (!TransOvl)
1870 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001871
Douglas Gregor71dc5092009-08-06 06:41:21 +00001872 if (!getDerived().AlwaysRebuild() &&
1873 NNS == QTN->getQualifier() &&
1874 TransOvl == Ovl)
1875 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001876
Douglas Gregor71dc5092009-08-06 06:41:21 +00001877 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1878 TransOvl);
1879 }
Mike Stump11289f42009-09-09 15:08:12 +00001880
Douglas Gregor71dc5092009-08-06 06:41:21 +00001881 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001882 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001883 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1884 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001885 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001886 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001887
Douglas Gregor71dc5092009-08-06 06:41:21 +00001888 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001889 NNS == DTN->getQualifier() &&
1890 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001891 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001892
Douglas Gregor71395fa2009-11-04 00:56:37 +00001893 if (DTN->isIdentifier())
1894 return getDerived().RebuildTemplateName(NNS, *DTN->getIdentifier(),
1895 ObjectType);
1896
1897 return getDerived().RebuildTemplateName(NNS, DTN->getOperator(),
1898 ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001899 }
Mike Stump11289f42009-09-09 15:08:12 +00001900
Douglas Gregor71dc5092009-08-06 06:41:21 +00001901 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001902 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001903 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1904 if (!TransTemplate)
1905 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001906
Douglas Gregor71dc5092009-08-06 06:41:21 +00001907 if (!getDerived().AlwaysRebuild() &&
1908 TransTemplate == Template)
1909 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001910
Douglas Gregor71dc5092009-08-06 06:41:21 +00001911 return TemplateName(TransTemplate);
1912 }
Mike Stump11289f42009-09-09 15:08:12 +00001913
Douglas Gregor71dc5092009-08-06 06:41:21 +00001914 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1915 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001916 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001917 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1918 if (!TransOvl)
1919 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001920
Douglas Gregor71dc5092009-08-06 06:41:21 +00001921 if (!getDerived().AlwaysRebuild() &&
1922 TransOvl == Ovl)
1923 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001924
Douglas Gregor71dc5092009-08-06 06:41:21 +00001925 return TemplateName(TransOvl);
1926}
1927
1928template<typename Derived>
John McCall0ad16662009-10-29 08:12:44 +00001929void TreeTransform<Derived>::InventTemplateArgumentLoc(
1930 const TemplateArgument &Arg,
1931 TemplateArgumentLoc &Output) {
1932 SourceLocation Loc = getDerived().getBaseLocation();
1933 switch (Arg.getKind()) {
1934 case TemplateArgument::Null:
1935 llvm::llvm_unreachable("null template argument in TreeTransform");
1936 break;
1937
1938 case TemplateArgument::Type:
1939 Output = TemplateArgumentLoc(Arg,
1940 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1941
1942 break;
1943
1944 case TemplateArgument::Expression:
1945 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1946 break;
1947
1948 case TemplateArgument::Declaration:
1949 case TemplateArgument::Integral:
1950 case TemplateArgument::Pack:
John McCall0d07eb32009-10-29 18:45:58 +00001951 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00001952 break;
1953 }
1954}
1955
1956template<typename Derived>
1957bool TreeTransform<Derived>::TransformTemplateArgument(
1958 const TemplateArgumentLoc &Input,
1959 TemplateArgumentLoc &Output) {
1960 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregore922c772009-08-04 22:27:00 +00001961 switch (Arg.getKind()) {
1962 case TemplateArgument::Null:
1963 case TemplateArgument::Integral:
John McCall0ad16662009-10-29 08:12:44 +00001964 Output = Input;
1965 return false;
Mike Stump11289f42009-09-09 15:08:12 +00001966
Douglas Gregore922c772009-08-04 22:27:00 +00001967 case TemplateArgument::Type: {
John McCall0ad16662009-10-29 08:12:44 +00001968 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1969 if (DI == NULL)
1970 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1971
1972 DI = getDerived().TransformType(DI);
1973 if (!DI) return true;
1974
1975 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1976 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001977 }
Mike Stump11289f42009-09-09 15:08:12 +00001978
Douglas Gregore922c772009-08-04 22:27:00 +00001979 case TemplateArgument::Declaration: {
John McCall0ad16662009-10-29 08:12:44 +00001980 // FIXME: we should never have to transform one of these.
Douglas Gregoref6ab412009-10-27 06:26:26 +00001981 DeclarationName Name;
1982 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1983 Name = ND->getDeclName();
John McCall0ad16662009-10-29 08:12:44 +00001984 TemporaryBase Rebase(*this, SourceLocation(), Name);
Douglas Gregore922c772009-08-04 22:27:00 +00001985 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall0ad16662009-10-29 08:12:44 +00001986 if (!D) return true;
1987
John McCall0d07eb32009-10-29 18:45:58 +00001988 Expr *SourceExpr = Input.getSourceDeclExpression();
1989 if (SourceExpr) {
1990 EnterExpressionEvaluationContext Unevaluated(getSema(),
1991 Action::Unevaluated);
1992 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
1993 if (E.isInvalid())
1994 SourceExpr = NULL;
1995 else {
1996 SourceExpr = E.takeAs<Expr>();
1997 SourceExpr->Retain();
1998 }
1999 }
2000
2001 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall0ad16662009-10-29 08:12:44 +00002002 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002003 }
Mike Stump11289f42009-09-09 15:08:12 +00002004
Douglas Gregore922c772009-08-04 22:27:00 +00002005 case TemplateArgument::Expression: {
2006 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00002007 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00002008 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002009
John McCall0ad16662009-10-29 08:12:44 +00002010 Expr *InputExpr = Input.getSourceExpression();
2011 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
2012
2013 Sema::OwningExprResult E
2014 = getDerived().TransformExpr(InputExpr);
2015 if (E.isInvalid()) return true;
2016
2017 Expr *ETaken = E.takeAs<Expr>();
John McCall0d07eb32009-10-29 18:45:58 +00002018 ETaken->Retain();
John McCall0ad16662009-10-29 08:12:44 +00002019 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
2020 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002021 }
Mike Stump11289f42009-09-09 15:08:12 +00002022
Douglas Gregore922c772009-08-04 22:27:00 +00002023 case TemplateArgument::Pack: {
2024 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
2025 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00002026 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00002027 AEnd = Arg.pack_end();
2028 A != AEnd; ++A) {
Mike Stump11289f42009-09-09 15:08:12 +00002029
John McCall0ad16662009-10-29 08:12:44 +00002030 // FIXME: preserve source information here when we start
2031 // caring about parameter packs.
2032
John McCall0d07eb32009-10-29 18:45:58 +00002033 TemplateArgumentLoc InputArg;
2034 TemplateArgumentLoc OutputArg;
2035 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2036 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall0ad16662009-10-29 08:12:44 +00002037 return true;
2038
John McCall0d07eb32009-10-29 18:45:58 +00002039 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregore922c772009-08-04 22:27:00 +00002040 }
2041 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00002042 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00002043 true);
John McCall0d07eb32009-10-29 18:45:58 +00002044 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00002045 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002046 }
2047 }
Mike Stump11289f42009-09-09 15:08:12 +00002048
Douglas Gregore922c772009-08-04 22:27:00 +00002049 // Work around bogus GCC warning
John McCall0ad16662009-10-29 08:12:44 +00002050 return true;
Douglas Gregore922c772009-08-04 22:27:00 +00002051}
2052
Douglas Gregord6ff3322009-08-04 16:50:30 +00002053//===----------------------------------------------------------------------===//
2054// Type transformation
2055//===----------------------------------------------------------------------===//
2056
2057template<typename Derived>
2058QualType TreeTransform<Derived>::TransformType(QualType T) {
2059 if (getDerived().AlreadyTransformed(T))
2060 return T;
Mike Stump11289f42009-09-09 15:08:12 +00002061
John McCall550e0c22009-10-21 00:40:46 +00002062 // Temporary workaround. All of these transformations should
2063 // eventually turn into transformations on TypeLocs.
2064 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00002065 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00002066
2067 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00002068
John McCall550e0c22009-10-21 00:40:46 +00002069 if (!NewDI)
2070 return QualType();
2071
2072 return NewDI->getType();
2073}
2074
2075template<typename Derived>
2076DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2077 if (getDerived().AlreadyTransformed(DI->getType()))
2078 return DI;
2079
2080 TypeLocBuilder TLB;
2081
2082 TypeLoc TL = DI->getTypeLoc();
2083 TLB.reserve(TL.getFullDataSize());
2084
2085 QualType Result = getDerived().TransformType(TLB, TL);
2086 if (Result.isNull())
2087 return 0;
2088
2089 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2090}
2091
2092template<typename Derived>
2093QualType
2094TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2095 switch (T.getTypeLocClass()) {
2096#define ABSTRACT_TYPELOC(CLASS, PARENT)
2097#define TYPELOC(CLASS, PARENT) \
2098 case TypeLoc::CLASS: \
2099 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2100#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00002101 }
Mike Stump11289f42009-09-09 15:08:12 +00002102
John McCall550e0c22009-10-21 00:40:46 +00002103 llvm::llvm_unreachable("unhandled type loc!");
2104 return QualType();
2105}
2106
2107/// FIXME: By default, this routine adds type qualifiers only to types
2108/// that can have qualifiers, and silently suppresses those qualifiers
2109/// that are not permitted (e.g., qualifiers on reference or function
2110/// types). This is the right thing for template instantiation, but
2111/// probably not for other clients.
2112template<typename Derived>
2113QualType
2114TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2115 QualifiedTypeLoc T) {
2116 Qualifiers Quals = T.getType().getQualifiers();
2117
2118 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2119 if (Result.isNull())
2120 return QualType();
2121
2122 // Silently suppress qualifiers if the result type can't be qualified.
2123 // FIXME: this is the right thing for template instantiation, but
2124 // probably not for other clients.
2125 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002126 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002127
John McCall550e0c22009-10-21 00:40:46 +00002128 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2129
2130 TLB.push<QualifiedTypeLoc>(Result);
2131
2132 // No location information to preserve.
2133
2134 return Result;
2135}
2136
2137template <class TyLoc> static inline
2138QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2139 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2140 NewT.setNameLoc(T.getNameLoc());
2141 return T.getType();
2142}
2143
2144// Ugly metaprogramming macros because I couldn't be bothered to make
2145// the equivalent template version work.
2146#define TransformPointerLikeType(TypeClass) do { \
2147 QualType PointeeType \
2148 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2149 if (PointeeType.isNull()) \
2150 return QualType(); \
2151 \
2152 QualType Result = TL.getType(); \
2153 if (getDerived().AlwaysRebuild() || \
2154 PointeeType != TL.getPointeeLoc().getType()) { \
John McCall70dd5f62009-10-30 00:06:24 +00002155 Result = getDerived().Rebuild##TypeClass(PointeeType, \
2156 TL.getSigilLoc()); \
John McCall550e0c22009-10-21 00:40:46 +00002157 if (Result.isNull()) \
2158 return QualType(); \
2159 } \
2160 \
2161 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2162 NewT.setSigilLoc(TL.getSigilLoc()); \
2163 \
2164 return Result; \
2165} while(0)
2166
John McCall550e0c22009-10-21 00:40:46 +00002167template<typename Derived>
2168QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2169 BuiltinTypeLoc T) {
2170 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002171}
Mike Stump11289f42009-09-09 15:08:12 +00002172
Douglas Gregord6ff3322009-08-04 16:50:30 +00002173template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002174QualType
John McCall550e0c22009-10-21 00:40:46 +00002175TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2176 FixedWidthIntTypeLoc T) {
2177 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002178}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002179
Douglas Gregord6ff3322009-08-04 16:50:30 +00002180template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002181QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2182 ComplexTypeLoc T) {
2183 // FIXME: recurse?
2184 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002185}
Mike Stump11289f42009-09-09 15:08:12 +00002186
Douglas Gregord6ff3322009-08-04 16:50:30 +00002187template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002188QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2189 PointerTypeLoc TL) {
2190 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002191}
Mike Stump11289f42009-09-09 15:08:12 +00002192
2193template<typename Derived>
2194QualType
John McCall550e0c22009-10-21 00:40:46 +00002195TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2196 BlockPointerTypeLoc TL) {
2197 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002198}
2199
John McCall70dd5f62009-10-30 00:06:24 +00002200/// Transforms a reference type. Note that somewhat paradoxically we
2201/// don't care whether the type itself is an l-value type or an r-value
2202/// type; we only care if the type was *written* as an l-value type
2203/// or an r-value type.
2204template<typename Derived>
2205QualType
2206TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
2207 ReferenceTypeLoc TL) {
2208 const ReferenceType *T = TL.getTypePtr();
2209
2210 // Note that this works with the pointee-as-written.
2211 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
2212 if (PointeeType.isNull())
2213 return QualType();
2214
2215 QualType Result = TL.getType();
2216 if (getDerived().AlwaysRebuild() ||
2217 PointeeType != T->getPointeeTypeAsWritten()) {
2218 Result = getDerived().RebuildReferenceType(PointeeType,
2219 T->isSpelledAsLValue(),
2220 TL.getSigilLoc());
2221 if (Result.isNull())
2222 return QualType();
2223 }
2224
2225 // r-value references can be rebuilt as l-value references.
2226 ReferenceTypeLoc NewTL;
2227 if (isa<LValueReferenceType>(Result))
2228 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
2229 else
2230 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
2231 NewTL.setSigilLoc(TL.getSigilLoc());
2232
2233 return Result;
2234}
2235
Mike Stump11289f42009-09-09 15:08:12 +00002236template<typename Derived>
2237QualType
John McCall550e0c22009-10-21 00:40:46 +00002238TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2239 LValueReferenceTypeLoc TL) {
John McCall70dd5f62009-10-30 00:06:24 +00002240 return TransformReferenceType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002241}
2242
Mike Stump11289f42009-09-09 15:08:12 +00002243template<typename Derived>
2244QualType
John McCall550e0c22009-10-21 00:40:46 +00002245TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2246 RValueReferenceTypeLoc TL) {
John McCall70dd5f62009-10-30 00:06:24 +00002247 return TransformReferenceType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002248}
Mike Stump11289f42009-09-09 15:08:12 +00002249
Douglas Gregord6ff3322009-08-04 16:50:30 +00002250template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002251QualType
John McCall550e0c22009-10-21 00:40:46 +00002252TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2253 MemberPointerTypeLoc TL) {
2254 MemberPointerType *T = TL.getTypePtr();
2255
2256 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002257 if (PointeeType.isNull())
2258 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002259
John McCall550e0c22009-10-21 00:40:46 +00002260 // TODO: preserve source information for this.
2261 QualType ClassType
2262 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002263 if (ClassType.isNull())
2264 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002265
John McCall550e0c22009-10-21 00:40:46 +00002266 QualType Result = TL.getType();
2267 if (getDerived().AlwaysRebuild() ||
2268 PointeeType != T->getPointeeType() ||
2269 ClassType != QualType(T->getClass(), 0)) {
John McCall70dd5f62009-10-30 00:06:24 +00002270 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
2271 TL.getStarLoc());
John McCall550e0c22009-10-21 00:40:46 +00002272 if (Result.isNull())
2273 return QualType();
2274 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002275
John McCall550e0c22009-10-21 00:40:46 +00002276 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2277 NewTL.setSigilLoc(TL.getSigilLoc());
2278
2279 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002280}
2281
Mike Stump11289f42009-09-09 15:08:12 +00002282template<typename Derived>
2283QualType
John McCall550e0c22009-10-21 00:40:46 +00002284TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2285 ConstantArrayTypeLoc TL) {
2286 ConstantArrayType *T = TL.getTypePtr();
2287 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002288 if (ElementType.isNull())
2289 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002290
John McCall550e0c22009-10-21 00:40:46 +00002291 QualType Result = TL.getType();
2292 if (getDerived().AlwaysRebuild() ||
2293 ElementType != T->getElementType()) {
2294 Result = getDerived().RebuildConstantArrayType(ElementType,
2295 T->getSizeModifier(),
2296 T->getSize(),
John McCall70dd5f62009-10-30 00:06:24 +00002297 T->getIndexTypeCVRQualifiers(),
2298 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002299 if (Result.isNull())
2300 return QualType();
2301 }
2302
2303 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2304 NewTL.setLBracketLoc(TL.getLBracketLoc());
2305 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002306
John McCall550e0c22009-10-21 00:40:46 +00002307 Expr *Size = TL.getSizeExpr();
2308 if (Size) {
2309 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2310 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2311 }
2312 NewTL.setSizeExpr(Size);
2313
2314 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002315}
Mike Stump11289f42009-09-09 15:08:12 +00002316
Douglas Gregord6ff3322009-08-04 16:50:30 +00002317template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002318QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002319 TypeLocBuilder &TLB,
2320 IncompleteArrayTypeLoc TL) {
2321 IncompleteArrayType *T = TL.getTypePtr();
2322 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002323 if (ElementType.isNull())
2324 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002325
John McCall550e0c22009-10-21 00:40:46 +00002326 QualType Result = TL.getType();
2327 if (getDerived().AlwaysRebuild() ||
2328 ElementType != T->getElementType()) {
2329 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002330 T->getSizeModifier(),
John McCall70dd5f62009-10-30 00:06:24 +00002331 T->getIndexTypeCVRQualifiers(),
2332 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002333 if (Result.isNull())
2334 return QualType();
2335 }
2336
2337 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2338 NewTL.setLBracketLoc(TL.getLBracketLoc());
2339 NewTL.setRBracketLoc(TL.getRBracketLoc());
2340 NewTL.setSizeExpr(0);
2341
2342 return Result;
2343}
2344
2345template<typename Derived>
2346QualType
2347TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2348 VariableArrayTypeLoc TL) {
2349 VariableArrayType *T = TL.getTypePtr();
2350 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2351 if (ElementType.isNull())
2352 return QualType();
2353
2354 // Array bounds are not potentially evaluated contexts
2355 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2356
2357 Sema::OwningExprResult SizeResult
2358 = getDerived().TransformExpr(T->getSizeExpr());
2359 if (SizeResult.isInvalid())
2360 return QualType();
2361
2362 Expr *Size = static_cast<Expr*>(SizeResult.get());
2363
2364 QualType Result = TL.getType();
2365 if (getDerived().AlwaysRebuild() ||
2366 ElementType != T->getElementType() ||
2367 Size != T->getSizeExpr()) {
2368 Result = getDerived().RebuildVariableArrayType(ElementType,
2369 T->getSizeModifier(),
2370 move(SizeResult),
2371 T->getIndexTypeCVRQualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00002372 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002373 if (Result.isNull())
2374 return QualType();
2375 }
2376 else SizeResult.take();
2377
2378 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2379 NewTL.setLBracketLoc(TL.getLBracketLoc());
2380 NewTL.setRBracketLoc(TL.getRBracketLoc());
2381 NewTL.setSizeExpr(Size);
2382
2383 return Result;
2384}
2385
2386template<typename Derived>
2387QualType
2388TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2389 DependentSizedArrayTypeLoc TL) {
2390 DependentSizedArrayType *T = TL.getTypePtr();
2391 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2392 if (ElementType.isNull())
2393 return QualType();
2394
2395 // Array bounds are not potentially evaluated contexts
2396 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2397
2398 Sema::OwningExprResult SizeResult
2399 = getDerived().TransformExpr(T->getSizeExpr());
2400 if (SizeResult.isInvalid())
2401 return QualType();
2402
2403 Expr *Size = static_cast<Expr*>(SizeResult.get());
2404
2405 QualType Result = TL.getType();
2406 if (getDerived().AlwaysRebuild() ||
2407 ElementType != T->getElementType() ||
2408 Size != T->getSizeExpr()) {
2409 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2410 T->getSizeModifier(),
2411 move(SizeResult),
2412 T->getIndexTypeCVRQualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00002413 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002414 if (Result.isNull())
2415 return QualType();
2416 }
2417 else SizeResult.take();
2418
2419 // We might have any sort of array type now, but fortunately they
2420 // all have the same location layout.
2421 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2422 NewTL.setLBracketLoc(TL.getLBracketLoc());
2423 NewTL.setRBracketLoc(TL.getRBracketLoc());
2424 NewTL.setSizeExpr(Size);
2425
2426 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002427}
Mike Stump11289f42009-09-09 15:08:12 +00002428
2429template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002430QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002431 TypeLocBuilder &TLB,
2432 DependentSizedExtVectorTypeLoc TL) {
2433 DependentSizedExtVectorType *T = TL.getTypePtr();
2434
2435 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002436 QualType ElementType = getDerived().TransformType(T->getElementType());
2437 if (ElementType.isNull())
2438 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002439
Douglas Gregore922c772009-08-04 22:27:00 +00002440 // Vector sizes are not potentially evaluated contexts
2441 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2442
Douglas Gregord6ff3322009-08-04 16:50:30 +00002443 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2444 if (Size.isInvalid())
2445 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002446
John McCall550e0c22009-10-21 00:40:46 +00002447 QualType Result = TL.getType();
2448 if (getDerived().AlwaysRebuild() ||
John McCall24e7cb62009-10-23 17:55:45 +00002449 ElementType != T->getElementType() ||
2450 Size.get() != T->getSizeExpr()) {
John McCall550e0c22009-10-21 00:40:46 +00002451 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002452 move(Size),
2453 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002454 if (Result.isNull())
2455 return QualType();
2456 }
2457 else Size.take();
2458
2459 // Result might be dependent or not.
2460 if (isa<DependentSizedExtVectorType>(Result)) {
2461 DependentSizedExtVectorTypeLoc NewTL
2462 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2463 NewTL.setNameLoc(TL.getNameLoc());
2464 } else {
2465 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2466 NewTL.setNameLoc(TL.getNameLoc());
2467 }
2468
2469 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002470}
Mike Stump11289f42009-09-09 15:08:12 +00002471
2472template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002473QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2474 VectorTypeLoc TL) {
2475 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002476 QualType ElementType = getDerived().TransformType(T->getElementType());
2477 if (ElementType.isNull())
2478 return QualType();
2479
John McCall550e0c22009-10-21 00:40:46 +00002480 QualType Result = TL.getType();
2481 if (getDerived().AlwaysRebuild() ||
2482 ElementType != T->getElementType()) {
2483 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2484 if (Result.isNull())
2485 return QualType();
2486 }
2487
2488 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2489 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002490
John McCall550e0c22009-10-21 00:40:46 +00002491 return Result;
2492}
2493
2494template<typename Derived>
2495QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2496 ExtVectorTypeLoc TL) {
2497 VectorType *T = TL.getTypePtr();
2498 QualType ElementType = getDerived().TransformType(T->getElementType());
2499 if (ElementType.isNull())
2500 return QualType();
2501
2502 QualType Result = TL.getType();
2503 if (getDerived().AlwaysRebuild() ||
2504 ElementType != T->getElementType()) {
2505 Result = getDerived().RebuildExtVectorType(ElementType,
2506 T->getNumElements(),
2507 /*FIXME*/ SourceLocation());
2508 if (Result.isNull())
2509 return QualType();
2510 }
2511
2512 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2513 NewTL.setNameLoc(TL.getNameLoc());
2514
2515 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002516}
Mike Stump11289f42009-09-09 15:08:12 +00002517
2518template<typename Derived>
2519QualType
John McCall550e0c22009-10-21 00:40:46 +00002520TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2521 FunctionProtoTypeLoc TL) {
2522 FunctionProtoType *T = TL.getTypePtr();
2523 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002524 if (ResultType.isNull())
2525 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002526
John McCall550e0c22009-10-21 00:40:46 +00002527 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002528 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002529 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2530 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2531 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002532
John McCall550e0c22009-10-21 00:40:46 +00002533 QualType NewType;
2534 ParmVarDecl *NewParm;
2535
2536 if (OldParm) {
2537 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2538 assert(OldDI->getType() == T->getArgType(i));
2539
2540 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2541 if (!NewDI)
2542 return QualType();
2543
2544 if (NewDI == OldDI)
2545 NewParm = OldParm;
2546 else
2547 NewParm = ParmVarDecl::Create(SemaRef.Context,
2548 OldParm->getDeclContext(),
2549 OldParm->getLocation(),
2550 OldParm->getIdentifier(),
2551 NewDI->getType(),
2552 NewDI,
2553 OldParm->getStorageClass(),
2554 /* DefArg */ NULL);
2555 NewType = NewParm->getType();
2556
2557 // Deal with the possibility that we don't have a parameter
2558 // declaration for this parameter.
2559 } else {
2560 NewParm = 0;
2561
2562 QualType OldType = T->getArgType(i);
2563 NewType = getDerived().TransformType(OldType);
2564 if (NewType.isNull())
2565 return QualType();
2566 }
2567
2568 ParamTypes.push_back(NewType);
2569 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002570 }
Mike Stump11289f42009-09-09 15:08:12 +00002571
John McCall550e0c22009-10-21 00:40:46 +00002572 QualType Result = TL.getType();
2573 if (getDerived().AlwaysRebuild() ||
2574 ResultType != T->getResultType() ||
2575 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2576 Result = getDerived().RebuildFunctionProtoType(ResultType,
2577 ParamTypes.data(),
2578 ParamTypes.size(),
2579 T->isVariadic(),
2580 T->getTypeQuals());
2581 if (Result.isNull())
2582 return QualType();
2583 }
Mike Stump11289f42009-09-09 15:08:12 +00002584
John McCall550e0c22009-10-21 00:40:46 +00002585 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2586 NewTL.setLParenLoc(TL.getLParenLoc());
2587 NewTL.setRParenLoc(TL.getRParenLoc());
2588 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2589 NewTL.setArg(i, ParamDecls[i]);
2590
2591 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002592}
Mike Stump11289f42009-09-09 15:08:12 +00002593
Douglas Gregord6ff3322009-08-04 16:50:30 +00002594template<typename Derived>
2595QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002596 TypeLocBuilder &TLB,
2597 FunctionNoProtoTypeLoc TL) {
2598 FunctionNoProtoType *T = TL.getTypePtr();
2599 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2600 if (ResultType.isNull())
2601 return QualType();
2602
2603 QualType Result = TL.getType();
2604 if (getDerived().AlwaysRebuild() ||
2605 ResultType != T->getResultType())
2606 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2607
2608 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2609 NewTL.setLParenLoc(TL.getLParenLoc());
2610 NewTL.setRParenLoc(TL.getRParenLoc());
2611
2612 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002613}
Mike Stump11289f42009-09-09 15:08:12 +00002614
Douglas Gregord6ff3322009-08-04 16:50:30 +00002615template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002616QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2617 TypedefTypeLoc TL) {
2618 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002619 TypedefDecl *Typedef
2620 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2621 if (!Typedef)
2622 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002623
John McCall550e0c22009-10-21 00:40:46 +00002624 QualType Result = TL.getType();
2625 if (getDerived().AlwaysRebuild() ||
2626 Typedef != T->getDecl()) {
2627 Result = getDerived().RebuildTypedefType(Typedef);
2628 if (Result.isNull())
2629 return QualType();
2630 }
Mike Stump11289f42009-09-09 15:08:12 +00002631
John McCall550e0c22009-10-21 00:40:46 +00002632 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2633 NewTL.setNameLoc(TL.getNameLoc());
2634
2635 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002636}
Mike Stump11289f42009-09-09 15:08:12 +00002637
Douglas Gregord6ff3322009-08-04 16:50:30 +00002638template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002639QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2640 TypeOfExprTypeLoc TL) {
2641 TypeOfExprType *T = TL.getTypePtr();
2642
Douglas Gregore922c772009-08-04 22:27:00 +00002643 // typeof expressions are not potentially evaluated contexts
2644 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002645
Douglas Gregord6ff3322009-08-04 16:50:30 +00002646 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2647 if (E.isInvalid())
2648 return QualType();
2649
John McCall550e0c22009-10-21 00:40:46 +00002650 QualType Result = TL.getType();
2651 if (getDerived().AlwaysRebuild() ||
2652 E.get() != T->getUnderlyingExpr()) {
2653 Result = getDerived().RebuildTypeOfExprType(move(E));
2654 if (Result.isNull())
2655 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002656 }
John McCall550e0c22009-10-21 00:40:46 +00002657 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002658
John McCall550e0c22009-10-21 00:40:46 +00002659 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2660 NewTL.setNameLoc(TL.getNameLoc());
2661
2662 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002663}
Mike Stump11289f42009-09-09 15:08:12 +00002664
2665template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002666QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2667 TypeOfTypeLoc TL) {
2668 TypeOfType *T = TL.getTypePtr();
2669
2670 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002671 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2672 if (Underlying.isNull())
2673 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002674
John McCall550e0c22009-10-21 00:40:46 +00002675 QualType Result = TL.getType();
2676 if (getDerived().AlwaysRebuild() ||
2677 Underlying != T->getUnderlyingType()) {
2678 Result = getDerived().RebuildTypeOfType(Underlying);
2679 if (Result.isNull())
2680 return QualType();
2681 }
Mike Stump11289f42009-09-09 15:08:12 +00002682
John McCall550e0c22009-10-21 00:40:46 +00002683 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2684 NewTL.setNameLoc(TL.getNameLoc());
2685
2686 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002687}
Mike Stump11289f42009-09-09 15:08:12 +00002688
2689template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002690QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2691 DecltypeTypeLoc TL) {
2692 DecltypeType *T = TL.getTypePtr();
2693
Douglas Gregore922c772009-08-04 22:27:00 +00002694 // decltype expressions are not potentially evaluated contexts
2695 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002696
Douglas Gregord6ff3322009-08-04 16:50:30 +00002697 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2698 if (E.isInvalid())
2699 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002700
John McCall550e0c22009-10-21 00:40:46 +00002701 QualType Result = TL.getType();
2702 if (getDerived().AlwaysRebuild() ||
2703 E.get() != T->getUnderlyingExpr()) {
2704 Result = getDerived().RebuildDecltypeType(move(E));
2705 if (Result.isNull())
2706 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002707 }
John McCall550e0c22009-10-21 00:40:46 +00002708 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002709
John McCall550e0c22009-10-21 00:40:46 +00002710 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2711 NewTL.setNameLoc(TL.getNameLoc());
2712
2713 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002714}
2715
2716template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002717QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2718 RecordTypeLoc TL) {
2719 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002720 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002721 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002722 if (!Record)
2723 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002724
John McCall550e0c22009-10-21 00:40:46 +00002725 QualType Result = TL.getType();
2726 if (getDerived().AlwaysRebuild() ||
2727 Record != T->getDecl()) {
2728 Result = getDerived().RebuildRecordType(Record);
2729 if (Result.isNull())
2730 return QualType();
2731 }
Mike Stump11289f42009-09-09 15:08:12 +00002732
John McCall550e0c22009-10-21 00:40:46 +00002733 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2734 NewTL.setNameLoc(TL.getNameLoc());
2735
2736 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002737}
Mike Stump11289f42009-09-09 15:08:12 +00002738
2739template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002740QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2741 EnumTypeLoc TL) {
2742 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002743 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002744 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002745 if (!Enum)
2746 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002747
John McCall550e0c22009-10-21 00:40:46 +00002748 QualType Result = TL.getType();
2749 if (getDerived().AlwaysRebuild() ||
2750 Enum != T->getDecl()) {
2751 Result = getDerived().RebuildEnumType(Enum);
2752 if (Result.isNull())
2753 return QualType();
2754 }
Mike Stump11289f42009-09-09 15:08:12 +00002755
John McCall550e0c22009-10-21 00:40:46 +00002756 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2757 NewTL.setNameLoc(TL.getNameLoc());
2758
2759 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002760}
John McCallfcc33b02009-09-05 00:15:47 +00002761
2762template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002763QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2764 ElaboratedTypeLoc TL) {
2765 ElaboratedType *T = TL.getTypePtr();
2766
2767 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002768 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2769 if (Underlying.isNull())
2770 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002771
John McCall550e0c22009-10-21 00:40:46 +00002772 QualType Result = TL.getType();
2773 if (getDerived().AlwaysRebuild() ||
2774 Underlying != T->getUnderlyingType()) {
2775 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2776 if (Result.isNull())
2777 return QualType();
2778 }
Mike Stump11289f42009-09-09 15:08:12 +00002779
John McCall550e0c22009-10-21 00:40:46 +00002780 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2781 NewTL.setNameLoc(TL.getNameLoc());
2782
2783 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002784}
Mike Stump11289f42009-09-09 15:08:12 +00002785
2786
Douglas Gregord6ff3322009-08-04 16:50:30 +00002787template<typename Derived>
2788QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002789 TypeLocBuilder &TLB,
2790 TemplateTypeParmTypeLoc TL) {
2791 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002792}
2793
Mike Stump11289f42009-09-09 15:08:12 +00002794template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002795QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002796 TypeLocBuilder &TLB,
2797 SubstTemplateTypeParmTypeLoc TL) {
2798 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002799}
2800
2801template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002802inline QualType
2803TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002804 TypeLocBuilder &TLB,
2805 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002806 return TransformTemplateSpecializationType(TLB, TL, QualType());
2807}
John McCall550e0c22009-10-21 00:40:46 +00002808
John McCall0ad16662009-10-29 08:12:44 +00002809template<typename Derived>
2810QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2811 const TemplateSpecializationType *TST,
2812 QualType ObjectType) {
2813 // FIXME: this entire method is a temporary workaround; callers
2814 // should be rewritten to provide real type locs.
John McCall550e0c22009-10-21 00:40:46 +00002815
John McCall0ad16662009-10-29 08:12:44 +00002816 // Fake up a TemplateSpecializationTypeLoc.
2817 TypeLocBuilder TLB;
2818 TemplateSpecializationTypeLoc TL
2819 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2820
John McCall0d07eb32009-10-29 18:45:58 +00002821 SourceLocation BaseLoc = getDerived().getBaseLocation();
2822
2823 TL.setTemplateNameLoc(BaseLoc);
2824 TL.setLAngleLoc(BaseLoc);
2825 TL.setRAngleLoc(BaseLoc);
John McCall0ad16662009-10-29 08:12:44 +00002826 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2827 const TemplateArgument &TA = TST->getArg(i);
2828 TemplateArgumentLoc TAL;
2829 getDerived().InventTemplateArgumentLoc(TA, TAL);
2830 TL.setArgLocInfo(i, TAL.getLocInfo());
2831 }
2832
2833 TypeLocBuilder IgnoredTLB;
2834 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +00002835}
2836
2837template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002838QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00002839 TypeLocBuilder &TLB,
2840 TemplateSpecializationTypeLoc TL,
2841 QualType ObjectType) {
2842 const TemplateSpecializationType *T = TL.getTypePtr();
2843
Mike Stump11289f42009-09-09 15:08:12 +00002844 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002845 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002846 if (Template.isNull())
2847 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002848
John McCall0ad16662009-10-29 08:12:44 +00002849 llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
2850 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
2851 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
2852 NewTemplateArgs[i]))
Douglas Gregord6ff3322009-08-04 16:50:30 +00002853 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002854
John McCall0ad16662009-10-29 08:12:44 +00002855 // FIXME: maybe don't rebuild if all the template arguments are the same.
2856
2857 QualType Result =
2858 getDerived().RebuildTemplateSpecializationType(Template,
2859 TL.getTemplateNameLoc(),
2860 TL.getLAngleLoc(),
2861 NewTemplateArgs.data(),
2862 NewTemplateArgs.size(),
2863 TL.getRAngleLoc());
2864
2865 if (!Result.isNull()) {
2866 TemplateSpecializationTypeLoc NewTL
2867 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2868 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2869 NewTL.setLAngleLoc(TL.getLAngleLoc());
2870 NewTL.setRAngleLoc(TL.getRAngleLoc());
2871 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2872 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002873 }
Mike Stump11289f42009-09-09 15:08:12 +00002874
John McCall0ad16662009-10-29 08:12:44 +00002875 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002876}
Mike Stump11289f42009-09-09 15:08:12 +00002877
2878template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002879QualType
2880TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2881 QualifiedNameTypeLoc TL) {
2882 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002883 NestedNameSpecifier *NNS
2884 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2885 SourceRange());
2886 if (!NNS)
2887 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002888
Douglas Gregord6ff3322009-08-04 16:50:30 +00002889 QualType Named = getDerived().TransformType(T->getNamedType());
2890 if (Named.isNull())
2891 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002892
John McCall550e0c22009-10-21 00:40:46 +00002893 QualType Result = TL.getType();
2894 if (getDerived().AlwaysRebuild() ||
2895 NNS != T->getQualifier() ||
2896 Named != T->getNamedType()) {
2897 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2898 if (Result.isNull())
2899 return QualType();
2900 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002901
John McCall550e0c22009-10-21 00:40:46 +00002902 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2903 NewTL.setNameLoc(TL.getNameLoc());
2904
2905 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002906}
Mike Stump11289f42009-09-09 15:08:12 +00002907
2908template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002909QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2910 TypenameTypeLoc TL) {
2911 TypenameType *T = TL.getTypePtr();
John McCall0ad16662009-10-29 08:12:44 +00002912
2913 /* FIXME: preserve source information better than this */
2914 SourceRange SR(TL.getNameLoc());
2915
Douglas Gregord6ff3322009-08-04 16:50:30 +00002916 NestedNameSpecifier *NNS
John McCall0ad16662009-10-29 08:12:44 +00002917 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002918 if (!NNS)
2919 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002920
John McCall550e0c22009-10-21 00:40:46 +00002921 QualType Result;
2922
Douglas Gregord6ff3322009-08-04 16:50:30 +00002923 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002924 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002925 = getDerived().TransformType(QualType(TemplateId, 0));
2926 if (NewTemplateId.isNull())
2927 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002928
Douglas Gregord6ff3322009-08-04 16:50:30 +00002929 if (!getDerived().AlwaysRebuild() &&
2930 NNS == T->getQualifier() &&
2931 NewTemplateId == QualType(TemplateId, 0))
2932 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002933
John McCall550e0c22009-10-21 00:40:46 +00002934 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2935 } else {
John McCall0ad16662009-10-29 08:12:44 +00002936 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002937 }
John McCall550e0c22009-10-21 00:40:46 +00002938 if (Result.isNull())
2939 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002940
John McCall550e0c22009-10-21 00:40:46 +00002941 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2942 NewTL.setNameLoc(TL.getNameLoc());
2943
2944 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002945}
Mike Stump11289f42009-09-09 15:08:12 +00002946
Douglas Gregord6ff3322009-08-04 16:50:30 +00002947template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002948QualType
2949TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2950 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002951 assert(false && "TransformObjCInterfaceType unimplemented");
2952 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002953}
Mike Stump11289f42009-09-09 15:08:12 +00002954
2955template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002956QualType
2957TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2958 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002959 assert(false && "TransformObjCObjectPointerType unimplemented");
2960 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002961}
2962
Douglas Gregord6ff3322009-08-04 16:50:30 +00002963//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002964// Statement transformation
2965//===----------------------------------------------------------------------===//
2966template<typename Derived>
2967Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002968TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2969 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002970}
2971
2972template<typename Derived>
2973Sema::OwningStmtResult
2974TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2975 return getDerived().TransformCompoundStmt(S, false);
2976}
2977
2978template<typename Derived>
2979Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002980TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002981 bool IsStmtExpr) {
2982 bool SubStmtChanged = false;
2983 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2984 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2985 B != BEnd; ++B) {
2986 OwningStmtResult Result = getDerived().TransformStmt(*B);
2987 if (Result.isInvalid())
2988 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002989
Douglas Gregorebe10102009-08-20 07:17:43 +00002990 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2991 Statements.push_back(Result.takeAs<Stmt>());
2992 }
Mike Stump11289f42009-09-09 15:08:12 +00002993
Douglas Gregorebe10102009-08-20 07:17:43 +00002994 if (!getDerived().AlwaysRebuild() &&
2995 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00002996 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002997
2998 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2999 move_arg(Statements),
3000 S->getRBracLoc(),
3001 IsStmtExpr);
3002}
Mike Stump11289f42009-09-09 15:08:12 +00003003
Douglas Gregorebe10102009-08-20 07:17:43 +00003004template<typename Derived>
3005Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003006TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003007 // The case value expressions are not potentially evaluated.
3008 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003009
Douglas Gregorebe10102009-08-20 07:17:43 +00003010 // Transform the left-hand case value.
3011 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
3012 if (LHS.isInvalid())
3013 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003014
Douglas Gregorebe10102009-08-20 07:17:43 +00003015 // Transform the right-hand case value (for the GNU case-range extension).
3016 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
3017 if (RHS.isInvalid())
3018 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003019
Douglas Gregorebe10102009-08-20 07:17:43 +00003020 // Build the case statement.
3021 // Case statements are always rebuilt so that they will attached to their
3022 // transformed switch statement.
3023 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
3024 move(LHS),
3025 S->getEllipsisLoc(),
3026 move(RHS),
3027 S->getColonLoc());
3028 if (Case.isInvalid())
3029 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003030
Douglas Gregorebe10102009-08-20 07:17:43 +00003031 // Transform the statement following the case
3032 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3033 if (SubStmt.isInvalid())
3034 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003035
Douglas Gregorebe10102009-08-20 07:17:43 +00003036 // Attach the body to the case statement
3037 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
3038}
3039
3040template<typename Derived>
3041Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003042TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003043 // Transform the statement following the default case
3044 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3045 if (SubStmt.isInvalid())
3046 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003047
Douglas Gregorebe10102009-08-20 07:17:43 +00003048 // Default statements are always rebuilt
3049 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3050 move(SubStmt));
3051}
Mike Stump11289f42009-09-09 15:08:12 +00003052
Douglas Gregorebe10102009-08-20 07:17:43 +00003053template<typename Derived>
3054Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003055TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003056 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3057 if (SubStmt.isInvalid())
3058 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003059
Douglas Gregorebe10102009-08-20 07:17:43 +00003060 // FIXME: Pass the real colon location in.
3061 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3062 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3063 move(SubStmt));
3064}
Mike Stump11289f42009-09-09 15:08:12 +00003065
Douglas Gregorebe10102009-08-20 07:17:43 +00003066template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003067Sema::OwningStmtResult
3068TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003069 // Transform the condition
3070 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3071 if (Cond.isInvalid())
3072 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003073
Douglas Gregorebe10102009-08-20 07:17:43 +00003074 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003075
Douglas Gregorebe10102009-08-20 07:17:43 +00003076 // Transform the "then" branch.
3077 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3078 if (Then.isInvalid())
3079 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003080
Douglas Gregorebe10102009-08-20 07:17:43 +00003081 // Transform the "else" branch.
3082 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3083 if (Else.isInvalid())
3084 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003085
Douglas Gregorebe10102009-08-20 07:17:43 +00003086 if (!getDerived().AlwaysRebuild() &&
3087 FullCond->get() == S->getCond() &&
3088 Then.get() == S->getThen() &&
3089 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00003090 return SemaRef.Owned(S->Retain());
3091
Douglas Gregorebe10102009-08-20 07:17:43 +00003092 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00003093 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00003094}
3095
3096template<typename Derived>
3097Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003098TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003099 // Transform the condition.
3100 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3101 if (Cond.isInvalid())
3102 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003103
Douglas Gregorebe10102009-08-20 07:17:43 +00003104 // Rebuild the switch statement.
3105 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3106 if (Switch.isInvalid())
3107 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003108
Douglas Gregorebe10102009-08-20 07:17:43 +00003109 // Transform the body of the switch statement.
3110 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3111 if (Body.isInvalid())
3112 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003113
Douglas Gregorebe10102009-08-20 07:17:43 +00003114 // Complete the switch statement.
3115 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3116 move(Body));
3117}
Mike Stump11289f42009-09-09 15:08:12 +00003118
Douglas Gregorebe10102009-08-20 07:17:43 +00003119template<typename Derived>
3120Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003121TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003122 // Transform the condition
3123 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3124 if (Cond.isInvalid())
3125 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003126
Douglas Gregorebe10102009-08-20 07:17:43 +00003127 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003128
Douglas Gregorebe10102009-08-20 07:17:43 +00003129 // Transform the body
3130 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3131 if (Body.isInvalid())
3132 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003133
Douglas Gregorebe10102009-08-20 07:17:43 +00003134 if (!getDerived().AlwaysRebuild() &&
3135 FullCond->get() == S->getCond() &&
3136 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003137 return SemaRef.Owned(S->Retain());
3138
Douglas Gregorebe10102009-08-20 07:17:43 +00003139 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3140}
Mike Stump11289f42009-09-09 15:08:12 +00003141
Douglas Gregorebe10102009-08-20 07:17:43 +00003142template<typename Derived>
3143Sema::OwningStmtResult
3144TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3145 // Transform the condition
3146 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3147 if (Cond.isInvalid())
3148 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003149
Douglas Gregorebe10102009-08-20 07:17:43 +00003150 // Transform the body
3151 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3152 if (Body.isInvalid())
3153 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003154
Douglas Gregorebe10102009-08-20 07:17:43 +00003155 if (!getDerived().AlwaysRebuild() &&
3156 Cond.get() == S->getCond() &&
3157 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003158 return SemaRef.Owned(S->Retain());
3159
Douglas Gregorebe10102009-08-20 07:17:43 +00003160 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3161 /*FIXME:*/S->getWhileLoc(), move(Cond),
3162 S->getRParenLoc());
3163}
Mike Stump11289f42009-09-09 15:08:12 +00003164
Douglas Gregorebe10102009-08-20 07:17:43 +00003165template<typename Derived>
3166Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003167TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003168 // Transform the initialization statement
3169 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3170 if (Init.isInvalid())
3171 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003172
Douglas Gregorebe10102009-08-20 07:17:43 +00003173 // Transform the condition
3174 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3175 if (Cond.isInvalid())
3176 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003177
Douglas Gregorebe10102009-08-20 07:17:43 +00003178 // Transform the increment
3179 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3180 if (Inc.isInvalid())
3181 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003182
Douglas Gregorebe10102009-08-20 07:17:43 +00003183 // Transform the body
3184 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3185 if (Body.isInvalid())
3186 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003187
Douglas Gregorebe10102009-08-20 07:17:43 +00003188 if (!getDerived().AlwaysRebuild() &&
3189 Init.get() == S->getInit() &&
3190 Cond.get() == S->getCond() &&
3191 Inc.get() == S->getInc() &&
3192 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003193 return SemaRef.Owned(S->Retain());
3194
Douglas Gregorebe10102009-08-20 07:17:43 +00003195 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3196 move(Init), move(Cond), move(Inc),
3197 S->getRParenLoc(), move(Body));
3198}
3199
3200template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003201Sema::OwningStmtResult
3202TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003203 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003204 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003205 S->getLabel());
3206}
3207
3208template<typename Derived>
3209Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003210TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003211 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3212 if (Target.isInvalid())
3213 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003214
Douglas Gregorebe10102009-08-20 07:17:43 +00003215 if (!getDerived().AlwaysRebuild() &&
3216 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003217 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003218
3219 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3220 move(Target));
3221}
3222
3223template<typename Derived>
3224Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003225TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3226 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003227}
Mike Stump11289f42009-09-09 15:08:12 +00003228
Douglas Gregorebe10102009-08-20 07:17:43 +00003229template<typename Derived>
3230Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003231TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3232 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003233}
Mike Stump11289f42009-09-09 15:08:12 +00003234
Douglas Gregorebe10102009-08-20 07:17:43 +00003235template<typename Derived>
3236Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003237TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003238 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3239 if (Result.isInvalid())
3240 return SemaRef.StmtError();
3241
Mike Stump11289f42009-09-09 15:08:12 +00003242 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003243 // to tell whether the return type of the function has changed.
3244 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3245}
Mike Stump11289f42009-09-09 15:08:12 +00003246
Douglas Gregorebe10102009-08-20 07:17:43 +00003247template<typename Derived>
3248Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003249TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003250 bool DeclChanged = false;
3251 llvm::SmallVector<Decl *, 4> Decls;
3252 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3253 D != DEnd; ++D) {
3254 Decl *Transformed = getDerived().TransformDefinition(*D);
3255 if (!Transformed)
3256 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003257
Douglas Gregorebe10102009-08-20 07:17:43 +00003258 if (Transformed != *D)
3259 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003260
Douglas Gregorebe10102009-08-20 07:17:43 +00003261 Decls.push_back(Transformed);
3262 }
Mike Stump11289f42009-09-09 15:08:12 +00003263
Douglas Gregorebe10102009-08-20 07:17:43 +00003264 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003265 return SemaRef.Owned(S->Retain());
3266
3267 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003268 S->getStartLoc(), S->getEndLoc());
3269}
Mike Stump11289f42009-09-09 15:08:12 +00003270
Douglas Gregorebe10102009-08-20 07:17:43 +00003271template<typename Derived>
3272Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003273TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003274 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003275 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003276}
3277
3278template<typename Derived>
3279Sema::OwningStmtResult
3280TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3281 // FIXME: Implement!
3282 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003283 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003284}
3285
3286
3287template<typename Derived>
3288Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003289TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003290 // FIXME: Implement this
3291 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003292 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003293}
Mike Stump11289f42009-09-09 15:08:12 +00003294
Douglas Gregorebe10102009-08-20 07:17:43 +00003295template<typename Derived>
3296Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003297TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003298 // FIXME: Implement this
3299 assert(false && "Cannot transform an Objective-C @catch statement");
3300 return SemaRef.Owned(S->Retain());
3301}
Mike Stump11289f42009-09-09 15:08:12 +00003302
Douglas Gregorebe10102009-08-20 07:17:43 +00003303template<typename Derived>
3304Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003305TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003306 // FIXME: Implement this
3307 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003308 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003309}
Mike Stump11289f42009-09-09 15:08:12 +00003310
Douglas Gregorebe10102009-08-20 07:17:43 +00003311template<typename Derived>
3312Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003313TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003314 // FIXME: Implement this
3315 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003316 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003317}
Mike Stump11289f42009-09-09 15:08:12 +00003318
Douglas Gregorebe10102009-08-20 07:17:43 +00003319template<typename Derived>
3320Sema::OwningStmtResult
3321TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003322 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003323 // FIXME: Implement this
3324 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003325 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003326}
3327
3328template<typename Derived>
3329Sema::OwningStmtResult
3330TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003331 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003332 // FIXME: Implement this
3333 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003334 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003335}
3336
3337
3338template<typename Derived>
3339Sema::OwningStmtResult
3340TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3341 // Transform the exception declaration, if any.
3342 VarDecl *Var = 0;
3343 if (S->getExceptionDecl()) {
3344 VarDecl *ExceptionDecl = S->getExceptionDecl();
3345 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3346 ExceptionDecl->getDeclName());
3347
3348 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3349 if (T.isNull())
3350 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003351
Douglas Gregorebe10102009-08-20 07:17:43 +00003352 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3353 T,
3354 ExceptionDecl->getDeclaratorInfo(),
3355 ExceptionDecl->getIdentifier(),
3356 ExceptionDecl->getLocation(),
3357 /*FIXME: Inaccurate*/
3358 SourceRange(ExceptionDecl->getLocation()));
3359 if (!Var || Var->isInvalidDecl()) {
3360 if (Var)
3361 Var->Destroy(SemaRef.Context);
3362 return SemaRef.StmtError();
3363 }
3364 }
Mike Stump11289f42009-09-09 15:08:12 +00003365
Douglas Gregorebe10102009-08-20 07:17:43 +00003366 // Transform the actual exception handler.
3367 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3368 if (Handler.isInvalid()) {
3369 if (Var)
3370 Var->Destroy(SemaRef.Context);
3371 return SemaRef.StmtError();
3372 }
Mike Stump11289f42009-09-09 15:08:12 +00003373
Douglas Gregorebe10102009-08-20 07:17:43 +00003374 if (!getDerived().AlwaysRebuild() &&
3375 !Var &&
3376 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003377 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003378
3379 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3380 Var,
3381 move(Handler));
3382}
Mike Stump11289f42009-09-09 15:08:12 +00003383
Douglas Gregorebe10102009-08-20 07:17:43 +00003384template<typename Derived>
3385Sema::OwningStmtResult
3386TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3387 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003388 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003389 = getDerived().TransformCompoundStmt(S->getTryBlock());
3390 if (TryBlock.isInvalid())
3391 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003392
Douglas Gregorebe10102009-08-20 07:17:43 +00003393 // Transform the handlers.
3394 bool HandlerChanged = false;
3395 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3396 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003397 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003398 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3399 if (Handler.isInvalid())
3400 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003401
Douglas Gregorebe10102009-08-20 07:17:43 +00003402 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3403 Handlers.push_back(Handler.takeAs<Stmt>());
3404 }
Mike Stump11289f42009-09-09 15:08:12 +00003405
Douglas Gregorebe10102009-08-20 07:17:43 +00003406 if (!getDerived().AlwaysRebuild() &&
3407 TryBlock.get() == S->getTryBlock() &&
3408 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003409 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003410
3411 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003412 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003413}
Mike Stump11289f42009-09-09 15:08:12 +00003414
Douglas Gregorebe10102009-08-20 07:17:43 +00003415//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003416// Expression transformation
3417//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003418template<typename Derived>
3419Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003420TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E,
3421 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003422 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003423}
Mike Stump11289f42009-09-09 15:08:12 +00003424
3425template<typename Derived>
3426Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003427TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E,
3428 bool isAddressOfOperand) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003429 NestedNameSpecifier *Qualifier = 0;
3430 if (E->getQualifier()) {
3431 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3432 E->getQualifierRange());
3433 if (!Qualifier)
3434 return SemaRef.ExprError();
3435 }
3436
Mike Stump11289f42009-09-09 15:08:12 +00003437 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003438 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3439 if (!ND)
3440 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003441
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003442 if (!getDerived().AlwaysRebuild() &&
3443 Qualifier == E->getQualifier() &&
3444 ND == E->getDecl() &&
3445 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003446 return SemaRef.Owned(E->Retain());
3447
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003448 // FIXME: We're losing the explicit template arguments in this transformation.
3449
John McCall0ad16662009-10-29 08:12:44 +00003450 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003451 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00003452 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3453 TransArgs[I]))
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003454 return SemaRef.ExprError();
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003455 }
3456
3457 // FIXME: Pass the qualifier/qualifier range along.
3458 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003459 ND, E->getLocation(),
3460 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00003461}
Mike Stump11289f42009-09-09 15:08:12 +00003462
Douglas Gregora16548e2009-08-11 05:31:07 +00003463template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003464Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003465TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E,
3466 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003467 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003468}
Mike Stump11289f42009-09-09 15:08:12 +00003469
Douglas Gregora16548e2009-08-11 05:31:07 +00003470template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003471Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003472TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E,
3473 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003474 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003475}
Mike Stump11289f42009-09-09 15:08:12 +00003476
Douglas Gregora16548e2009-08-11 05:31:07 +00003477template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003478Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003479TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E,
3480 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003481 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003482}
Mike Stump11289f42009-09-09 15:08:12 +00003483
Douglas Gregora16548e2009-08-11 05:31:07 +00003484template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003485Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003486TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E,
3487 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003488 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003489}
Mike Stump11289f42009-09-09 15:08:12 +00003490
Douglas Gregora16548e2009-08-11 05:31:07 +00003491template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003492Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003493TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E,
3494 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003495 return SemaRef.Owned(E->Retain());
3496}
3497
3498template<typename Derived>
3499Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003500TreeTransform<Derived>::TransformParenExpr(ParenExpr *E,
3501 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003502 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3503 if (SubExpr.isInvalid())
3504 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003505
Douglas Gregora16548e2009-08-11 05:31:07 +00003506 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003507 return SemaRef.Owned(E->Retain());
3508
3509 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003510 E->getRParen());
3511}
3512
Mike Stump11289f42009-09-09 15:08:12 +00003513template<typename Derived>
3514Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003515TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E,
3516 bool isAddressOfOperand) {
3517 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr(),
3518 E->getOpcode() == UnaryOperator::AddrOf);
Douglas Gregora16548e2009-08-11 05:31:07 +00003519 if (SubExpr.isInvalid())
3520 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003521
Douglas Gregora16548e2009-08-11 05:31:07 +00003522 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003523 return SemaRef.Owned(E->Retain());
3524
Douglas Gregora16548e2009-08-11 05:31:07 +00003525 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3526 E->getOpcode(),
3527 move(SubExpr));
3528}
Mike Stump11289f42009-09-09 15:08:12 +00003529
Douglas Gregora16548e2009-08-11 05:31:07 +00003530template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003531Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003532TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
3533 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003534 if (E->isArgumentType()) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003535 TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
3536
Douglas Gregora16548e2009-08-11 05:31:07 +00003537 QualType T = getDerived().TransformType(E->getArgumentType());
3538 if (T.isNull())
3539 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003540
Douglas Gregora16548e2009-08-11 05:31:07 +00003541 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3542 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003543
3544 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3545 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003546 E->getSourceRange());
3547 }
Mike Stump11289f42009-09-09 15:08:12 +00003548
Douglas Gregora16548e2009-08-11 05:31:07 +00003549 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003550 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003551 // C++0x [expr.sizeof]p1:
3552 // The operand is either an expression, which is an unevaluated operand
3553 // [...]
3554 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003555
Douglas Gregora16548e2009-08-11 05:31:07 +00003556 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3557 if (SubExpr.isInvalid())
3558 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003559
Douglas Gregora16548e2009-08-11 05:31:07 +00003560 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3561 return SemaRef.Owned(E->Retain());
3562 }
Mike Stump11289f42009-09-09 15:08:12 +00003563
Douglas Gregora16548e2009-08-11 05:31:07 +00003564 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3565 E->isSizeOf(),
3566 E->getSourceRange());
3567}
Mike Stump11289f42009-09-09 15:08:12 +00003568
Douglas Gregora16548e2009-08-11 05:31:07 +00003569template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003570Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003571TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E,
3572 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003573 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3574 if (LHS.isInvalid())
3575 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003576
Douglas Gregora16548e2009-08-11 05:31:07 +00003577 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3578 if (RHS.isInvalid())
3579 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003580
3581
Douglas Gregora16548e2009-08-11 05:31:07 +00003582 if (!getDerived().AlwaysRebuild() &&
3583 LHS.get() == E->getLHS() &&
3584 RHS.get() == E->getRHS())
3585 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003586
Douglas Gregora16548e2009-08-11 05:31:07 +00003587 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3588 /*FIXME:*/E->getLHS()->getLocStart(),
3589 move(RHS),
3590 E->getRBracketLoc());
3591}
Mike Stump11289f42009-09-09 15:08:12 +00003592
3593template<typename Derived>
3594Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003595TreeTransform<Derived>::TransformCallExpr(CallExpr *E,
3596 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003597 // Transform the callee.
3598 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3599 if (Callee.isInvalid())
3600 return SemaRef.ExprError();
3601
3602 // Transform arguments.
3603 bool ArgChanged = false;
3604 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3605 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3606 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3607 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3608 if (Arg.isInvalid())
3609 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003610
Douglas Gregora16548e2009-08-11 05:31:07 +00003611 // FIXME: Wrong source location information for the ','.
3612 FakeCommaLocs.push_back(
3613 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003614
3615 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003616 Args.push_back(Arg.takeAs<Expr>());
3617 }
Mike Stump11289f42009-09-09 15:08:12 +00003618
Douglas Gregora16548e2009-08-11 05:31:07 +00003619 if (!getDerived().AlwaysRebuild() &&
3620 Callee.get() == E->getCallee() &&
3621 !ArgChanged)
3622 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003623
Douglas Gregora16548e2009-08-11 05:31:07 +00003624 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003625 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003626 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3627 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3628 move_arg(Args),
3629 FakeCommaLocs.data(),
3630 E->getRParenLoc());
3631}
Mike Stump11289f42009-09-09 15:08:12 +00003632
3633template<typename Derived>
3634Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003635TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
3636 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003637 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3638 if (Base.isInvalid())
3639 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003640
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003641 NestedNameSpecifier *Qualifier = 0;
3642 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003643 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003644 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3645 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003646 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003647 return SemaRef.ExprError();
3648 }
Mike Stump11289f42009-09-09 15:08:12 +00003649
3650 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003651 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3652 if (!Member)
3653 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003654
Douglas Gregora16548e2009-08-11 05:31:07 +00003655 if (!getDerived().AlwaysRebuild() &&
3656 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003657 Qualifier == E->getQualifier() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00003658 Member == E->getMemberDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003659 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003660
3661 // FIXME: Bogus source location for the operator
3662 SourceLocation FakeOperatorLoc
3663 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3664
3665 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3666 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003667 Qualifier,
3668 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003669 E->getMemberLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003670 Member);
Douglas Gregora16548e2009-08-11 05:31:07 +00003671}
Mike Stump11289f42009-09-09 15:08:12 +00003672
Douglas Gregora16548e2009-08-11 05:31:07 +00003673template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003674Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003675TreeTransform<Derived>::TransformCastExpr(CastExpr *E,
3676 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003677 assert(false && "Cannot transform abstract class");
3678 return SemaRef.Owned(E->Retain());
3679}
3680
3681template<typename Derived>
3682Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003683TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E,
3684 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003685 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3686 if (LHS.isInvalid())
3687 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003688
Douglas Gregora16548e2009-08-11 05:31:07 +00003689 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3690 if (RHS.isInvalid())
3691 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003692
Douglas Gregora16548e2009-08-11 05:31:07 +00003693 if (!getDerived().AlwaysRebuild() &&
3694 LHS.get() == E->getLHS() &&
3695 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003696 return SemaRef.Owned(E->Retain());
3697
Douglas Gregora16548e2009-08-11 05:31:07 +00003698 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3699 move(LHS), move(RHS));
3700}
3701
Mike Stump11289f42009-09-09 15:08:12 +00003702template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003703Sema::OwningExprResult
3704TreeTransform<Derived>::TransformCompoundAssignOperator(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003705 CompoundAssignOperator *E,
3706 bool isAddressOfOperand) {
3707 return getDerived().TransformBinaryOperator(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00003708}
Mike Stump11289f42009-09-09 15:08:12 +00003709
Douglas Gregora16548e2009-08-11 05:31:07 +00003710template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003711Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003712TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E,
3713 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003714 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3715 if (Cond.isInvalid())
3716 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003717
Douglas Gregora16548e2009-08-11 05:31:07 +00003718 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3719 if (LHS.isInvalid())
3720 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003721
Douglas Gregora16548e2009-08-11 05:31:07 +00003722 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3723 if (RHS.isInvalid())
3724 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003725
Douglas Gregora16548e2009-08-11 05:31:07 +00003726 if (!getDerived().AlwaysRebuild() &&
3727 Cond.get() == E->getCond() &&
3728 LHS.get() == E->getLHS() &&
3729 RHS.get() == E->getRHS())
3730 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003731
3732 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003733 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003734 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003735 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003736 move(RHS));
3737}
Mike Stump11289f42009-09-09 15:08:12 +00003738
3739template<typename Derived>
3740Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003741TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E,
3742 bool isAddressOfOperand) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003743 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3744
3745 // FIXME: Will we ever have type information here? It seems like we won't,
3746 // so do we even need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003747 QualType T = getDerived().TransformType(E->getType());
3748 if (T.isNull())
3749 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003750
Douglas Gregora16548e2009-08-11 05:31:07 +00003751 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3752 if (SubExpr.isInvalid())
3753 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003754
Douglas Gregora16548e2009-08-11 05:31:07 +00003755 if (!getDerived().AlwaysRebuild() &&
3756 T == E->getType() &&
3757 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003758 return SemaRef.Owned(E->Retain());
3759
Douglas Gregora16548e2009-08-11 05:31:07 +00003760 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003761 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003762 E->isLvalueCast());
3763}
Mike Stump11289f42009-09-09 15:08:12 +00003764
Douglas Gregora16548e2009-08-11 05:31:07 +00003765template<typename Derived>
3766Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003767TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E,
3768 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003769 assert(false && "Cannot transform abstract class");
3770 return SemaRef.Owned(E->Retain());
3771}
3772
3773template<typename Derived>
3774Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003775TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E,
3776 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003777 QualType T;
3778 {
3779 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003780 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003781 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3782 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003783
Douglas Gregora16548e2009-08-11 05:31:07 +00003784 T = getDerived().TransformType(E->getTypeAsWritten());
3785 if (T.isNull())
3786 return SemaRef.ExprError();
3787 }
Mike Stump11289f42009-09-09 15:08:12 +00003788
Douglas Gregora16548e2009-08-11 05:31:07 +00003789 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3790 if (SubExpr.isInvalid())
3791 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003792
Douglas Gregora16548e2009-08-11 05:31:07 +00003793 if (!getDerived().AlwaysRebuild() &&
3794 T == E->getTypeAsWritten() &&
3795 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003796 return SemaRef.Owned(E->Retain());
3797
Douglas Gregora16548e2009-08-11 05:31:07 +00003798 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3799 E->getRParenLoc(),
3800 move(SubExpr));
3801}
Mike Stump11289f42009-09-09 15:08:12 +00003802
Douglas Gregora16548e2009-08-11 05:31:07 +00003803template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003804Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003805TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E,
3806 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003807 QualType T;
3808 {
3809 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003810 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003811 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3812 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003813
Douglas Gregora16548e2009-08-11 05:31:07 +00003814 T = getDerived().TransformType(E->getType());
3815 if (T.isNull())
3816 return SemaRef.ExprError();
3817 }
Mike Stump11289f42009-09-09 15:08:12 +00003818
Douglas Gregora16548e2009-08-11 05:31:07 +00003819 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3820 if (Init.isInvalid())
3821 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003822
Douglas Gregora16548e2009-08-11 05:31:07 +00003823 if (!getDerived().AlwaysRebuild() &&
3824 T == E->getType() &&
3825 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003826 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003827
3828 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3829 /*FIXME:*/E->getInitializer()->getLocEnd(),
3830 move(Init));
3831}
Mike Stump11289f42009-09-09 15:08:12 +00003832
Douglas Gregora16548e2009-08-11 05:31:07 +00003833template<typename Derived>
3834Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003835TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E,
3836 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003837 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3838 if (Base.isInvalid())
3839 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003840
Douglas Gregora16548e2009-08-11 05:31:07 +00003841 if (!getDerived().AlwaysRebuild() &&
3842 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003843 return SemaRef.Owned(E->Retain());
3844
Douglas Gregora16548e2009-08-11 05:31:07 +00003845 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003846 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003847 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3848 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3849 E->getAccessorLoc(),
3850 E->getAccessor());
3851}
Mike Stump11289f42009-09-09 15:08:12 +00003852
Douglas Gregora16548e2009-08-11 05:31:07 +00003853template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003854Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003855TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E,
3856 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003857 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003858
Douglas Gregora16548e2009-08-11 05:31:07 +00003859 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3860 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3861 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3862 if (Init.isInvalid())
3863 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003864
Douglas Gregora16548e2009-08-11 05:31:07 +00003865 InitChanged = InitChanged || Init.get() != E->getInit(I);
3866 Inits.push_back(Init.takeAs<Expr>());
3867 }
Mike Stump11289f42009-09-09 15:08:12 +00003868
Douglas Gregora16548e2009-08-11 05:31:07 +00003869 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003870 return SemaRef.Owned(E->Retain());
3871
Douglas Gregora16548e2009-08-11 05:31:07 +00003872 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3873 E->getRBraceLoc());
3874}
Mike Stump11289f42009-09-09 15:08:12 +00003875
Douglas Gregora16548e2009-08-11 05:31:07 +00003876template<typename Derived>
3877Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003878TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E,
3879 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003880 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003881
Douglas Gregorebe10102009-08-20 07:17:43 +00003882 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003883 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3884 if (Init.isInvalid())
3885 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003886
Douglas Gregorebe10102009-08-20 07:17:43 +00003887 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003888 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3889 bool ExprChanged = false;
3890 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3891 DEnd = E->designators_end();
3892 D != DEnd; ++D) {
3893 if (D->isFieldDesignator()) {
3894 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3895 D->getDotLoc(),
3896 D->getFieldLoc()));
3897 continue;
3898 }
Mike Stump11289f42009-09-09 15:08:12 +00003899
Douglas Gregora16548e2009-08-11 05:31:07 +00003900 if (D->isArrayDesignator()) {
3901 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3902 if (Index.isInvalid())
3903 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003904
3905 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003906 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003907
Douglas Gregora16548e2009-08-11 05:31:07 +00003908 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3909 ArrayExprs.push_back(Index.release());
3910 continue;
3911 }
Mike Stump11289f42009-09-09 15:08:12 +00003912
Douglas Gregora16548e2009-08-11 05:31:07 +00003913 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003914 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003915 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3916 if (Start.isInvalid())
3917 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003918
Douglas Gregora16548e2009-08-11 05:31:07 +00003919 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3920 if (End.isInvalid())
3921 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003922
3923 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003924 End.get(),
3925 D->getLBracketLoc(),
3926 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003927
Douglas Gregora16548e2009-08-11 05:31:07 +00003928 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3929 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003930
Douglas Gregora16548e2009-08-11 05:31:07 +00003931 ArrayExprs.push_back(Start.release());
3932 ArrayExprs.push_back(End.release());
3933 }
Mike Stump11289f42009-09-09 15:08:12 +00003934
Douglas Gregora16548e2009-08-11 05:31:07 +00003935 if (!getDerived().AlwaysRebuild() &&
3936 Init.get() == E->getInit() &&
3937 !ExprChanged)
3938 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003939
Douglas Gregora16548e2009-08-11 05:31:07 +00003940 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3941 E->getEqualOrColonLoc(),
3942 E->usesGNUSyntax(), move(Init));
3943}
Mike Stump11289f42009-09-09 15:08:12 +00003944
Douglas Gregora16548e2009-08-11 05:31:07 +00003945template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003946Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003947TreeTransform<Derived>::TransformImplicitValueInitExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003948 ImplicitValueInitExpr *E,
3949 bool isAddressOfOperand) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003950 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3951
3952 // FIXME: Will we ever have proper type location here? Will we actually
3953 // need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003954 QualType T = getDerived().TransformType(E->getType());
3955 if (T.isNull())
3956 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003957
Douglas Gregora16548e2009-08-11 05:31:07 +00003958 if (!getDerived().AlwaysRebuild() &&
3959 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003960 return SemaRef.Owned(E->Retain());
3961
Douglas Gregora16548e2009-08-11 05:31:07 +00003962 return getDerived().RebuildImplicitValueInitExpr(T);
3963}
Mike Stump11289f42009-09-09 15:08:12 +00003964
Douglas Gregora16548e2009-08-11 05:31:07 +00003965template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003966Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003967TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E,
3968 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003969 // FIXME: Do we want the type as written?
3970 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003971
Douglas Gregora16548e2009-08-11 05:31:07 +00003972 {
3973 // FIXME: Source location isn't quite accurate.
3974 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3975 T = getDerived().TransformType(E->getType());
3976 if (T.isNull())
3977 return SemaRef.ExprError();
3978 }
Mike Stump11289f42009-09-09 15:08:12 +00003979
Douglas Gregora16548e2009-08-11 05:31:07 +00003980 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3981 if (SubExpr.isInvalid())
3982 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003983
Douglas Gregora16548e2009-08-11 05:31:07 +00003984 if (!getDerived().AlwaysRebuild() &&
3985 T == E->getType() &&
3986 SubExpr.get() == E->getSubExpr())
3987 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003988
Douglas Gregora16548e2009-08-11 05:31:07 +00003989 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3990 T, E->getRParenLoc());
3991}
3992
3993template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003994Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003995TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E,
3996 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003997 bool ArgumentChanged = false;
3998 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3999 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
4000 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
4001 if (Init.isInvalid())
4002 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004003
Douglas Gregora16548e2009-08-11 05:31:07 +00004004 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
4005 Inits.push_back(Init.takeAs<Expr>());
4006 }
Mike Stump11289f42009-09-09 15:08:12 +00004007
Douglas Gregora16548e2009-08-11 05:31:07 +00004008 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
4009 move_arg(Inits),
4010 E->getRParenLoc());
4011}
Mike Stump11289f42009-09-09 15:08:12 +00004012
Douglas Gregora16548e2009-08-11 05:31:07 +00004013/// \brief Transform an address-of-label expression.
4014///
4015/// By default, the transformation of an address-of-label expression always
4016/// rebuilds the expression, so that the label identifier can be resolved to
4017/// the corresponding label statement by semantic analysis.
4018template<typename Derived>
4019Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004020TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E,
4021 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004022 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
4023 E->getLabel());
4024}
Mike Stump11289f42009-09-09 15:08:12 +00004025
4026template<typename Derived>
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004027Sema::OwningExprResult
4028TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E,
4029 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004030 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00004031 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
4032 if (SubStmt.isInvalid())
4033 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004034
Douglas Gregora16548e2009-08-11 05:31:07 +00004035 if (!getDerived().AlwaysRebuild() &&
4036 SubStmt.get() == E->getSubStmt())
4037 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004038
4039 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004040 move(SubStmt),
4041 E->getRParenLoc());
4042}
Mike Stump11289f42009-09-09 15:08:12 +00004043
Douglas Gregora16548e2009-08-11 05:31:07 +00004044template<typename Derived>
4045Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004046TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E,
4047 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004048 QualType T1, T2;
4049 {
4050 // FIXME: Source location isn't quite accurate.
4051 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004052
Douglas Gregora16548e2009-08-11 05:31:07 +00004053 T1 = getDerived().TransformType(E->getArgType1());
4054 if (T1.isNull())
4055 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004056
Douglas Gregora16548e2009-08-11 05:31:07 +00004057 T2 = getDerived().TransformType(E->getArgType2());
4058 if (T2.isNull())
4059 return SemaRef.ExprError();
4060 }
4061
4062 if (!getDerived().AlwaysRebuild() &&
4063 T1 == E->getArgType1() &&
4064 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00004065 return SemaRef.Owned(E->Retain());
4066
Douglas Gregora16548e2009-08-11 05:31:07 +00004067 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
4068 T1, T2, E->getRParenLoc());
4069}
Mike Stump11289f42009-09-09 15:08:12 +00004070
Douglas Gregora16548e2009-08-11 05:31:07 +00004071template<typename Derived>
4072Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004073TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E,
4074 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004075 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4076 if (Cond.isInvalid())
4077 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004078
Douglas Gregora16548e2009-08-11 05:31:07 +00004079 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4080 if (LHS.isInvalid())
4081 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004082
Douglas Gregora16548e2009-08-11 05:31:07 +00004083 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4084 if (RHS.isInvalid())
4085 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004086
Douglas Gregora16548e2009-08-11 05:31:07 +00004087 if (!getDerived().AlwaysRebuild() &&
4088 Cond.get() == E->getCond() &&
4089 LHS.get() == E->getLHS() &&
4090 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00004091 return SemaRef.Owned(E->Retain());
4092
Douglas Gregora16548e2009-08-11 05:31:07 +00004093 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4094 move(Cond), move(LHS), move(RHS),
4095 E->getRParenLoc());
4096}
Mike Stump11289f42009-09-09 15:08:12 +00004097
Douglas Gregora16548e2009-08-11 05:31:07 +00004098template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004099Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004100TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E,
4101 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004102 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004103}
4104
4105template<typename Derived>
4106Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004107TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E,
4108 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004109 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4110 if (Callee.isInvalid())
4111 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004112
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004113 OwningExprResult First
4114 = getDerived().TransformExpr(E->getArg(0),
4115 E->getNumArgs() == 1 && E->getOperator() == OO_Amp);
Douglas Gregora16548e2009-08-11 05:31:07 +00004116 if (First.isInvalid())
4117 return SemaRef.ExprError();
4118
4119 OwningExprResult Second(SemaRef);
4120 if (E->getNumArgs() == 2) {
4121 Second = getDerived().TransformExpr(E->getArg(1));
4122 if (Second.isInvalid())
4123 return SemaRef.ExprError();
4124 }
Mike Stump11289f42009-09-09 15:08:12 +00004125
Douglas Gregora16548e2009-08-11 05:31:07 +00004126 if (!getDerived().AlwaysRebuild() &&
4127 Callee.get() == E->getCallee() &&
4128 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00004129 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4130 return SemaRef.Owned(E->Retain());
4131
Douglas Gregora16548e2009-08-11 05:31:07 +00004132 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4133 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004134 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00004135 move(First),
4136 move(Second));
4137}
Mike Stump11289f42009-09-09 15:08:12 +00004138
Douglas Gregora16548e2009-08-11 05:31:07 +00004139template<typename Derived>
4140Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004141TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E,
4142 bool isAddressOfOperand) {
4143 return getDerived().TransformCallExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004144}
Mike Stump11289f42009-09-09 15:08:12 +00004145
Douglas Gregora16548e2009-08-11 05:31:07 +00004146template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004147Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004148TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E,
4149 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004150 QualType ExplicitTy;
4151 {
4152 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00004153 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004154 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4155 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004156
Douglas Gregora16548e2009-08-11 05:31:07 +00004157 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4158 if (ExplicitTy.isNull())
4159 return SemaRef.ExprError();
4160 }
Mike Stump11289f42009-09-09 15:08:12 +00004161
Douglas Gregora16548e2009-08-11 05:31:07 +00004162 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4163 if (SubExpr.isInvalid())
4164 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004165
Douglas Gregora16548e2009-08-11 05:31:07 +00004166 if (!getDerived().AlwaysRebuild() &&
4167 ExplicitTy == E->getTypeAsWritten() &&
4168 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004169 return SemaRef.Owned(E->Retain());
4170
Douglas Gregora16548e2009-08-11 05:31:07 +00004171 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00004172 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004173 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4174 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4175 SourceLocation FakeRParenLoc
4176 = SemaRef.PP.getLocForEndOfToken(
4177 E->getSubExpr()->getSourceRange().getEnd());
4178 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004179 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004180 FakeLAngleLoc,
4181 ExplicitTy,
4182 FakeRAngleLoc,
4183 FakeRAngleLoc,
4184 move(SubExpr),
4185 FakeRParenLoc);
4186}
Mike Stump11289f42009-09-09 15:08:12 +00004187
Douglas Gregora16548e2009-08-11 05:31:07 +00004188template<typename Derived>
4189Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004190TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E,
4191 bool isAddressOfOperand) {
4192 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004193}
Mike Stump11289f42009-09-09 15:08:12 +00004194
4195template<typename Derived>
4196Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004197TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E,
4198 bool isAddressOfOperand) {
4199 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Mike Stump11289f42009-09-09 15:08:12 +00004200}
4201
Douglas Gregora16548e2009-08-11 05:31:07 +00004202template<typename Derived>
4203Sema::OwningExprResult
4204TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004205 CXXReinterpretCastExpr *E,
4206 bool isAddressOfOperand) {
4207 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004208}
Mike Stump11289f42009-09-09 15:08:12 +00004209
Douglas Gregora16548e2009-08-11 05:31:07 +00004210template<typename Derived>
4211Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004212TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E,
4213 bool isAddressOfOperand) {
4214 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004215}
Mike Stump11289f42009-09-09 15:08:12 +00004216
Douglas Gregora16548e2009-08-11 05:31:07 +00004217template<typename Derived>
4218Sema::OwningExprResult
4219TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004220 CXXFunctionalCastExpr *E,
4221 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004222 QualType ExplicitTy;
4223 {
4224 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004225
Douglas Gregora16548e2009-08-11 05:31:07 +00004226 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4227 if (ExplicitTy.isNull())
4228 return SemaRef.ExprError();
4229 }
Mike Stump11289f42009-09-09 15:08:12 +00004230
Douglas Gregora16548e2009-08-11 05:31:07 +00004231 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4232 if (SubExpr.isInvalid())
4233 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004234
Douglas Gregora16548e2009-08-11 05:31:07 +00004235 if (!getDerived().AlwaysRebuild() &&
4236 ExplicitTy == E->getTypeAsWritten() &&
4237 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004238 return SemaRef.Owned(E->Retain());
4239
Douglas Gregora16548e2009-08-11 05:31:07 +00004240 // FIXME: The end of the type's source range is wrong
4241 return getDerived().RebuildCXXFunctionalCastExpr(
4242 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4243 ExplicitTy,
4244 /*FIXME:*/E->getSubExpr()->getLocStart(),
4245 move(SubExpr),
4246 E->getRParenLoc());
4247}
Mike Stump11289f42009-09-09 15:08:12 +00004248
Douglas Gregora16548e2009-08-11 05:31:07 +00004249template<typename Derived>
4250Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004251TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E,
4252 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004253 if (E->isTypeOperand()) {
4254 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004255
Douglas Gregora16548e2009-08-11 05:31:07 +00004256 QualType T = getDerived().TransformType(E->getTypeOperand());
4257 if (T.isNull())
4258 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004259
Douglas Gregora16548e2009-08-11 05:31:07 +00004260 if (!getDerived().AlwaysRebuild() &&
4261 T == E->getTypeOperand())
4262 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004263
Douglas Gregora16548e2009-08-11 05:31:07 +00004264 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4265 /*FIXME:*/E->getLocStart(),
4266 T,
4267 E->getLocEnd());
4268 }
Mike Stump11289f42009-09-09 15:08:12 +00004269
Douglas Gregora16548e2009-08-11 05:31:07 +00004270 // We don't know whether the expression is potentially evaluated until
4271 // after we perform semantic analysis, so the expression is potentially
4272 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004273 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004274 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004275
Douglas Gregora16548e2009-08-11 05:31:07 +00004276 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4277 if (SubExpr.isInvalid())
4278 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004279
Douglas Gregora16548e2009-08-11 05:31:07 +00004280 if (!getDerived().AlwaysRebuild() &&
4281 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004282 return SemaRef.Owned(E->Retain());
4283
Douglas Gregora16548e2009-08-11 05:31:07 +00004284 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4285 /*FIXME:*/E->getLocStart(),
4286 move(SubExpr),
4287 E->getLocEnd());
4288}
4289
4290template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004291Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004292TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E,
4293 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004294 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004295}
Mike Stump11289f42009-09-09 15:08:12 +00004296
Douglas Gregora16548e2009-08-11 05:31:07 +00004297template<typename Derived>
4298Sema::OwningExprResult
4299TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004300 CXXNullPtrLiteralExpr *E,
4301 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004302 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004303}
Mike Stump11289f42009-09-09 15:08:12 +00004304
Douglas Gregora16548e2009-08-11 05:31:07 +00004305template<typename Derived>
4306Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004307TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E,
4308 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004309 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004310
Douglas Gregora16548e2009-08-11 05:31:07 +00004311 QualType T = getDerived().TransformType(E->getType());
4312 if (T.isNull())
4313 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004314
Douglas Gregora16548e2009-08-11 05:31:07 +00004315 if (!getDerived().AlwaysRebuild() &&
4316 T == E->getType())
4317 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004318
Douglas Gregora16548e2009-08-11 05:31:07 +00004319 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4320}
Mike Stump11289f42009-09-09 15:08:12 +00004321
Douglas Gregora16548e2009-08-11 05:31:07 +00004322template<typename Derived>
4323Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004324TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E,
4325 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004326 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4327 if (SubExpr.isInvalid())
4328 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004329
Douglas Gregora16548e2009-08-11 05:31:07 +00004330 if (!getDerived().AlwaysRebuild() &&
4331 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004332 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004333
4334 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4335}
Mike Stump11289f42009-09-09 15:08:12 +00004336
Douglas Gregora16548e2009-08-11 05:31:07 +00004337template<typename Derived>
4338Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004339TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
4340 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004341 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004342 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4343 if (!Param)
4344 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004345
Douglas Gregora16548e2009-08-11 05:31:07 +00004346 if (getDerived().AlwaysRebuild() &&
4347 Param == E->getParam())
4348 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004349
Douglas Gregora16548e2009-08-11 05:31:07 +00004350 return getDerived().RebuildCXXDefaultArgExpr(Param);
4351}
Mike Stump11289f42009-09-09 15:08:12 +00004352
Douglas Gregora16548e2009-08-11 05:31:07 +00004353template<typename Derived>
4354Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004355TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E,
4356 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004357 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4358
4359 QualType T = getDerived().TransformType(E->getType());
4360 if (T.isNull())
4361 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004362
Douglas Gregora16548e2009-08-11 05:31:07 +00004363 if (!getDerived().AlwaysRebuild() &&
4364 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004365 return SemaRef.Owned(E->Retain());
4366
4367 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004368 /*FIXME:*/E->getTypeBeginLoc(),
4369 T,
4370 E->getRParenLoc());
4371}
Mike Stump11289f42009-09-09 15:08:12 +00004372
Douglas Gregora16548e2009-08-11 05:31:07 +00004373template<typename Derived>
4374Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004375TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E,
4376 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004377 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004378 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004379 if (!Var)
4380 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004381
Douglas Gregora16548e2009-08-11 05:31:07 +00004382 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004383 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004384 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004385
4386 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004387 /*FIXME:*/E->getStartLoc(),
4388 Var);
4389}
Mike Stump11289f42009-09-09 15:08:12 +00004390
Douglas Gregora16548e2009-08-11 05:31:07 +00004391template<typename Derived>
4392Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004393TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E,
4394 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004395 // Transform the type that we're allocating
4396 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4397 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4398 if (AllocType.isNull())
4399 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004400
Douglas Gregora16548e2009-08-11 05:31:07 +00004401 // Transform the size of the array we're allocating (if any).
4402 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4403 if (ArraySize.isInvalid())
4404 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004405
Douglas Gregora16548e2009-08-11 05:31:07 +00004406 // Transform the placement arguments (if any).
4407 bool ArgumentChanged = false;
4408 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4409 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4410 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4411 if (Arg.isInvalid())
4412 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004413
Douglas Gregora16548e2009-08-11 05:31:07 +00004414 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4415 PlacementArgs.push_back(Arg.take());
4416 }
Mike Stump11289f42009-09-09 15:08:12 +00004417
Douglas Gregorebe10102009-08-20 07:17:43 +00004418 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004419 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4420 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4421 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4422 if (Arg.isInvalid())
4423 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004424
Douglas Gregora16548e2009-08-11 05:31:07 +00004425 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4426 ConstructorArgs.push_back(Arg.take());
4427 }
Mike Stump11289f42009-09-09 15:08:12 +00004428
Douglas Gregora16548e2009-08-11 05:31:07 +00004429 if (!getDerived().AlwaysRebuild() &&
4430 AllocType == E->getAllocatedType() &&
4431 ArraySize.get() == E->getArraySize() &&
4432 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004433 return SemaRef.Owned(E->Retain());
4434
Douglas Gregora16548e2009-08-11 05:31:07 +00004435 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4436 E->isGlobalNew(),
4437 /*FIXME:*/E->getLocStart(),
4438 move_arg(PlacementArgs),
4439 /*FIXME:*/E->getLocStart(),
4440 E->isParenTypeId(),
4441 AllocType,
4442 /*FIXME:*/E->getLocStart(),
4443 /*FIXME:*/SourceRange(),
4444 move(ArraySize),
4445 /*FIXME:*/E->getLocStart(),
4446 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004447 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004448}
Mike Stump11289f42009-09-09 15:08:12 +00004449
Douglas Gregora16548e2009-08-11 05:31:07 +00004450template<typename Derived>
4451Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004452TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E,
4453 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004454 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4455 if (Operand.isInvalid())
4456 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004457
Douglas Gregora16548e2009-08-11 05:31:07 +00004458 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004459 Operand.get() == E->getArgument())
4460 return SemaRef.Owned(E->Retain());
4461
Douglas Gregora16548e2009-08-11 05:31:07 +00004462 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4463 E->isGlobalDelete(),
4464 E->isArrayForm(),
4465 move(Operand));
4466}
Mike Stump11289f42009-09-09 15:08:12 +00004467
Douglas Gregora16548e2009-08-11 05:31:07 +00004468template<typename Derived>
4469Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004470TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004471 CXXPseudoDestructorExpr *E,
4472 bool isAddressOfOperand) {
Douglas Gregorad8a3362009-09-04 17:36:40 +00004473 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4474 if (Base.isInvalid())
4475 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004476
Douglas Gregorad8a3362009-09-04 17:36:40 +00004477 NestedNameSpecifier *Qualifier
4478 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4479 E->getQualifierRange());
4480 if (E->getQualifier() && !Qualifier)
4481 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004482
Douglas Gregorad8a3362009-09-04 17:36:40 +00004483 QualType DestroyedType;
4484 {
4485 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4486 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4487 if (DestroyedType.isNull())
4488 return SemaRef.ExprError();
4489 }
Mike Stump11289f42009-09-09 15:08:12 +00004490
Douglas Gregorad8a3362009-09-04 17:36:40 +00004491 if (!getDerived().AlwaysRebuild() &&
4492 Base.get() == E->getBase() &&
4493 Qualifier == E->getQualifier() &&
4494 DestroyedType == E->getDestroyedType())
4495 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004496
Douglas Gregorad8a3362009-09-04 17:36:40 +00004497 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4498 E->getOperatorLoc(),
4499 E->isArrow(),
4500 E->getDestroyedTypeLoc(),
4501 DestroyedType,
4502 Qualifier,
4503 E->getQualifierRange());
4504}
Mike Stump11289f42009-09-09 15:08:12 +00004505
Douglas Gregorad8a3362009-09-04 17:36:40 +00004506template<typename Derived>
4507Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004508TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004509 UnresolvedFunctionNameExpr *E,
4510 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004511 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004512 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004513}
Mike Stump11289f42009-09-09 15:08:12 +00004514
Douglas Gregora16548e2009-08-11 05:31:07 +00004515template<typename Derived>
4516Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004517TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E,
4518 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004519 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004520
Douglas Gregora16548e2009-08-11 05:31:07 +00004521 QualType T = getDerived().TransformType(E->getQueriedType());
4522 if (T.isNull())
4523 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004524
Douglas Gregora16548e2009-08-11 05:31:07 +00004525 if (!getDerived().AlwaysRebuild() &&
4526 T == E->getQueriedType())
4527 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004528
Douglas Gregora16548e2009-08-11 05:31:07 +00004529 // FIXME: Bad location information
4530 SourceLocation FakeLParenLoc
4531 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004532
4533 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004534 E->getLocStart(),
4535 /*FIXME:*/FakeLParenLoc,
4536 T,
4537 E->getLocEnd());
4538}
Mike Stump11289f42009-09-09 15:08:12 +00004539
Douglas Gregora16548e2009-08-11 05:31:07 +00004540template<typename Derived>
4541Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004542TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004543 UnresolvedDeclRefExpr *E,
4544 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004545 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004546 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4547 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004548 if (!NNS)
4549 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004550
4551 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004552 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4553 if (!Name)
4554 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004555
4556 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004557 NNS == E->getQualifier() &&
4558 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004559 return SemaRef.Owned(E->Retain());
4560
4561 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004562 E->getQualifierRange(),
4563 Name,
4564 E->getLocation(),
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004565 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004566}
4567
4568template<typename Derived>
4569Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004570TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E,
4571 bool isAddressOfOperand) {
Douglas Gregorba91b892009-10-29 17:56:10 +00004572 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4573
Mike Stump11289f42009-09-09 15:08:12 +00004574 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004575 = getDerived().TransformTemplateName(E->getTemplateName());
4576 if (Template.isNull())
4577 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004578
Douglas Gregord019ff62009-10-22 17:20:55 +00004579 NestedNameSpecifier *Qualifier = 0;
4580 if (E->getQualifier()) {
4581 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4582 E->getQualifierRange());
4583 if (!Qualifier)
4584 return SemaRef.ExprError();
4585 }
4586
John McCall0ad16662009-10-29 08:12:44 +00004587 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora16548e2009-08-11 05:31:07 +00004588 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004589 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4590 TransArgs[I]))
Douglas Gregora16548e2009-08-11 05:31:07 +00004591 return SemaRef.ExprError();
Douglas Gregora16548e2009-08-11 05:31:07 +00004592 }
4593
4594 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4595 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004596
4597 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004598 // actually refers to a type, in which case the caller is actually dealing
4599 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004600 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4601 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004602 E->getLAngleLoc(),
4603 TransArgs.data(),
4604 TransArgs.size(),
4605 E->getRAngleLoc());
4606}
4607
4608template<typename Derived>
4609Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004610TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E,
4611 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004612 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4613
4614 QualType T = getDerived().TransformType(E->getType());
4615 if (T.isNull())
4616 return SemaRef.ExprError();
4617
4618 CXXConstructorDecl *Constructor
4619 = cast_or_null<CXXConstructorDecl>(
4620 getDerived().TransformDecl(E->getConstructor()));
4621 if (!Constructor)
4622 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004623
Douglas Gregora16548e2009-08-11 05:31:07 +00004624 bool ArgumentChanged = false;
4625 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004626 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004627 ArgEnd = E->arg_end();
4628 Arg != ArgEnd; ++Arg) {
4629 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4630 if (TransArg.isInvalid())
4631 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004632
Douglas Gregora16548e2009-08-11 05:31:07 +00004633 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4634 Args.push_back(TransArg.takeAs<Expr>());
4635 }
4636
4637 if (!getDerived().AlwaysRebuild() &&
4638 T == E->getType() &&
4639 Constructor == E->getConstructor() &&
4640 !ArgumentChanged)
4641 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004642
Douglas Gregora16548e2009-08-11 05:31:07 +00004643 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4644 move_arg(Args));
4645}
Mike Stump11289f42009-09-09 15:08:12 +00004646
Douglas Gregora16548e2009-08-11 05:31:07 +00004647/// \brief Transform a C++ temporary-binding expression.
4648///
Mike Stump11289f42009-09-09 15:08:12 +00004649/// The transformation of a temporary-binding expression always attempts to
4650/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004651/// subexpression itself did not change, because the temporary variable itself
4652/// must be unique.
4653template<typename Derived>
4654Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004655TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
4656 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004657 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4658 if (SubExpr.isInvalid())
4659 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004660
Douglas Gregora16548e2009-08-11 05:31:07 +00004661 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4662}
Mike Stump11289f42009-09-09 15:08:12 +00004663
4664/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004665/// be destroyed after the expression is evaluated.
4666///
Mike Stump11289f42009-09-09 15:08:12 +00004667/// The transformation of a full expression always attempts to build a new
4668/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004669/// subexpression itself did not change, because it will need to capture the
4670/// the new temporary variables introduced in the subexpression.
4671template<typename Derived>
4672Sema::OwningExprResult
4673TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004674 CXXExprWithTemporaries *E,
4675 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004676 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4677 if (SubExpr.isInvalid())
4678 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004679
Douglas Gregora16548e2009-08-11 05:31:07 +00004680 return SemaRef.Owned(
4681 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4682 E->shouldDestroyTemporaries()));
4683}
Mike Stump11289f42009-09-09 15:08:12 +00004684
Douglas Gregora16548e2009-08-11 05:31:07 +00004685template<typename Derived>
4686Sema::OwningExprResult
4687TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004688 CXXTemporaryObjectExpr *E,
4689 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004690 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4691 QualType T = getDerived().TransformType(E->getType());
4692 if (T.isNull())
4693 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004694
Douglas Gregora16548e2009-08-11 05:31:07 +00004695 CXXConstructorDecl *Constructor
4696 = cast_or_null<CXXConstructorDecl>(
4697 getDerived().TransformDecl(E->getConstructor()));
4698 if (!Constructor)
4699 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004700
Douglas Gregora16548e2009-08-11 05:31:07 +00004701 bool ArgumentChanged = false;
4702 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4703 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004704 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004705 ArgEnd = E->arg_end();
4706 Arg != ArgEnd; ++Arg) {
4707 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4708 if (TransArg.isInvalid())
4709 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004710
Douglas Gregora16548e2009-08-11 05:31:07 +00004711 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4712 Args.push_back((Expr *)TransArg.release());
4713 }
Mike Stump11289f42009-09-09 15:08:12 +00004714
Douglas Gregora16548e2009-08-11 05:31:07 +00004715 if (!getDerived().AlwaysRebuild() &&
4716 T == E->getType() &&
4717 Constructor == E->getConstructor() &&
4718 !ArgumentChanged)
4719 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004720
Douglas Gregora16548e2009-08-11 05:31:07 +00004721 // FIXME: Bogus location information
4722 SourceLocation CommaLoc;
4723 if (Args.size() > 1) {
4724 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004725 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004726 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4727 }
4728 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4729 T,
4730 /*FIXME:*/E->getTypeBeginLoc(),
4731 move_arg(Args),
4732 &CommaLoc,
4733 E->getLocEnd());
4734}
Mike Stump11289f42009-09-09 15:08:12 +00004735
Douglas Gregora16548e2009-08-11 05:31:07 +00004736template<typename Derived>
4737Sema::OwningExprResult
4738TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004739 CXXUnresolvedConstructExpr *E,
4740 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004741 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4742 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4743 if (T.isNull())
4744 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004745
Douglas Gregora16548e2009-08-11 05:31:07 +00004746 bool ArgumentChanged = false;
4747 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4748 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4749 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4750 ArgEnd = E->arg_end();
4751 Arg != ArgEnd; ++Arg) {
4752 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4753 if (TransArg.isInvalid())
4754 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004755
Douglas Gregora16548e2009-08-11 05:31:07 +00004756 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4757 FakeCommaLocs.push_back(
4758 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4759 Args.push_back(TransArg.takeAs<Expr>());
4760 }
Mike Stump11289f42009-09-09 15:08:12 +00004761
Douglas Gregora16548e2009-08-11 05:31:07 +00004762 if (!getDerived().AlwaysRebuild() &&
4763 T == E->getTypeAsWritten() &&
4764 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004765 return SemaRef.Owned(E->Retain());
4766
Douglas Gregora16548e2009-08-11 05:31:07 +00004767 // FIXME: we're faking the locations of the commas
4768 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4769 T,
4770 E->getLParenLoc(),
4771 move_arg(Args),
4772 FakeCommaLocs.data(),
4773 E->getRParenLoc());
4774}
Mike Stump11289f42009-09-09 15:08:12 +00004775
Douglas Gregora16548e2009-08-11 05:31:07 +00004776template<typename Derived>
4777Sema::OwningExprResult
4778TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004779 CXXUnresolvedMemberExpr *E,
4780 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004781 // Transform the base of the expression.
4782 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4783 if (Base.isInvalid())
4784 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004785
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004786 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004787 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004788 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004789 E->getOperatorLoc(),
4790 E->isArrow()? tok::arrow : tok::period,
4791 ObjectType);
4792 if (Base.isInvalid())
4793 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004794
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004795 // Transform the first part of the nested-name-specifier that qualifies
4796 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004797 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004798 = getDerived().TransformFirstQualifierInScope(
4799 E->getFirstQualifierFoundInScope(),
4800 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004801
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004802 NestedNameSpecifier *Qualifier = 0;
4803 if (E->getQualifier()) {
4804 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4805 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004806 QualType::getFromOpaquePtr(ObjectType),
4807 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004808 if (!Qualifier)
4809 return SemaRef.ExprError();
4810 }
Mike Stump11289f42009-09-09 15:08:12 +00004811
4812 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004813 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4814 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004815 if (!Name)
4816 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004817
Douglas Gregor308047d2009-09-09 00:23:06 +00004818 if (!E->hasExplicitTemplateArgumentList()) {
4819 // This is a reference to a member without an explicitly-specified
4820 // template argument list. Optimize for this common case.
4821 if (!getDerived().AlwaysRebuild() &&
4822 Base.get() == E->getBase() &&
4823 Qualifier == E->getQualifier() &&
4824 Name == E->getMember() &&
4825 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004826 return SemaRef.Owned(E->Retain());
4827
Douglas Gregor308047d2009-09-09 00:23:06 +00004828 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4829 E->isArrow(),
4830 E->getOperatorLoc(),
4831 Qualifier,
4832 E->getQualifierRange(),
4833 Name,
4834 E->getMemberLoc(),
4835 FirstQualifierInScope);
4836 }
4837
4838 // FIXME: This is an ugly hack, which forces the same template name to
4839 // be looked up multiple times. Yuck!
Douglas Gregor71395fa2009-11-04 00:56:37 +00004840 TemporaryBase Rebase(*this, E->getMemberLoc(), DeclarationName());
4841 TemplateName OrigTemplateName;
4842 if (const IdentifierInfo *II = Name.getAsIdentifierInfo())
4843 OrigTemplateName = SemaRef.Context.getDependentTemplateName(0, II);
4844 else
4845 OrigTemplateName
4846 = SemaRef.Context.getDependentTemplateName(0,
4847 Name.getCXXOverloadedOperator());
Mike Stump11289f42009-09-09 15:08:12 +00004848
4849 TemplateName Template
4850 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004851 QualType::getFromOpaquePtr(ObjectType));
4852 if (Template.isNull())
4853 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004854
John McCall0ad16662009-10-29 08:12:44 +00004855 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor308047d2009-09-09 00:23:06 +00004856 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004857 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4858 TransArgs[I]))
Douglas Gregor308047d2009-09-09 00:23:06 +00004859 return SemaRef.ExprError();
Douglas Gregor308047d2009-09-09 00:23:06 +00004860 }
Mike Stump11289f42009-09-09 15:08:12 +00004861
Douglas Gregora16548e2009-08-11 05:31:07 +00004862 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4863 E->isArrow(),
4864 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004865 Qualifier,
4866 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004867 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004868 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004869 FirstQualifierInScope,
4870 E->getLAngleLoc(),
4871 TransArgs.data(),
4872 TransArgs.size(),
4873 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004874}
4875
4876template<typename Derived>
4877Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004878TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E,
4879 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004880 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004881}
4882
Mike Stump11289f42009-09-09 15:08:12 +00004883template<typename Derived>
4884Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004885TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E,
4886 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004887 // FIXME: poor source location
4888 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4889 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4890 if (EncodedType.isNull())
4891 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004892
Douglas Gregora16548e2009-08-11 05:31:07 +00004893 if (!getDerived().AlwaysRebuild() &&
4894 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004895 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004896
4897 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4898 EncodedType,
4899 E->getRParenLoc());
4900}
Mike Stump11289f42009-09-09 15:08:12 +00004901
Douglas Gregora16548e2009-08-11 05:31:07 +00004902template<typename Derived>
4903Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004904TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E,
4905 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004906 // FIXME: Implement this!
4907 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004908 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004909}
4910
Mike Stump11289f42009-09-09 15:08:12 +00004911template<typename Derived>
4912Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004913TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E,
4914 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004915 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004916}
4917
Mike Stump11289f42009-09-09 15:08:12 +00004918template<typename Derived>
4919Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004920TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E,
4921 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004922 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004923 = cast_or_null<ObjCProtocolDecl>(
4924 getDerived().TransformDecl(E->getProtocol()));
4925 if (!Protocol)
4926 return SemaRef.ExprError();
4927
4928 if (!getDerived().AlwaysRebuild() &&
4929 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004930 return SemaRef.Owned(E->Retain());
4931
Douglas Gregora16548e2009-08-11 05:31:07 +00004932 return getDerived().RebuildObjCProtocolExpr(Protocol,
4933 E->getAtLoc(),
4934 /*FIXME:*/E->getAtLoc(),
4935 /*FIXME:*/E->getAtLoc(),
4936 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004937
Douglas Gregora16548e2009-08-11 05:31:07 +00004938}
4939
Mike Stump11289f42009-09-09 15:08:12 +00004940template<typename Derived>
4941Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004942TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E,
4943 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004944 // FIXME: Implement this!
4945 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004946 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004947}
4948
Mike Stump11289f42009-09-09 15:08:12 +00004949template<typename Derived>
4950Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004951TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E,
4952 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004953 // FIXME: Implement this!
4954 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004955 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004956}
4957
Mike Stump11289f42009-09-09 15:08:12 +00004958template<typename Derived>
4959Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004960TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004961 ObjCImplicitSetterGetterRefExpr *E,
4962 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004963 // FIXME: Implement this!
4964 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004965 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004966}
4967
Mike Stump11289f42009-09-09 15:08:12 +00004968template<typename Derived>
4969Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004970TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E,
4971 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004972 // FIXME: Implement this!
4973 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004974 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004975}
4976
Mike Stump11289f42009-09-09 15:08:12 +00004977template<typename Derived>
4978Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004979TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E,
4980 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004981 // FIXME: Implement this!
4982 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004983 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004984}
4985
Mike Stump11289f42009-09-09 15:08:12 +00004986template<typename Derived>
4987Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004988TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E,
4989 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004990 bool ArgumentChanged = false;
4991 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4992 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4993 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4994 if (SubExpr.isInvalid())
4995 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004996
Douglas Gregora16548e2009-08-11 05:31:07 +00004997 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4998 SubExprs.push_back(SubExpr.takeAs<Expr>());
4999 }
Mike Stump11289f42009-09-09 15:08:12 +00005000
Douglas Gregora16548e2009-08-11 05:31:07 +00005001 if (!getDerived().AlwaysRebuild() &&
5002 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00005003 return SemaRef.Owned(E->Retain());
5004
Douglas Gregora16548e2009-08-11 05:31:07 +00005005 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
5006 move_arg(SubExprs),
5007 E->getRParenLoc());
5008}
5009
Mike Stump11289f42009-09-09 15:08:12 +00005010template<typename Derived>
5011Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00005012TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E,
5013 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005014 // FIXME: Implement this!
5015 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00005016 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00005017}
5018
Mike Stump11289f42009-09-09 15:08:12 +00005019template<typename Derived>
5020Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00005021TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E,
5022 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005023 // FIXME: Implement this!
5024 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00005025 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00005026}
Mike Stump11289f42009-09-09 15:08:12 +00005027
Douglas Gregora16548e2009-08-11 05:31:07 +00005028//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00005029// Type reconstruction
5030//===----------------------------------------------------------------------===//
5031
Mike Stump11289f42009-09-09 15:08:12 +00005032template<typename Derived>
John McCall70dd5f62009-10-30 00:06:24 +00005033QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
5034 SourceLocation Star) {
5035 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005036 getDerived().getBaseEntity());
5037}
5038
Mike Stump11289f42009-09-09 15:08:12 +00005039template<typename Derived>
John McCall70dd5f62009-10-30 00:06:24 +00005040QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
5041 SourceLocation Star) {
5042 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005043 getDerived().getBaseEntity());
5044}
5045
Mike Stump11289f42009-09-09 15:08:12 +00005046template<typename Derived>
5047QualType
John McCall70dd5f62009-10-30 00:06:24 +00005048TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
5049 bool WrittenAsLValue,
5050 SourceLocation Sigil) {
5051 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
5052 Sigil, getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00005053}
5054
5055template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005056QualType
John McCall70dd5f62009-10-30 00:06:24 +00005057TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
5058 QualType ClassType,
5059 SourceLocation Sigil) {
John McCall8ccfcb52009-09-24 19:53:00 +00005060 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00005061 Sigil, getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00005062}
5063
5064template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005065QualType
John McCall70dd5f62009-10-30 00:06:24 +00005066TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType,
5067 SourceLocation Sigil) {
5068 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Sigil,
John McCall550e0c22009-10-21 00:40:46 +00005069 getDerived().getBaseEntity());
5070}
5071
5072template<typename Derived>
5073QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00005074TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
5075 ArrayType::ArraySizeModifier SizeMod,
5076 const llvm::APInt *Size,
5077 Expr *SizeExpr,
5078 unsigned IndexTypeQuals,
5079 SourceRange BracketsRange) {
5080 if (SizeExpr || !Size)
5081 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
5082 IndexTypeQuals, BracketsRange,
5083 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00005084
5085 QualType Types[] = {
5086 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
5087 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
5088 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00005089 };
5090 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
5091 QualType SizeType;
5092 for (unsigned I = 0; I != NumTypes; ++I)
5093 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
5094 SizeType = Types[I];
5095 break;
5096 }
Mike Stump11289f42009-09-09 15:08:12 +00005097
Douglas Gregord6ff3322009-08-04 16:50:30 +00005098 if (SizeType.isNull())
5099 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00005100
Douglas Gregord6ff3322009-08-04 16:50:30 +00005101 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00005102 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005103 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00005104 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00005105}
Mike Stump11289f42009-09-09 15:08:12 +00005106
Douglas Gregord6ff3322009-08-04 16:50:30 +00005107template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005108QualType
5109TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005110 ArrayType::ArraySizeModifier SizeMod,
5111 const llvm::APInt &Size,
John McCall70dd5f62009-10-30 00:06:24 +00005112 unsigned IndexTypeQuals,
5113 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005114 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
John McCall70dd5f62009-10-30 00:06:24 +00005115 IndexTypeQuals, BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005116}
5117
5118template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005119QualType
Mike Stump11289f42009-09-09 15:08:12 +00005120TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005121 ArrayType::ArraySizeModifier SizeMod,
John McCall70dd5f62009-10-30 00:06:24 +00005122 unsigned IndexTypeQuals,
5123 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005124 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
John McCall70dd5f62009-10-30 00:06:24 +00005125 IndexTypeQuals, BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005126}
Mike Stump11289f42009-09-09 15:08:12 +00005127
Douglas Gregord6ff3322009-08-04 16:50:30 +00005128template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005129QualType
5130TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005131 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005132 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005133 unsigned IndexTypeQuals,
5134 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005135 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005136 SizeExpr.takeAs<Expr>(),
5137 IndexTypeQuals, BracketsRange);
5138}
5139
5140template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005141QualType
5142TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005143 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005144 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005145 unsigned IndexTypeQuals,
5146 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005147 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005148 SizeExpr.takeAs<Expr>(),
5149 IndexTypeQuals, BracketsRange);
5150}
5151
5152template<typename Derived>
5153QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5154 unsigned NumElements) {
5155 // FIXME: semantic checking!
5156 return SemaRef.Context.getVectorType(ElementType, NumElements);
5157}
Mike Stump11289f42009-09-09 15:08:12 +00005158
Douglas Gregord6ff3322009-08-04 16:50:30 +00005159template<typename Derived>
5160QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5161 unsigned NumElements,
5162 SourceLocation AttributeLoc) {
5163 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5164 NumElements, true);
5165 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00005166 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005167 AttributeLoc);
5168 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5169 AttributeLoc);
5170}
Mike Stump11289f42009-09-09 15:08:12 +00005171
Douglas Gregord6ff3322009-08-04 16:50:30 +00005172template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005173QualType
5174TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00005175 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005176 SourceLocation AttributeLoc) {
5177 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5178}
Mike Stump11289f42009-09-09 15:08:12 +00005179
Douglas Gregord6ff3322009-08-04 16:50:30 +00005180template<typename Derived>
5181QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00005182 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005183 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00005184 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005185 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00005186 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005187 Quals,
5188 getDerived().getBaseLocation(),
5189 getDerived().getBaseEntity());
5190}
Mike Stump11289f42009-09-09 15:08:12 +00005191
Douglas Gregord6ff3322009-08-04 16:50:30 +00005192template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00005193QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5194 return SemaRef.Context.getFunctionNoProtoType(T);
5195}
5196
5197template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005198QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005199 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5200}
5201
5202template<typename Derived>
5203QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5204 return SemaRef.Context.getTypeOfType(Underlying);
5205}
5206
5207template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005208QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005209 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5210}
5211
5212template<typename Derived>
5213QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00005214 TemplateName Template,
5215 SourceLocation TemplateNameLoc,
5216 SourceLocation LAngleLoc,
5217 const TemplateArgumentLoc *Args,
5218 unsigned NumArgs,
5219 SourceLocation RAngleLoc) {
5220 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
5221 Args, NumArgs, RAngleLoc);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005222}
Mike Stump11289f42009-09-09 15:08:12 +00005223
Douglas Gregor1135c352009-08-06 05:28:30 +00005224template<typename Derived>
5225NestedNameSpecifier *
5226TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5227 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00005228 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005229 QualType ObjectType,
5230 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00005231 CXXScopeSpec SS;
5232 // FIXME: The source location information is all wrong.
5233 SS.setRange(Range);
5234 SS.setScopeRep(Prefix);
5235 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005236 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005237 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005238 ObjectType,
5239 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005240 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005241}
5242
5243template<typename Derived>
5244NestedNameSpecifier *
5245TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5246 SourceRange Range,
5247 NamespaceDecl *NS) {
5248 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5249}
5250
5251template<typename Derived>
5252NestedNameSpecifier *
5253TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5254 SourceRange Range,
5255 bool TemplateKW,
5256 QualType T) {
5257 if (T->isDependentType() || T->isRecordType() ||
5258 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005259 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005260 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5261 T.getTypePtr());
5262 }
Mike Stump11289f42009-09-09 15:08:12 +00005263
Douglas Gregor1135c352009-08-06 05:28:30 +00005264 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5265 return 0;
5266}
Mike Stump11289f42009-09-09 15:08:12 +00005267
Douglas Gregor71dc5092009-08-06 06:41:21 +00005268template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005269TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005270TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5271 bool TemplateKW,
5272 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005273 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005274 Template);
5275}
5276
5277template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005278TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005279TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5280 bool TemplateKW,
5281 OverloadedFunctionDecl *Ovl) {
5282 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5283}
5284
5285template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005286TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005287TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005288 const IdentifierInfo &II,
5289 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005290 CXXScopeSpec SS;
5291 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005292 SS.setScopeRep(Qualifier);
Douglas Gregor3cf81312009-11-03 23:16:33 +00005293 UnqualifiedId Name;
5294 Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
Douglas Gregor308047d2009-09-09 00:23:06 +00005295 return getSema().ActOnDependentTemplateName(
5296 /*FIXME:*/getDerived().getBaseLocation(),
Douglas Gregor308047d2009-09-09 00:23:06 +00005297 SS,
Douglas Gregor3cf81312009-11-03 23:16:33 +00005298 Name,
Douglas Gregor308047d2009-09-09 00:23:06 +00005299 ObjectType.getAsOpaquePtr())
5300 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005301}
Mike Stump11289f42009-09-09 15:08:12 +00005302
Douglas Gregora16548e2009-08-11 05:31:07 +00005303template<typename Derived>
Douglas Gregor71395fa2009-11-04 00:56:37 +00005304TemplateName
5305TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5306 OverloadedOperatorKind Operator,
5307 QualType ObjectType) {
5308 CXXScopeSpec SS;
5309 SS.setRange(SourceRange(getDerived().getBaseLocation()));
5310 SS.setScopeRep(Qualifier);
5311 UnqualifiedId Name;
5312 SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
5313 Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
5314 Operator, SymbolLocations);
5315 return getSema().ActOnDependentTemplateName(
5316 /*FIXME:*/getDerived().getBaseLocation(),
5317 SS,
5318 Name,
5319 ObjectType.getAsOpaquePtr())
5320 .template getAsVal<TemplateName>();
5321}
5322
5323template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005324Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005325TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5326 SourceLocation OpLoc,
5327 ExprArg Callee,
5328 ExprArg First,
5329 ExprArg Second) {
5330 Expr *FirstExpr = (Expr *)First.get();
5331 Expr *SecondExpr = (Expr *)Second.get();
Sebastian Redladba46e2009-10-29 20:17:01 +00005332 DeclRefExpr *DRE
5333 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregora16548e2009-08-11 05:31:07 +00005334 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005335
Douglas Gregora16548e2009-08-11 05:31:07 +00005336 // Determine whether this should be a builtin operation.
Sebastian Redladba46e2009-10-29 20:17:01 +00005337 if (Op == OO_Subscript) {
5338 if (!FirstExpr->getType()->isOverloadableType() &&
5339 !SecondExpr->getType()->isOverloadableType())
5340 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
5341 DRE->getLocStart(),
5342 move(Second), OpLoc);
5343 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005344 if (!FirstExpr->getType()->isOverloadableType()) {
5345 // The argument is not of overloadable type, so try to create a
5346 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005347 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005348 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005349
Douglas Gregora16548e2009-08-11 05:31:07 +00005350 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5351 }
5352 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005353 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005354 !SecondExpr->getType()->isOverloadableType()) {
5355 // Neither of the arguments is an overloadable type, so try to
5356 // create a built-in binary operation.
5357 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005358 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005359 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5360 if (Result.isInvalid())
5361 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005362
Douglas Gregora16548e2009-08-11 05:31:07 +00005363 First.release();
5364 Second.release();
5365 return move(Result);
5366 }
5367 }
Mike Stump11289f42009-09-09 15:08:12 +00005368
5369 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005370 // used during overload resolution.
5371 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005372
Douglas Gregora16548e2009-08-11 05:31:07 +00005373 // FIXME: Do we have to check
5374 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005375 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005376 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005377
Douglas Gregora16548e2009-08-11 05:31:07 +00005378 // Add any functions found via argument-dependent lookup.
5379 Expr *Args[2] = { FirstExpr, SecondExpr };
5380 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005381 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005382 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redlc057f422009-10-23 19:23:15 +00005383 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5384 Functions);
Mike Stump11289f42009-09-09 15:08:12 +00005385
Douglas Gregora16548e2009-08-11 05:31:07 +00005386 // Create the overloaded operator invocation for unary operators.
5387 if (NumArgs == 1 || isPostIncDec) {
Mike Stump11289f42009-09-09 15:08:12 +00005388 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005389 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5390 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5391 }
Mike Stump11289f42009-09-09 15:08:12 +00005392
Sebastian Redladba46e2009-10-29 20:17:01 +00005393 if (Op == OO_Subscript)
5394 return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
5395 move(First),move(Second));
5396
Douglas Gregora16548e2009-08-11 05:31:07 +00005397 // Create the overloaded operator invocation for binary operators.
Mike Stump11289f42009-09-09 15:08:12 +00005398 BinaryOperator::Opcode Opc =
Douglas Gregora16548e2009-08-11 05:31:07 +00005399 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005400 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005401 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5402 if (Result.isInvalid())
5403 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005404
Douglas Gregora16548e2009-08-11 05:31:07 +00005405 First.release();
5406 Second.release();
Mike Stump11289f42009-09-09 15:08:12 +00005407 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00005408}
Mike Stump11289f42009-09-09 15:08:12 +00005409
Douglas Gregord6ff3322009-08-04 16:50:30 +00005410} // end namespace clang
5411
5412#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H