blob: 767725a1f3182f7d2849751b1117598b6439880b [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) {
Douglas Gregor5287f092009-11-05 00:51:44 +0000880 return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
Douglas Gregora16548e2009-08-11 05:31:07 +0000881 }
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.
John McCall4c98fd82009-11-04 07:28:41 +0000887 OwningExprResult RebuildSizeOfAlignOf(DeclaratorInfo *DInfo,
888 SourceLocation OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000889 bool isSizeOf, SourceRange R) {
John McCall4c98fd82009-11-04 07:28:41 +0000890 return getSema().CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeOf, R);
Douglas Gregora16548e2009-08-11 05:31:07 +0000891 }
892
Mike Stump11289f42009-09-09 15:08:12 +0000893 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000894 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000895 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000896 /// By default, performs semantic analysis to build the new expression.
897 /// Subclasses may override this routine to provide different behavior.
898 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
899 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000900 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000901 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
902 OpLoc, isSizeOf, R);
903 if (Result.isInvalid())
904 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000905
Douglas Gregora16548e2009-08-11 05:31:07 +0000906 SubExpr.release();
907 return move(Result);
908 }
Mike Stump11289f42009-09-09 15:08:12 +0000909
Douglas Gregora16548e2009-08-11 05:31:07 +0000910 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000911 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000912 /// By default, performs semantic analysis to build the new expression.
913 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000914 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000915 SourceLocation LBracketLoc,
916 ExprArg RHS,
917 SourceLocation RBracketLoc) {
918 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000919 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000920 RBracketLoc);
921 }
922
923 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000924 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000925 /// By default, performs semantic analysis to build the new expression.
926 /// Subclasses may override this routine to provide different behavior.
927 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
928 MultiExprArg Args,
929 SourceLocation *CommaLocs,
930 SourceLocation RParenLoc) {
931 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
932 move(Args), CommaLocs, RParenLoc);
933 }
934
935 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000936 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000937 /// By default, performs semantic analysis to build the new expression.
938 /// Subclasses may override this routine to provide different behavior.
939 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000940 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000941 NestedNameSpecifier *Qualifier,
942 SourceRange QualifierRange,
943 SourceLocation MemberLoc,
Douglas Gregorb184f0d2009-11-04 23:20:05 +0000944 NamedDecl *Member,
945 bool HasExplicitTemplateArgs,
946 SourceLocation LAngleLoc,
947 const TemplateArgumentLoc *ExplicitTemplateArgs,
948 unsigned NumExplicitTemplateArgs,
949 SourceLocation RAngleLoc,
950 NamedDecl *FirstQualifierInScope) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000951 if (!Member->getDeclName()) {
952 // We have a reference to an unnamed field.
953 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000954
955 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000956 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
957 Member, MemberLoc,
958 cast<FieldDecl>(Member)->getType());
959 return getSema().Owned(ME);
960 }
Mike Stump11289f42009-09-09 15:08:12 +0000961
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000962 CXXScopeSpec SS;
963 if (Qualifier) {
964 SS.setRange(QualifierRange);
965 SS.setScopeRep(Qualifier);
966 }
967
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000968 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000969 isArrow? tok::arrow : tok::period,
970 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000971 Member->getDeclName(),
Douglas Gregorb184f0d2009-11-04 23:20:05 +0000972 HasExplicitTemplateArgs,
973 LAngleLoc,
974 ExplicitTemplateArgs,
975 NumExplicitTemplateArgs,
976 RAngleLoc,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000977 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorb184f0d2009-11-04 23:20:05 +0000978 &SS,
979 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +0000980 }
Mike Stump11289f42009-09-09 15:08:12 +0000981
Douglas Gregora16548e2009-08-11 05:31:07 +0000982 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000983 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000984 /// By default, performs semantic analysis to build the new expression.
985 /// Subclasses may override this routine to provide different behavior.
986 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
987 BinaryOperator::Opcode Opc,
988 ExprArg LHS, ExprArg RHS) {
Douglas Gregor5287f092009-11-05 00:51:44 +0000989 return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc,
990 LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
Douglas Gregora16548e2009-08-11 05:31:07 +0000991 }
992
993 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000994 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000995 /// By default, performs semantic analysis to build the new expression.
996 /// Subclasses may override this routine to provide different behavior.
997 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
998 SourceLocation QuestionLoc,
999 ExprArg LHS,
1000 SourceLocation ColonLoc,
1001 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +00001002 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +00001003 move(LHS), move(RHS));
1004 }
1005
1006 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +00001007 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001008 /// By default, builds a new implicit cast without any semantic analysis.
1009 /// Subclasses may override this routine to provide different behavior.
1010 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
1011 ExprArg SubExpr, bool isLvalue) {
1012 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +00001013 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +00001014 (Expr *)SubExpr.release(),
1015 isLvalue);
1016 return getSema().Owned(ICE);
1017 }
1018
1019 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +00001020 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001021 /// By default, performs semantic analysis to build the new expression.
1022 /// Subclasses may override this routine to provide different behavior.
1023 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1024 QualType ExplicitTy,
1025 SourceLocation RParenLoc,
1026 ExprArg SubExpr) {
1027 return getSema().ActOnCastExpr(/*Scope=*/0,
1028 LParenLoc,
1029 ExplicitTy.getAsOpaquePtr(),
1030 RParenLoc,
1031 move(SubExpr));
1032 }
Mike Stump11289f42009-09-09 15:08:12 +00001033
Douglas Gregora16548e2009-08-11 05:31:07 +00001034 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +00001035 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001036 /// By default, performs semantic analysis to build the new expression.
1037 /// Subclasses may override this routine to provide different behavior.
1038 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1039 QualType T,
1040 SourceLocation RParenLoc,
1041 ExprArg Init) {
1042 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1043 RParenLoc, move(Init));
1044 }
Mike Stump11289f42009-09-09 15:08:12 +00001045
Douglas Gregora16548e2009-08-11 05:31:07 +00001046 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +00001047 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001048 /// By default, performs semantic analysis to build the new expression.
1049 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001050 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001051 SourceLocation OpLoc,
1052 SourceLocation AccessorLoc,
1053 IdentifierInfo &Accessor) {
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001054 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001055 tok::period, AccessorLoc,
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001056 DeclarationName(&Accessor),
Douglas Gregora16548e2009-08-11 05:31:07 +00001057 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1058 }
Mike Stump11289f42009-09-09 15:08:12 +00001059
Douglas Gregora16548e2009-08-11 05:31:07 +00001060 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001061 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001062 /// By default, performs semantic analysis to build the new expression.
1063 /// Subclasses may override this routine to provide different behavior.
1064 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1065 MultiExprArg Inits,
1066 SourceLocation RBraceLoc) {
1067 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1068 }
Mike Stump11289f42009-09-09 15:08:12 +00001069
Douglas Gregora16548e2009-08-11 05:31:07 +00001070 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001071 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001072 /// By default, performs semantic analysis to build the new expression.
1073 /// Subclasses may override this routine to provide different behavior.
1074 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1075 MultiExprArg ArrayExprs,
1076 SourceLocation EqualOrColonLoc,
1077 bool GNUSyntax,
1078 ExprArg Init) {
1079 OwningExprResult Result
1080 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1081 move(Init));
1082 if (Result.isInvalid())
1083 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001084
Douglas Gregora16548e2009-08-11 05:31:07 +00001085 ArrayExprs.release();
1086 return move(Result);
1087 }
Mike Stump11289f42009-09-09 15:08:12 +00001088
Douglas Gregora16548e2009-08-11 05:31:07 +00001089 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001090 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001091 /// By default, builds the implicit value initialization without performing
1092 /// any semantic analysis. Subclasses may override this routine to provide
1093 /// different behavior.
1094 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1095 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1096 }
Mike Stump11289f42009-09-09 15:08:12 +00001097
Douglas Gregora16548e2009-08-11 05:31:07 +00001098 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001099 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001100 /// By default, performs semantic analysis to build the new expression.
1101 /// Subclasses may override this routine to provide different behavior.
1102 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1103 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001104 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001105 RParenLoc);
1106 }
1107
1108 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001109 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001110 /// By default, performs semantic analysis to build the new expression.
1111 /// Subclasses may override this routine to provide different behavior.
1112 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1113 MultiExprArg SubExprs,
1114 SourceLocation RParenLoc) {
1115 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1116 }
Mike Stump11289f42009-09-09 15:08:12 +00001117
Douglas Gregora16548e2009-08-11 05:31:07 +00001118 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001119 ///
1120 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001121 /// rather than attempting to map the label statement itself.
1122 /// Subclasses may override this routine to provide different behavior.
1123 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1124 SourceLocation LabelLoc,
1125 LabelStmt *Label) {
1126 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1127 }
Mike Stump11289f42009-09-09 15:08:12 +00001128
Douglas Gregora16548e2009-08-11 05:31:07 +00001129 /// \brief Build a new GNU statement expression.
Mike Stump11289f42009-09-09 15:08:12 +00001130 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001131 /// By default, performs semantic analysis to build the new expression.
1132 /// Subclasses may override this routine to provide different behavior.
1133 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1134 StmtArg SubStmt,
1135 SourceLocation RParenLoc) {
1136 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1137 }
Mike Stump11289f42009-09-09 15:08:12 +00001138
Douglas Gregora16548e2009-08-11 05:31:07 +00001139 /// \brief Build a new __builtin_types_compatible_p expression.
1140 ///
1141 /// By default, performs semantic analysis to build the new expression.
1142 /// Subclasses may override this routine to provide different behavior.
1143 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1144 QualType T1, QualType T2,
1145 SourceLocation RParenLoc) {
1146 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1147 T1.getAsOpaquePtr(),
1148 T2.getAsOpaquePtr(),
1149 RParenLoc);
1150 }
Mike Stump11289f42009-09-09 15:08:12 +00001151
Douglas Gregora16548e2009-08-11 05:31:07 +00001152 /// \brief Build a new __builtin_choose_expr expression.
1153 ///
1154 /// By default, performs semantic analysis to build the new expression.
1155 /// Subclasses may override this routine to provide different behavior.
1156 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1157 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1158 SourceLocation RParenLoc) {
1159 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1160 move(Cond), move(LHS), move(RHS),
1161 RParenLoc);
1162 }
Mike Stump11289f42009-09-09 15:08:12 +00001163
Douglas Gregora16548e2009-08-11 05:31:07 +00001164 /// \brief Build a new overloaded operator call expression.
1165 ///
1166 /// By default, performs semantic analysis to build the new expression.
1167 /// The semantic analysis provides the behavior of template instantiation,
1168 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001169 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001170 /// argument-dependent lookup, etc. Subclasses may override this routine to
1171 /// provide different behavior.
1172 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1173 SourceLocation OpLoc,
1174 ExprArg Callee,
1175 ExprArg First,
1176 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001177
1178 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001179 /// reinterpret_cast.
1180 ///
1181 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001182 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001183 /// Subclasses may override this routine to provide different behavior.
1184 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1185 Stmt::StmtClass Class,
1186 SourceLocation LAngleLoc,
1187 QualType T,
1188 SourceLocation RAngleLoc,
1189 SourceLocation LParenLoc,
1190 ExprArg SubExpr,
1191 SourceLocation RParenLoc) {
1192 switch (Class) {
1193 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001194 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1195 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001196 move(SubExpr), RParenLoc);
1197
1198 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001199 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1200 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001201 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001202
Douglas Gregora16548e2009-08-11 05:31:07 +00001203 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001204 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1205 RAngleLoc, LParenLoc,
1206 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001207 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001208
Douglas Gregora16548e2009-08-11 05:31:07 +00001209 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001210 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1211 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001212 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001213
Douglas Gregora16548e2009-08-11 05:31:07 +00001214 default:
1215 assert(false && "Invalid C++ named cast");
1216 break;
1217 }
Mike Stump11289f42009-09-09 15:08:12 +00001218
Douglas Gregora16548e2009-08-11 05:31:07 +00001219 return getSema().ExprError();
1220 }
Mike Stump11289f42009-09-09 15:08:12 +00001221
Douglas Gregora16548e2009-08-11 05:31:07 +00001222 /// \brief Build a new C++ static_cast expression.
1223 ///
1224 /// By default, performs semantic analysis to build the new expression.
1225 /// Subclasses may override this routine to provide different behavior.
1226 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1227 SourceLocation LAngleLoc,
1228 QualType T,
1229 SourceLocation RAngleLoc,
1230 SourceLocation LParenLoc,
1231 ExprArg SubExpr,
1232 SourceLocation RParenLoc) {
1233 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001234 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001235 LParenLoc, move(SubExpr), RParenLoc);
1236 }
1237
1238 /// \brief Build a new C++ dynamic_cast expression.
1239 ///
1240 /// By default, performs semantic analysis to build the new expression.
1241 /// Subclasses may override this routine to provide different behavior.
1242 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1243 SourceLocation LAngleLoc,
1244 QualType T,
1245 SourceLocation RAngleLoc,
1246 SourceLocation LParenLoc,
1247 ExprArg SubExpr,
1248 SourceLocation RParenLoc) {
1249 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001250 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001251 LParenLoc, move(SubExpr), RParenLoc);
1252 }
1253
1254 /// \brief Build a new C++ reinterpret_cast expression.
1255 ///
1256 /// By default, performs semantic analysis to build the new expression.
1257 /// Subclasses may override this routine to provide different behavior.
1258 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1259 SourceLocation LAngleLoc,
1260 QualType T,
1261 SourceLocation RAngleLoc,
1262 SourceLocation LParenLoc,
1263 ExprArg SubExpr,
1264 SourceLocation RParenLoc) {
1265 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1266 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1267 LParenLoc, move(SubExpr), RParenLoc);
1268 }
1269
1270 /// \brief Build a new C++ const_cast expression.
1271 ///
1272 /// By default, performs semantic analysis to build the new expression.
1273 /// Subclasses may override this routine to provide different behavior.
1274 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1275 SourceLocation LAngleLoc,
1276 QualType T,
1277 SourceLocation RAngleLoc,
1278 SourceLocation LParenLoc,
1279 ExprArg SubExpr,
1280 SourceLocation RParenLoc) {
1281 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001282 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001283 LParenLoc, move(SubExpr), RParenLoc);
1284 }
Mike Stump11289f42009-09-09 15:08:12 +00001285
Douglas Gregora16548e2009-08-11 05:31:07 +00001286 /// \brief Build a new C++ functional-style cast expression.
1287 ///
1288 /// By default, performs semantic analysis to build the new expression.
1289 /// Subclasses may override this routine to provide different behavior.
1290 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1291 QualType T,
1292 SourceLocation LParenLoc,
1293 ExprArg SubExpr,
1294 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001295 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001296 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1297 T.getAsOpaquePtr(),
1298 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001299 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001300 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001301 RParenLoc);
1302 }
Mike Stump11289f42009-09-09 15:08:12 +00001303
Douglas Gregora16548e2009-08-11 05:31:07 +00001304 /// \brief Build a new C++ typeid(type) expression.
1305 ///
1306 /// By default, performs semantic analysis to build the new expression.
1307 /// Subclasses may override this routine to provide different behavior.
1308 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1309 SourceLocation LParenLoc,
1310 QualType T,
1311 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001312 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001313 T.getAsOpaquePtr(), RParenLoc);
1314 }
Mike Stump11289f42009-09-09 15:08:12 +00001315
Douglas Gregora16548e2009-08-11 05:31:07 +00001316 /// \brief Build a new C++ typeid(expr) expression.
1317 ///
1318 /// By default, performs semantic analysis to build the new expression.
1319 /// Subclasses may override this routine to provide different behavior.
1320 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1321 SourceLocation LParenLoc,
1322 ExprArg Operand,
1323 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001324 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001325 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1326 RParenLoc);
1327 if (Result.isInvalid())
1328 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001329
Douglas Gregora16548e2009-08-11 05:31:07 +00001330 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1331 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001332 }
1333
Douglas Gregora16548e2009-08-11 05:31:07 +00001334 /// \brief Build a new C++ "this" expression.
1335 ///
1336 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001337 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001338 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001339 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001340 QualType ThisType) {
1341 return getSema().Owned(
1342 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1343 }
1344
1345 /// \brief Build a new C++ throw expression.
1346 ///
1347 /// By default, performs semantic analysis to build the new expression.
1348 /// Subclasses may override this routine to provide different behavior.
1349 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1350 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1351 }
1352
1353 /// \brief Build a new C++ default-argument expression.
1354 ///
1355 /// By default, builds a new default-argument expression, which does not
1356 /// require any semantic analysis. Subclasses may override this routine to
1357 /// provide different behavior.
1358 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001359 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001360 }
1361
1362 /// \brief Build a new C++ zero-initialization expression.
1363 ///
1364 /// By default, performs semantic analysis to build the new expression.
1365 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001366 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001367 SourceLocation LParenLoc,
1368 QualType T,
1369 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001370 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1371 T.getAsOpaquePtr(), LParenLoc,
1372 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001373 0, RParenLoc);
1374 }
Mike Stump11289f42009-09-09 15:08:12 +00001375
Douglas Gregora16548e2009-08-11 05:31:07 +00001376 /// \brief Build a new C++ conditional declaration expression.
1377 ///
1378 /// By default, performs semantic analysis to build the new expression.
1379 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001380 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001381 SourceLocation EqLoc,
1382 VarDecl *Var) {
1383 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1384 EqLoc,
1385 Var));
1386 }
Mike Stump11289f42009-09-09 15:08:12 +00001387
Douglas Gregora16548e2009-08-11 05:31:07 +00001388 /// \brief Build a new C++ "new" expression.
1389 ///
1390 /// By default, performs semantic analysis to build the new expression.
1391 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001392 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001393 bool UseGlobal,
1394 SourceLocation PlacementLParen,
1395 MultiExprArg PlacementArgs,
1396 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001397 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001398 QualType AllocType,
1399 SourceLocation TypeLoc,
1400 SourceRange TypeRange,
1401 ExprArg ArraySize,
1402 SourceLocation ConstructorLParen,
1403 MultiExprArg ConstructorArgs,
1404 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001405 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001406 PlacementLParen,
1407 move(PlacementArgs),
1408 PlacementRParen,
1409 ParenTypeId,
1410 AllocType,
1411 TypeLoc,
1412 TypeRange,
1413 move(ArraySize),
1414 ConstructorLParen,
1415 move(ConstructorArgs),
1416 ConstructorRParen);
1417 }
Mike Stump11289f42009-09-09 15:08:12 +00001418
Douglas Gregora16548e2009-08-11 05:31:07 +00001419 /// \brief Build a new C++ "delete" expression.
1420 ///
1421 /// By default, performs semantic analysis to build the new expression.
1422 /// Subclasses may override this routine to provide different behavior.
1423 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1424 bool IsGlobalDelete,
1425 bool IsArrayForm,
1426 ExprArg Operand) {
1427 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1428 move(Operand));
1429 }
Mike Stump11289f42009-09-09 15:08:12 +00001430
Douglas Gregora16548e2009-08-11 05:31:07 +00001431 /// \brief Build a new unary type trait expression.
1432 ///
1433 /// By default, performs semantic analysis to build the new expression.
1434 /// Subclasses may override this routine to provide different behavior.
1435 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1436 SourceLocation StartLoc,
1437 SourceLocation LParenLoc,
1438 QualType T,
1439 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001440 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001441 T.getAsOpaquePtr(), RParenLoc);
1442 }
1443
Mike Stump11289f42009-09-09 15:08:12 +00001444 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001445 /// expression.
1446 ///
1447 /// By default, performs semantic analysis to build the new expression.
1448 /// Subclasses may override this routine to provide different behavior.
1449 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1450 SourceRange QualifierRange,
1451 DeclarationName Name,
1452 SourceLocation Location,
1453 bool IsAddressOfOperand) {
1454 CXXScopeSpec SS;
1455 SS.setRange(QualifierRange);
1456 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001457 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001458 Location,
1459 Name,
1460 /*Trailing lparen=*/false,
1461 &SS,
1462 IsAddressOfOperand);
1463 }
1464
1465 /// \brief Build a new template-id expression.
1466 ///
1467 /// By default, performs semantic analysis to build the new expression.
1468 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001469 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1470 SourceRange QualifierRange,
1471 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001472 SourceLocation TemplateLoc,
1473 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001474 TemplateArgumentLoc *TemplateArgs,
Douglas Gregora16548e2009-08-11 05:31:07 +00001475 unsigned NumTemplateArgs,
1476 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001477 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1478 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001479 LAngleLoc,
1480 TemplateArgs, NumTemplateArgs,
1481 RAngleLoc);
1482 }
1483
1484 /// \brief Build a new object-construction expression.
1485 ///
1486 /// By default, performs semantic analysis to build the new expression.
1487 /// Subclasses may override this routine to provide different behavior.
1488 OwningExprResult RebuildCXXConstructExpr(QualType T,
1489 CXXConstructorDecl *Constructor,
1490 bool IsElidable,
1491 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001492 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1493 SourceLocation(),
1494 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001495 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001496 }
1497
1498 /// \brief Build a new object-construction expression.
1499 ///
1500 /// By default, performs semantic analysis to build the new expression.
1501 /// Subclasses may override this routine to provide different behavior.
1502 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1503 QualType T,
1504 SourceLocation LParenLoc,
1505 MultiExprArg Args,
1506 SourceLocation *Commas,
1507 SourceLocation RParenLoc) {
1508 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1509 T.getAsOpaquePtr(),
1510 LParenLoc,
1511 move(Args),
1512 Commas,
1513 RParenLoc);
1514 }
1515
1516 /// \brief Build a new object-construction expression.
1517 ///
1518 /// By default, performs semantic analysis to build the new expression.
1519 /// Subclasses may override this routine to provide different behavior.
1520 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1521 QualType T,
1522 SourceLocation LParenLoc,
1523 MultiExprArg Args,
1524 SourceLocation *Commas,
1525 SourceLocation RParenLoc) {
1526 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1527 /*FIXME*/LParenLoc),
1528 T.getAsOpaquePtr(),
1529 LParenLoc,
1530 move(Args),
1531 Commas,
1532 RParenLoc);
1533 }
Mike Stump11289f42009-09-09 15:08:12 +00001534
Douglas Gregora16548e2009-08-11 05:31:07 +00001535 /// \brief Build a new member reference expression.
1536 ///
1537 /// By default, performs semantic analysis to build the new expression.
1538 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001539 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001540 bool IsArrow,
1541 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001542 NestedNameSpecifier *Qualifier,
1543 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001544 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001545 SourceLocation MemberLoc,
1546 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001547 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001548 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001549
Douglas Gregora16548e2009-08-11 05:31:07 +00001550 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001551 SS.setRange(QualifierRange);
1552 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001553
Douglas Gregor308047d2009-09-09 00:23:06 +00001554 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001555 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001556 MemberLoc,
1557 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001558 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001559 &SS,
1560 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001561 }
1562
Douglas Gregor308047d2009-09-09 00:23:06 +00001563 /// \brief Build a new member reference expression with explicit template
1564 /// arguments.
1565 ///
1566 /// By default, performs semantic analysis to build the new expression.
1567 /// Subclasses may override this routine to provide different behavior.
1568 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1569 bool IsArrow,
1570 SourceLocation OperatorLoc,
1571 NestedNameSpecifier *Qualifier,
1572 SourceRange QualifierRange,
1573 TemplateName Template,
1574 SourceLocation TemplateNameLoc,
1575 NamedDecl *FirstQualifierInScope,
1576 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001577 const TemplateArgumentLoc *TemplateArgs,
Douglas Gregor308047d2009-09-09 00:23:06 +00001578 unsigned NumTemplateArgs,
1579 SourceLocation RAngleLoc) {
1580 OwningExprResult Base = move(BaseE);
1581 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001582
Douglas Gregor308047d2009-09-09 00:23:06 +00001583 CXXScopeSpec SS;
1584 SS.setRange(QualifierRange);
1585 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001586
Douglas Gregor308047d2009-09-09 00:23:06 +00001587 // FIXME: We're going to end up looking up the template based on its name,
Douglas Gregor30d60cb2009-11-03 19:44:04 +00001588 // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
Douglas Gregor308047d2009-09-09 00:23:06 +00001589 DeclarationName Name;
1590 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1591 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001592 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001593 = Template.getAsOverloadedFunctionDecl())
1594 Name = Ovl->getDeclName();
Douglas Gregor71395fa2009-11-04 00:56:37 +00001595 else {
1596 DependentTemplateName *DTN = Template.getAsDependentTemplateName();
1597 if (DTN->isIdentifier())
1598 Name = DTN->getIdentifier();
1599 else
1600 Name = SemaRef.Context.DeclarationNames.getCXXOperatorName(
1601 DTN->getOperator());
1602 }
Mike Stump11289f42009-09-09 15:08:12 +00001603 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001604 OperatorLoc, OpKind,
1605 TemplateNameLoc, Name, true,
1606 LAngleLoc, TemplateArgs,
1607 NumTemplateArgs, RAngleLoc,
1608 Sema::DeclPtrTy(), &SS);
1609 }
Mike Stump11289f42009-09-09 15:08:12 +00001610
Douglas Gregora16548e2009-08-11 05:31:07 +00001611 /// \brief Build a new Objective-C @encode expression.
1612 ///
1613 /// By default, performs semantic analysis to build the new expression.
1614 /// Subclasses may override this routine to provide different behavior.
1615 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1616 QualType T,
1617 SourceLocation RParenLoc) {
1618 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1619 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001620 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001621
1622 /// \brief Build a new Objective-C protocol expression.
1623 ///
1624 /// By default, performs semantic analysis to build the new expression.
1625 /// Subclasses may override this routine to provide different behavior.
1626 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1627 SourceLocation AtLoc,
1628 SourceLocation ProtoLoc,
1629 SourceLocation LParenLoc,
1630 SourceLocation RParenLoc) {
1631 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1632 Protocol->getIdentifier(),
1633 AtLoc,
1634 ProtoLoc,
1635 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001636 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001637 }
Mike Stump11289f42009-09-09 15:08:12 +00001638
Douglas Gregora16548e2009-08-11 05:31:07 +00001639 /// \brief Build a new shuffle vector expression.
1640 ///
1641 /// By default, performs semantic analysis to build the new expression.
1642 /// Subclasses may override this routine to provide different behavior.
1643 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1644 MultiExprArg SubExprs,
1645 SourceLocation RParenLoc) {
1646 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001647 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001648 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1649 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1650 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1651 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001652
Douglas Gregora16548e2009-08-11 05:31:07 +00001653 // Build a reference to the __builtin_shufflevector builtin
1654 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001655 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001656 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1657 BuiltinLoc, false, false);
1658 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001659
1660 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001661 unsigned NumSubExprs = SubExprs.size();
1662 Expr **Subs = (Expr **)SubExprs.release();
1663 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1664 Subs, NumSubExprs,
1665 Builtin->getResultType(),
1666 RParenLoc);
1667 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001668
Douglas Gregora16548e2009-08-11 05:31:07 +00001669 // Type-check the __builtin_shufflevector expression.
1670 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1671 if (Result.isInvalid())
1672 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001673
Douglas Gregora16548e2009-08-11 05:31:07 +00001674 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001675 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001676 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001677};
Douglas Gregora16548e2009-08-11 05:31:07 +00001678
Douglas Gregorebe10102009-08-20 07:17:43 +00001679template<typename Derived>
1680Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1681 if (!S)
1682 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001683
Douglas Gregorebe10102009-08-20 07:17:43 +00001684 switch (S->getStmtClass()) {
1685 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001686
Douglas Gregorebe10102009-08-20 07:17:43 +00001687 // Transform individual statement nodes
1688#define STMT(Node, Parent) \
1689 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1690#define EXPR(Node, Parent)
1691#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001692
Douglas Gregorebe10102009-08-20 07:17:43 +00001693 // Transform expressions by calling TransformExpr.
1694#define STMT(Node, Parent)
1695#define EXPR(Node, Parent) case Stmt::Node##Class:
1696#include "clang/AST/StmtNodes.def"
1697 {
1698 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1699 if (E.isInvalid())
1700 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001701
Douglas Gregorebe10102009-08-20 07:17:43 +00001702 return getSema().Owned(E.takeAs<Stmt>());
1703 }
Mike Stump11289f42009-09-09 15:08:12 +00001704 }
1705
Douglas Gregorebe10102009-08-20 07:17:43 +00001706 return SemaRef.Owned(S->Retain());
1707}
Mike Stump11289f42009-09-09 15:08:12 +00001708
1709
Douglas Gregore922c772009-08-04 22:27:00 +00001710template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001711Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1712 bool isAddressOfOperand) {
1713 if (!E)
1714 return SemaRef.Owned(E);
1715
1716 switch (E->getStmtClass()) {
1717 case Stmt::NoStmtClass: break;
1718#define STMT(Node, Parent) case Stmt::Node##Class: break;
1719#define EXPR(Node, Parent) \
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00001720 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E), \
1721 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00001722#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001723 }
1724
Douglas Gregora16548e2009-08-11 05:31:07 +00001725 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001726}
1727
1728template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001729NestedNameSpecifier *
1730TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001731 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001732 QualType ObjectType,
1733 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001734 if (!NNS)
1735 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001736
Douglas Gregorebe10102009-08-20 07:17:43 +00001737 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001738 NestedNameSpecifier *Prefix = NNS->getPrefix();
1739 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001740 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001741 ObjectType,
1742 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001743 if (!Prefix)
1744 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001745
1746 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001747 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001748 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001749 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001750 }
Mike Stump11289f42009-09-09 15:08:12 +00001751
Douglas Gregor1135c352009-08-06 05:28:30 +00001752 switch (NNS->getKind()) {
1753 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001754 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001755 "Identifier nested-name-specifier with no prefix or object type");
1756 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1757 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001758 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001759
1760 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001761 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001762 ObjectType,
1763 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001764
Douglas Gregor1135c352009-08-06 05:28:30 +00001765 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001766 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001767 = cast_or_null<NamespaceDecl>(
1768 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001769 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001770 Prefix == NNS->getPrefix() &&
1771 NS == NNS->getAsNamespace())
1772 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001773
Douglas Gregor1135c352009-08-06 05:28:30 +00001774 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1775 }
Mike Stump11289f42009-09-09 15:08:12 +00001776
Douglas Gregor1135c352009-08-06 05:28:30 +00001777 case NestedNameSpecifier::Global:
1778 // There is no meaningful transformation that one could perform on the
1779 // global scope.
1780 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001781
Douglas Gregor1135c352009-08-06 05:28:30 +00001782 case NestedNameSpecifier::TypeSpecWithTemplate:
1783 case NestedNameSpecifier::TypeSpec: {
Douglas Gregor07cc4ac2009-10-29 22:21:39 +00001784 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregor1135c352009-08-06 05:28:30 +00001785 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001786 if (T.isNull())
1787 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001788
Douglas Gregor1135c352009-08-06 05:28:30 +00001789 if (!getDerived().AlwaysRebuild() &&
1790 Prefix == NNS->getPrefix() &&
1791 T == QualType(NNS->getAsType(), 0))
1792 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001793
1794 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1795 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001796 T);
1797 }
1798 }
Mike Stump11289f42009-09-09 15:08:12 +00001799
Douglas Gregor1135c352009-08-06 05:28:30 +00001800 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001801 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001802}
1803
1804template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001805DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001806TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001807 SourceLocation Loc,
1808 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001809 if (!Name)
1810 return Name;
1811
1812 switch (Name.getNameKind()) {
1813 case DeclarationName::Identifier:
1814 case DeclarationName::ObjCZeroArgSelector:
1815 case DeclarationName::ObjCOneArgSelector:
1816 case DeclarationName::ObjCMultiArgSelector:
1817 case DeclarationName::CXXOperatorName:
1818 case DeclarationName::CXXUsingDirective:
1819 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001820
Douglas Gregorf816bd72009-09-03 22:13:48 +00001821 case DeclarationName::CXXConstructorName:
1822 case DeclarationName::CXXDestructorName:
1823 case DeclarationName::CXXConversionFunctionName: {
1824 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001825 QualType T;
1826 if (!ObjectType.isNull() &&
1827 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1828 TemplateSpecializationType *SpecType
1829 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1830 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1831 } else
1832 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001833 if (T.isNull())
1834 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001835
Douglas Gregorf816bd72009-09-03 22:13:48 +00001836 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001837 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001838 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001839 }
Mike Stump11289f42009-09-09 15:08:12 +00001840 }
1841
Douglas Gregorf816bd72009-09-03 22:13:48 +00001842 return DeclarationName();
1843}
1844
1845template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001846TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001847TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1848 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001849 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001850 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001851 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1852 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1853 if (!NNS)
1854 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001855
Douglas Gregor71dc5092009-08-06 06:41:21 +00001856 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001857 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001858 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1859 if (!TransTemplate)
1860 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001861
Douglas Gregor71dc5092009-08-06 06:41:21 +00001862 if (!getDerived().AlwaysRebuild() &&
1863 NNS == QTN->getQualifier() &&
1864 TransTemplate == Template)
1865 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001866
Douglas Gregor71dc5092009-08-06 06:41:21 +00001867 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1868 TransTemplate);
1869 }
Mike Stump11289f42009-09-09 15:08:12 +00001870
Douglas Gregor71dc5092009-08-06 06:41:21 +00001871 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1872 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001873 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001874 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1875 if (!TransOvl)
1876 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001877
Douglas Gregor71dc5092009-08-06 06:41:21 +00001878 if (!getDerived().AlwaysRebuild() &&
1879 NNS == QTN->getQualifier() &&
1880 TransOvl == Ovl)
1881 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001882
Douglas Gregor71dc5092009-08-06 06:41:21 +00001883 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1884 TransOvl);
1885 }
Mike Stump11289f42009-09-09 15:08:12 +00001886
Douglas Gregor71dc5092009-08-06 06:41:21 +00001887 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001888 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001889 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1890 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001891 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001892 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001893
Douglas Gregor71dc5092009-08-06 06:41:21 +00001894 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001895 NNS == DTN->getQualifier() &&
1896 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001897 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001898
Douglas Gregor71395fa2009-11-04 00:56:37 +00001899 if (DTN->isIdentifier())
1900 return getDerived().RebuildTemplateName(NNS, *DTN->getIdentifier(),
1901 ObjectType);
1902
1903 return getDerived().RebuildTemplateName(NNS, DTN->getOperator(),
1904 ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001905 }
Mike Stump11289f42009-09-09 15:08:12 +00001906
Douglas Gregor71dc5092009-08-06 06:41:21 +00001907 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001908 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001909 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1910 if (!TransTemplate)
1911 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001912
Douglas Gregor71dc5092009-08-06 06:41:21 +00001913 if (!getDerived().AlwaysRebuild() &&
1914 TransTemplate == Template)
1915 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001916
Douglas Gregor71dc5092009-08-06 06:41:21 +00001917 return TemplateName(TransTemplate);
1918 }
Mike Stump11289f42009-09-09 15:08:12 +00001919
Douglas Gregor71dc5092009-08-06 06:41:21 +00001920 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1921 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001922 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001923 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1924 if (!TransOvl)
1925 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001926
Douglas Gregor71dc5092009-08-06 06:41:21 +00001927 if (!getDerived().AlwaysRebuild() &&
1928 TransOvl == Ovl)
1929 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001930
Douglas Gregor71dc5092009-08-06 06:41:21 +00001931 return TemplateName(TransOvl);
1932}
1933
1934template<typename Derived>
John McCall0ad16662009-10-29 08:12:44 +00001935void TreeTransform<Derived>::InventTemplateArgumentLoc(
1936 const TemplateArgument &Arg,
1937 TemplateArgumentLoc &Output) {
1938 SourceLocation Loc = getDerived().getBaseLocation();
1939 switch (Arg.getKind()) {
1940 case TemplateArgument::Null:
1941 llvm::llvm_unreachable("null template argument in TreeTransform");
1942 break;
1943
1944 case TemplateArgument::Type:
1945 Output = TemplateArgumentLoc(Arg,
1946 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1947
1948 break;
1949
1950 case TemplateArgument::Expression:
1951 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1952 break;
1953
1954 case TemplateArgument::Declaration:
1955 case TemplateArgument::Integral:
1956 case TemplateArgument::Pack:
John McCall0d07eb32009-10-29 18:45:58 +00001957 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00001958 break;
1959 }
1960}
1961
1962template<typename Derived>
1963bool TreeTransform<Derived>::TransformTemplateArgument(
1964 const TemplateArgumentLoc &Input,
1965 TemplateArgumentLoc &Output) {
1966 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregore922c772009-08-04 22:27:00 +00001967 switch (Arg.getKind()) {
1968 case TemplateArgument::Null:
1969 case TemplateArgument::Integral:
John McCall0ad16662009-10-29 08:12:44 +00001970 Output = Input;
1971 return false;
Mike Stump11289f42009-09-09 15:08:12 +00001972
Douglas Gregore922c772009-08-04 22:27:00 +00001973 case TemplateArgument::Type: {
John McCall0ad16662009-10-29 08:12:44 +00001974 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1975 if (DI == NULL)
1976 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1977
1978 DI = getDerived().TransformType(DI);
1979 if (!DI) return true;
1980
1981 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1982 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001983 }
Mike Stump11289f42009-09-09 15:08:12 +00001984
Douglas Gregore922c772009-08-04 22:27:00 +00001985 case TemplateArgument::Declaration: {
John McCall0ad16662009-10-29 08:12:44 +00001986 // FIXME: we should never have to transform one of these.
Douglas Gregoref6ab412009-10-27 06:26:26 +00001987 DeclarationName Name;
1988 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1989 Name = ND->getDeclName();
John McCall0ad16662009-10-29 08:12:44 +00001990 TemporaryBase Rebase(*this, SourceLocation(), Name);
Douglas Gregore922c772009-08-04 22:27:00 +00001991 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall0ad16662009-10-29 08:12:44 +00001992 if (!D) return true;
1993
John McCall0d07eb32009-10-29 18:45:58 +00001994 Expr *SourceExpr = Input.getSourceDeclExpression();
1995 if (SourceExpr) {
1996 EnterExpressionEvaluationContext Unevaluated(getSema(),
1997 Action::Unevaluated);
1998 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
1999 if (E.isInvalid())
2000 SourceExpr = NULL;
2001 else {
2002 SourceExpr = E.takeAs<Expr>();
2003 SourceExpr->Retain();
2004 }
2005 }
2006
2007 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall0ad16662009-10-29 08:12:44 +00002008 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002009 }
Mike Stump11289f42009-09-09 15:08:12 +00002010
Douglas Gregore922c772009-08-04 22:27:00 +00002011 case TemplateArgument::Expression: {
2012 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00002013 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00002014 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002015
John McCall0ad16662009-10-29 08:12:44 +00002016 Expr *InputExpr = Input.getSourceExpression();
2017 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
2018
2019 Sema::OwningExprResult E
2020 = getDerived().TransformExpr(InputExpr);
2021 if (E.isInvalid()) return true;
2022
2023 Expr *ETaken = E.takeAs<Expr>();
John McCall0d07eb32009-10-29 18:45:58 +00002024 ETaken->Retain();
John McCall0ad16662009-10-29 08:12:44 +00002025 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
2026 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002027 }
Mike Stump11289f42009-09-09 15:08:12 +00002028
Douglas Gregore922c772009-08-04 22:27:00 +00002029 case TemplateArgument::Pack: {
2030 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
2031 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00002032 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00002033 AEnd = Arg.pack_end();
2034 A != AEnd; ++A) {
Mike Stump11289f42009-09-09 15:08:12 +00002035
John McCall0ad16662009-10-29 08:12:44 +00002036 // FIXME: preserve source information here when we start
2037 // caring about parameter packs.
2038
John McCall0d07eb32009-10-29 18:45:58 +00002039 TemplateArgumentLoc InputArg;
2040 TemplateArgumentLoc OutputArg;
2041 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2042 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall0ad16662009-10-29 08:12:44 +00002043 return true;
2044
John McCall0d07eb32009-10-29 18:45:58 +00002045 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregore922c772009-08-04 22:27:00 +00002046 }
2047 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00002048 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00002049 true);
John McCall0d07eb32009-10-29 18:45:58 +00002050 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00002051 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002052 }
2053 }
Mike Stump11289f42009-09-09 15:08:12 +00002054
Douglas Gregore922c772009-08-04 22:27:00 +00002055 // Work around bogus GCC warning
John McCall0ad16662009-10-29 08:12:44 +00002056 return true;
Douglas Gregore922c772009-08-04 22:27:00 +00002057}
2058
Douglas Gregord6ff3322009-08-04 16:50:30 +00002059//===----------------------------------------------------------------------===//
2060// Type transformation
2061//===----------------------------------------------------------------------===//
2062
2063template<typename Derived>
2064QualType TreeTransform<Derived>::TransformType(QualType T) {
2065 if (getDerived().AlreadyTransformed(T))
2066 return T;
Mike Stump11289f42009-09-09 15:08:12 +00002067
John McCall550e0c22009-10-21 00:40:46 +00002068 // Temporary workaround. All of these transformations should
2069 // eventually turn into transformations on TypeLocs.
2070 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00002071 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00002072
2073 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00002074
John McCall550e0c22009-10-21 00:40:46 +00002075 if (!NewDI)
2076 return QualType();
2077
2078 return NewDI->getType();
2079}
2080
2081template<typename Derived>
2082DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2083 if (getDerived().AlreadyTransformed(DI->getType()))
2084 return DI;
2085
2086 TypeLocBuilder TLB;
2087
2088 TypeLoc TL = DI->getTypeLoc();
2089 TLB.reserve(TL.getFullDataSize());
2090
2091 QualType Result = getDerived().TransformType(TLB, TL);
2092 if (Result.isNull())
2093 return 0;
2094
2095 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2096}
2097
2098template<typename Derived>
2099QualType
2100TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2101 switch (T.getTypeLocClass()) {
2102#define ABSTRACT_TYPELOC(CLASS, PARENT)
2103#define TYPELOC(CLASS, PARENT) \
2104 case TypeLoc::CLASS: \
2105 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2106#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00002107 }
Mike Stump11289f42009-09-09 15:08:12 +00002108
John McCall550e0c22009-10-21 00:40:46 +00002109 llvm::llvm_unreachable("unhandled type loc!");
2110 return QualType();
2111}
2112
2113/// FIXME: By default, this routine adds type qualifiers only to types
2114/// that can have qualifiers, and silently suppresses those qualifiers
2115/// that are not permitted (e.g., qualifiers on reference or function
2116/// types). This is the right thing for template instantiation, but
2117/// probably not for other clients.
2118template<typename Derived>
2119QualType
2120TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2121 QualifiedTypeLoc T) {
2122 Qualifiers Quals = T.getType().getQualifiers();
2123
2124 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2125 if (Result.isNull())
2126 return QualType();
2127
2128 // Silently suppress qualifiers if the result type can't be qualified.
2129 // FIXME: this is the right thing for template instantiation, but
2130 // probably not for other clients.
2131 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002132 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002133
John McCall550e0c22009-10-21 00:40:46 +00002134 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2135
2136 TLB.push<QualifiedTypeLoc>(Result);
2137
2138 // No location information to preserve.
2139
2140 return Result;
2141}
2142
2143template <class TyLoc> static inline
2144QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2145 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2146 NewT.setNameLoc(T.getNameLoc());
2147 return T.getType();
2148}
2149
2150// Ugly metaprogramming macros because I couldn't be bothered to make
2151// the equivalent template version work.
2152#define TransformPointerLikeType(TypeClass) do { \
2153 QualType PointeeType \
2154 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2155 if (PointeeType.isNull()) \
2156 return QualType(); \
2157 \
2158 QualType Result = TL.getType(); \
2159 if (getDerived().AlwaysRebuild() || \
2160 PointeeType != TL.getPointeeLoc().getType()) { \
John McCall70dd5f62009-10-30 00:06:24 +00002161 Result = getDerived().Rebuild##TypeClass(PointeeType, \
2162 TL.getSigilLoc()); \
John McCall550e0c22009-10-21 00:40:46 +00002163 if (Result.isNull()) \
2164 return QualType(); \
2165 } \
2166 \
2167 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2168 NewT.setSigilLoc(TL.getSigilLoc()); \
2169 \
2170 return Result; \
2171} while(0)
2172
John McCall550e0c22009-10-21 00:40:46 +00002173template<typename Derived>
2174QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2175 BuiltinTypeLoc T) {
2176 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002177}
Mike Stump11289f42009-09-09 15:08:12 +00002178
Douglas Gregord6ff3322009-08-04 16:50:30 +00002179template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002180QualType
John McCall550e0c22009-10-21 00:40:46 +00002181TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2182 FixedWidthIntTypeLoc T) {
2183 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002184}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002185
Douglas Gregord6ff3322009-08-04 16:50:30 +00002186template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002187QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2188 ComplexTypeLoc T) {
2189 // FIXME: recurse?
2190 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002191}
Mike Stump11289f42009-09-09 15:08:12 +00002192
Douglas Gregord6ff3322009-08-04 16:50:30 +00002193template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002194QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2195 PointerTypeLoc TL) {
2196 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002197}
Mike Stump11289f42009-09-09 15:08:12 +00002198
2199template<typename Derived>
2200QualType
John McCall550e0c22009-10-21 00:40:46 +00002201TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2202 BlockPointerTypeLoc TL) {
2203 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002204}
2205
John McCall70dd5f62009-10-30 00:06:24 +00002206/// Transforms a reference type. Note that somewhat paradoxically we
2207/// don't care whether the type itself is an l-value type or an r-value
2208/// type; we only care if the type was *written* as an l-value type
2209/// or an r-value type.
2210template<typename Derived>
2211QualType
2212TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
2213 ReferenceTypeLoc TL) {
2214 const ReferenceType *T = TL.getTypePtr();
2215
2216 // Note that this works with the pointee-as-written.
2217 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
2218 if (PointeeType.isNull())
2219 return QualType();
2220
2221 QualType Result = TL.getType();
2222 if (getDerived().AlwaysRebuild() ||
2223 PointeeType != T->getPointeeTypeAsWritten()) {
2224 Result = getDerived().RebuildReferenceType(PointeeType,
2225 T->isSpelledAsLValue(),
2226 TL.getSigilLoc());
2227 if (Result.isNull())
2228 return QualType();
2229 }
2230
2231 // r-value references can be rebuilt as l-value references.
2232 ReferenceTypeLoc NewTL;
2233 if (isa<LValueReferenceType>(Result))
2234 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
2235 else
2236 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
2237 NewTL.setSigilLoc(TL.getSigilLoc());
2238
2239 return Result;
2240}
2241
Mike Stump11289f42009-09-09 15:08:12 +00002242template<typename Derived>
2243QualType
John McCall550e0c22009-10-21 00:40:46 +00002244TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2245 LValueReferenceTypeLoc TL) {
John McCall70dd5f62009-10-30 00:06:24 +00002246 return TransformReferenceType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002247}
2248
Mike Stump11289f42009-09-09 15:08:12 +00002249template<typename Derived>
2250QualType
John McCall550e0c22009-10-21 00:40:46 +00002251TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2252 RValueReferenceTypeLoc TL) {
John McCall70dd5f62009-10-30 00:06:24 +00002253 return TransformReferenceType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002254}
Mike Stump11289f42009-09-09 15:08:12 +00002255
Douglas Gregord6ff3322009-08-04 16:50:30 +00002256template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002257QualType
John McCall550e0c22009-10-21 00:40:46 +00002258TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2259 MemberPointerTypeLoc TL) {
2260 MemberPointerType *T = TL.getTypePtr();
2261
2262 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002263 if (PointeeType.isNull())
2264 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002265
John McCall550e0c22009-10-21 00:40:46 +00002266 // TODO: preserve source information for this.
2267 QualType ClassType
2268 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002269 if (ClassType.isNull())
2270 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002271
John McCall550e0c22009-10-21 00:40:46 +00002272 QualType Result = TL.getType();
2273 if (getDerived().AlwaysRebuild() ||
2274 PointeeType != T->getPointeeType() ||
2275 ClassType != QualType(T->getClass(), 0)) {
John McCall70dd5f62009-10-30 00:06:24 +00002276 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
2277 TL.getStarLoc());
John McCall550e0c22009-10-21 00:40:46 +00002278 if (Result.isNull())
2279 return QualType();
2280 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002281
John McCall550e0c22009-10-21 00:40:46 +00002282 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2283 NewTL.setSigilLoc(TL.getSigilLoc());
2284
2285 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002286}
2287
Mike Stump11289f42009-09-09 15:08:12 +00002288template<typename Derived>
2289QualType
John McCall550e0c22009-10-21 00:40:46 +00002290TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2291 ConstantArrayTypeLoc TL) {
2292 ConstantArrayType *T = TL.getTypePtr();
2293 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002294 if (ElementType.isNull())
2295 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002296
John McCall550e0c22009-10-21 00:40:46 +00002297 QualType Result = TL.getType();
2298 if (getDerived().AlwaysRebuild() ||
2299 ElementType != T->getElementType()) {
2300 Result = getDerived().RebuildConstantArrayType(ElementType,
2301 T->getSizeModifier(),
2302 T->getSize(),
John McCall70dd5f62009-10-30 00:06:24 +00002303 T->getIndexTypeCVRQualifiers(),
2304 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002305 if (Result.isNull())
2306 return QualType();
2307 }
2308
2309 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2310 NewTL.setLBracketLoc(TL.getLBracketLoc());
2311 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002312
John McCall550e0c22009-10-21 00:40:46 +00002313 Expr *Size = TL.getSizeExpr();
2314 if (Size) {
2315 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2316 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2317 }
2318 NewTL.setSizeExpr(Size);
2319
2320 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002321}
Mike Stump11289f42009-09-09 15:08:12 +00002322
Douglas Gregord6ff3322009-08-04 16:50:30 +00002323template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002324QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002325 TypeLocBuilder &TLB,
2326 IncompleteArrayTypeLoc TL) {
2327 IncompleteArrayType *T = TL.getTypePtr();
2328 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002329 if (ElementType.isNull())
2330 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002331
John McCall550e0c22009-10-21 00:40:46 +00002332 QualType Result = TL.getType();
2333 if (getDerived().AlwaysRebuild() ||
2334 ElementType != T->getElementType()) {
2335 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002336 T->getSizeModifier(),
John McCall70dd5f62009-10-30 00:06:24 +00002337 T->getIndexTypeCVRQualifiers(),
2338 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002339 if (Result.isNull())
2340 return QualType();
2341 }
2342
2343 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2344 NewTL.setLBracketLoc(TL.getLBracketLoc());
2345 NewTL.setRBracketLoc(TL.getRBracketLoc());
2346 NewTL.setSizeExpr(0);
2347
2348 return Result;
2349}
2350
2351template<typename Derived>
2352QualType
2353TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2354 VariableArrayTypeLoc TL) {
2355 VariableArrayType *T = TL.getTypePtr();
2356 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2357 if (ElementType.isNull())
2358 return QualType();
2359
2360 // Array bounds are not potentially evaluated contexts
2361 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2362
2363 Sema::OwningExprResult SizeResult
2364 = getDerived().TransformExpr(T->getSizeExpr());
2365 if (SizeResult.isInvalid())
2366 return QualType();
2367
2368 Expr *Size = static_cast<Expr*>(SizeResult.get());
2369
2370 QualType Result = TL.getType();
2371 if (getDerived().AlwaysRebuild() ||
2372 ElementType != T->getElementType() ||
2373 Size != T->getSizeExpr()) {
2374 Result = getDerived().RebuildVariableArrayType(ElementType,
2375 T->getSizeModifier(),
2376 move(SizeResult),
2377 T->getIndexTypeCVRQualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00002378 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002379 if (Result.isNull())
2380 return QualType();
2381 }
2382 else SizeResult.take();
2383
2384 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2385 NewTL.setLBracketLoc(TL.getLBracketLoc());
2386 NewTL.setRBracketLoc(TL.getRBracketLoc());
2387 NewTL.setSizeExpr(Size);
2388
2389 return Result;
2390}
2391
2392template<typename Derived>
2393QualType
2394TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2395 DependentSizedArrayTypeLoc TL) {
2396 DependentSizedArrayType *T = TL.getTypePtr();
2397 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2398 if (ElementType.isNull())
2399 return QualType();
2400
2401 // Array bounds are not potentially evaluated contexts
2402 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2403
2404 Sema::OwningExprResult SizeResult
2405 = getDerived().TransformExpr(T->getSizeExpr());
2406 if (SizeResult.isInvalid())
2407 return QualType();
2408
2409 Expr *Size = static_cast<Expr*>(SizeResult.get());
2410
2411 QualType Result = TL.getType();
2412 if (getDerived().AlwaysRebuild() ||
2413 ElementType != T->getElementType() ||
2414 Size != T->getSizeExpr()) {
2415 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2416 T->getSizeModifier(),
2417 move(SizeResult),
2418 T->getIndexTypeCVRQualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00002419 TL.getBracketsRange());
John McCall550e0c22009-10-21 00:40:46 +00002420 if (Result.isNull())
2421 return QualType();
2422 }
2423 else SizeResult.take();
2424
2425 // We might have any sort of array type now, but fortunately they
2426 // all have the same location layout.
2427 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2428 NewTL.setLBracketLoc(TL.getLBracketLoc());
2429 NewTL.setRBracketLoc(TL.getRBracketLoc());
2430 NewTL.setSizeExpr(Size);
2431
2432 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002433}
Mike Stump11289f42009-09-09 15:08:12 +00002434
2435template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002436QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002437 TypeLocBuilder &TLB,
2438 DependentSizedExtVectorTypeLoc TL) {
2439 DependentSizedExtVectorType *T = TL.getTypePtr();
2440
2441 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002442 QualType ElementType = getDerived().TransformType(T->getElementType());
2443 if (ElementType.isNull())
2444 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002445
Douglas Gregore922c772009-08-04 22:27:00 +00002446 // Vector sizes are not potentially evaluated contexts
2447 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2448
Douglas Gregord6ff3322009-08-04 16:50:30 +00002449 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2450 if (Size.isInvalid())
2451 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002452
John McCall550e0c22009-10-21 00:40:46 +00002453 QualType Result = TL.getType();
2454 if (getDerived().AlwaysRebuild() ||
John McCall24e7cb62009-10-23 17:55:45 +00002455 ElementType != T->getElementType() ||
2456 Size.get() != T->getSizeExpr()) {
John McCall550e0c22009-10-21 00:40:46 +00002457 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002458 move(Size),
2459 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002460 if (Result.isNull())
2461 return QualType();
2462 }
2463 else Size.take();
2464
2465 // Result might be dependent or not.
2466 if (isa<DependentSizedExtVectorType>(Result)) {
2467 DependentSizedExtVectorTypeLoc NewTL
2468 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2469 NewTL.setNameLoc(TL.getNameLoc());
2470 } else {
2471 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2472 NewTL.setNameLoc(TL.getNameLoc());
2473 }
2474
2475 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002476}
Mike Stump11289f42009-09-09 15:08:12 +00002477
2478template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002479QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2480 VectorTypeLoc TL) {
2481 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002482 QualType ElementType = getDerived().TransformType(T->getElementType());
2483 if (ElementType.isNull())
2484 return QualType();
2485
John McCall550e0c22009-10-21 00:40:46 +00002486 QualType Result = TL.getType();
2487 if (getDerived().AlwaysRebuild() ||
2488 ElementType != T->getElementType()) {
2489 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2490 if (Result.isNull())
2491 return QualType();
2492 }
2493
2494 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2495 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002496
John McCall550e0c22009-10-21 00:40:46 +00002497 return Result;
2498}
2499
2500template<typename Derived>
2501QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2502 ExtVectorTypeLoc TL) {
2503 VectorType *T = TL.getTypePtr();
2504 QualType ElementType = getDerived().TransformType(T->getElementType());
2505 if (ElementType.isNull())
2506 return QualType();
2507
2508 QualType Result = TL.getType();
2509 if (getDerived().AlwaysRebuild() ||
2510 ElementType != T->getElementType()) {
2511 Result = getDerived().RebuildExtVectorType(ElementType,
2512 T->getNumElements(),
2513 /*FIXME*/ SourceLocation());
2514 if (Result.isNull())
2515 return QualType();
2516 }
2517
2518 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2519 NewTL.setNameLoc(TL.getNameLoc());
2520
2521 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002522}
Mike Stump11289f42009-09-09 15:08:12 +00002523
2524template<typename Derived>
2525QualType
John McCall550e0c22009-10-21 00:40:46 +00002526TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2527 FunctionProtoTypeLoc TL) {
2528 FunctionProtoType *T = TL.getTypePtr();
2529 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002530 if (ResultType.isNull())
2531 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002532
John McCall550e0c22009-10-21 00:40:46 +00002533 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002534 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002535 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2536 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2537 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002538
John McCall550e0c22009-10-21 00:40:46 +00002539 QualType NewType;
2540 ParmVarDecl *NewParm;
2541
2542 if (OldParm) {
2543 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2544 assert(OldDI->getType() == T->getArgType(i));
2545
2546 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2547 if (!NewDI)
2548 return QualType();
2549
2550 if (NewDI == OldDI)
2551 NewParm = OldParm;
2552 else
2553 NewParm = ParmVarDecl::Create(SemaRef.Context,
2554 OldParm->getDeclContext(),
2555 OldParm->getLocation(),
2556 OldParm->getIdentifier(),
2557 NewDI->getType(),
2558 NewDI,
2559 OldParm->getStorageClass(),
2560 /* DefArg */ NULL);
2561 NewType = NewParm->getType();
2562
2563 // Deal with the possibility that we don't have a parameter
2564 // declaration for this parameter.
2565 } else {
2566 NewParm = 0;
2567
2568 QualType OldType = T->getArgType(i);
2569 NewType = getDerived().TransformType(OldType);
2570 if (NewType.isNull())
2571 return QualType();
2572 }
2573
2574 ParamTypes.push_back(NewType);
2575 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002576 }
Mike Stump11289f42009-09-09 15:08:12 +00002577
John McCall550e0c22009-10-21 00:40:46 +00002578 QualType Result = TL.getType();
2579 if (getDerived().AlwaysRebuild() ||
2580 ResultType != T->getResultType() ||
2581 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2582 Result = getDerived().RebuildFunctionProtoType(ResultType,
2583 ParamTypes.data(),
2584 ParamTypes.size(),
2585 T->isVariadic(),
2586 T->getTypeQuals());
2587 if (Result.isNull())
2588 return QualType();
2589 }
Mike Stump11289f42009-09-09 15:08:12 +00002590
John McCall550e0c22009-10-21 00:40:46 +00002591 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2592 NewTL.setLParenLoc(TL.getLParenLoc());
2593 NewTL.setRParenLoc(TL.getRParenLoc());
2594 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2595 NewTL.setArg(i, ParamDecls[i]);
2596
2597 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002598}
Mike Stump11289f42009-09-09 15:08:12 +00002599
Douglas Gregord6ff3322009-08-04 16:50:30 +00002600template<typename Derived>
2601QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002602 TypeLocBuilder &TLB,
2603 FunctionNoProtoTypeLoc TL) {
2604 FunctionNoProtoType *T = TL.getTypePtr();
2605 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2606 if (ResultType.isNull())
2607 return QualType();
2608
2609 QualType Result = TL.getType();
2610 if (getDerived().AlwaysRebuild() ||
2611 ResultType != T->getResultType())
2612 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2613
2614 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2615 NewTL.setLParenLoc(TL.getLParenLoc());
2616 NewTL.setRParenLoc(TL.getRParenLoc());
2617
2618 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002619}
Mike Stump11289f42009-09-09 15:08:12 +00002620
Douglas Gregord6ff3322009-08-04 16:50:30 +00002621template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002622QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2623 TypedefTypeLoc TL) {
2624 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002625 TypedefDecl *Typedef
2626 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2627 if (!Typedef)
2628 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002629
John McCall550e0c22009-10-21 00:40:46 +00002630 QualType Result = TL.getType();
2631 if (getDerived().AlwaysRebuild() ||
2632 Typedef != T->getDecl()) {
2633 Result = getDerived().RebuildTypedefType(Typedef);
2634 if (Result.isNull())
2635 return QualType();
2636 }
Mike Stump11289f42009-09-09 15:08:12 +00002637
John McCall550e0c22009-10-21 00:40:46 +00002638 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2639 NewTL.setNameLoc(TL.getNameLoc());
2640
2641 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002642}
Mike Stump11289f42009-09-09 15:08:12 +00002643
Douglas Gregord6ff3322009-08-04 16:50:30 +00002644template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002645QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2646 TypeOfExprTypeLoc TL) {
2647 TypeOfExprType *T = TL.getTypePtr();
2648
Douglas Gregore922c772009-08-04 22:27:00 +00002649 // typeof expressions are not potentially evaluated contexts
2650 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002651
Douglas Gregord6ff3322009-08-04 16:50:30 +00002652 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2653 if (E.isInvalid())
2654 return QualType();
2655
John McCall550e0c22009-10-21 00:40:46 +00002656 QualType Result = TL.getType();
2657 if (getDerived().AlwaysRebuild() ||
2658 E.get() != T->getUnderlyingExpr()) {
2659 Result = getDerived().RebuildTypeOfExprType(move(E));
2660 if (Result.isNull())
2661 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002662 }
John McCall550e0c22009-10-21 00:40:46 +00002663 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002664
John McCall550e0c22009-10-21 00:40:46 +00002665 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2666 NewTL.setNameLoc(TL.getNameLoc());
2667
2668 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002669}
Mike Stump11289f42009-09-09 15:08:12 +00002670
2671template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002672QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2673 TypeOfTypeLoc TL) {
2674 TypeOfType *T = TL.getTypePtr();
2675
2676 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002677 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2678 if (Underlying.isNull())
2679 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002680
John McCall550e0c22009-10-21 00:40:46 +00002681 QualType Result = TL.getType();
2682 if (getDerived().AlwaysRebuild() ||
2683 Underlying != T->getUnderlyingType()) {
2684 Result = getDerived().RebuildTypeOfType(Underlying);
2685 if (Result.isNull())
2686 return QualType();
2687 }
Mike Stump11289f42009-09-09 15:08:12 +00002688
John McCall550e0c22009-10-21 00:40:46 +00002689 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2690 NewTL.setNameLoc(TL.getNameLoc());
2691
2692 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002693}
Mike Stump11289f42009-09-09 15:08:12 +00002694
2695template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002696QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2697 DecltypeTypeLoc TL) {
2698 DecltypeType *T = TL.getTypePtr();
2699
Douglas Gregore922c772009-08-04 22:27:00 +00002700 // decltype expressions are not potentially evaluated contexts
2701 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002702
Douglas Gregord6ff3322009-08-04 16:50:30 +00002703 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2704 if (E.isInvalid())
2705 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002706
John McCall550e0c22009-10-21 00:40:46 +00002707 QualType Result = TL.getType();
2708 if (getDerived().AlwaysRebuild() ||
2709 E.get() != T->getUnderlyingExpr()) {
2710 Result = getDerived().RebuildDecltypeType(move(E));
2711 if (Result.isNull())
2712 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002713 }
John McCall550e0c22009-10-21 00:40:46 +00002714 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002715
John McCall550e0c22009-10-21 00:40:46 +00002716 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2717 NewTL.setNameLoc(TL.getNameLoc());
2718
2719 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002720}
2721
2722template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002723QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2724 RecordTypeLoc TL) {
2725 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002726 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002727 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002728 if (!Record)
2729 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002730
John McCall550e0c22009-10-21 00:40:46 +00002731 QualType Result = TL.getType();
2732 if (getDerived().AlwaysRebuild() ||
2733 Record != T->getDecl()) {
2734 Result = getDerived().RebuildRecordType(Record);
2735 if (Result.isNull())
2736 return QualType();
2737 }
Mike Stump11289f42009-09-09 15:08:12 +00002738
John McCall550e0c22009-10-21 00:40:46 +00002739 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2740 NewTL.setNameLoc(TL.getNameLoc());
2741
2742 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002743}
Mike Stump11289f42009-09-09 15:08:12 +00002744
2745template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002746QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2747 EnumTypeLoc TL) {
2748 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002749 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002750 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002751 if (!Enum)
2752 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002753
John McCall550e0c22009-10-21 00:40:46 +00002754 QualType Result = TL.getType();
2755 if (getDerived().AlwaysRebuild() ||
2756 Enum != T->getDecl()) {
2757 Result = getDerived().RebuildEnumType(Enum);
2758 if (Result.isNull())
2759 return QualType();
2760 }
Mike Stump11289f42009-09-09 15:08:12 +00002761
John McCall550e0c22009-10-21 00:40:46 +00002762 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2763 NewTL.setNameLoc(TL.getNameLoc());
2764
2765 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002766}
John McCallfcc33b02009-09-05 00:15:47 +00002767
2768template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002769QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2770 ElaboratedTypeLoc TL) {
2771 ElaboratedType *T = TL.getTypePtr();
2772
2773 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002774 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2775 if (Underlying.isNull())
2776 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002777
John McCall550e0c22009-10-21 00:40:46 +00002778 QualType Result = TL.getType();
2779 if (getDerived().AlwaysRebuild() ||
2780 Underlying != T->getUnderlyingType()) {
2781 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2782 if (Result.isNull())
2783 return QualType();
2784 }
Mike Stump11289f42009-09-09 15:08:12 +00002785
John McCall550e0c22009-10-21 00:40:46 +00002786 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2787 NewTL.setNameLoc(TL.getNameLoc());
2788
2789 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002790}
Mike Stump11289f42009-09-09 15:08:12 +00002791
2792
Douglas Gregord6ff3322009-08-04 16:50:30 +00002793template<typename Derived>
2794QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002795 TypeLocBuilder &TLB,
2796 TemplateTypeParmTypeLoc TL) {
2797 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002798}
2799
Mike Stump11289f42009-09-09 15:08:12 +00002800template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002801QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002802 TypeLocBuilder &TLB,
2803 SubstTemplateTypeParmTypeLoc TL) {
2804 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002805}
2806
2807template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002808inline QualType
2809TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002810 TypeLocBuilder &TLB,
2811 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002812 return TransformTemplateSpecializationType(TLB, TL, QualType());
2813}
John McCall550e0c22009-10-21 00:40:46 +00002814
John McCall0ad16662009-10-29 08:12:44 +00002815template<typename Derived>
2816QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2817 const TemplateSpecializationType *TST,
2818 QualType ObjectType) {
2819 // FIXME: this entire method is a temporary workaround; callers
2820 // should be rewritten to provide real type locs.
John McCall550e0c22009-10-21 00:40:46 +00002821
John McCall0ad16662009-10-29 08:12:44 +00002822 // Fake up a TemplateSpecializationTypeLoc.
2823 TypeLocBuilder TLB;
2824 TemplateSpecializationTypeLoc TL
2825 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2826
John McCall0d07eb32009-10-29 18:45:58 +00002827 SourceLocation BaseLoc = getDerived().getBaseLocation();
2828
2829 TL.setTemplateNameLoc(BaseLoc);
2830 TL.setLAngleLoc(BaseLoc);
2831 TL.setRAngleLoc(BaseLoc);
John McCall0ad16662009-10-29 08:12:44 +00002832 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2833 const TemplateArgument &TA = TST->getArg(i);
2834 TemplateArgumentLoc TAL;
2835 getDerived().InventTemplateArgumentLoc(TA, TAL);
2836 TL.setArgLocInfo(i, TAL.getLocInfo());
2837 }
2838
2839 TypeLocBuilder IgnoredTLB;
2840 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +00002841}
2842
2843template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002844QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00002845 TypeLocBuilder &TLB,
2846 TemplateSpecializationTypeLoc TL,
2847 QualType ObjectType) {
2848 const TemplateSpecializationType *T = TL.getTypePtr();
2849
Mike Stump11289f42009-09-09 15:08:12 +00002850 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002851 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002852 if (Template.isNull())
2853 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002854
John McCall0ad16662009-10-29 08:12:44 +00002855 llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
2856 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
2857 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
2858 NewTemplateArgs[i]))
Douglas Gregord6ff3322009-08-04 16:50:30 +00002859 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002860
John McCall0ad16662009-10-29 08:12:44 +00002861 // FIXME: maybe don't rebuild if all the template arguments are the same.
2862
2863 QualType Result =
2864 getDerived().RebuildTemplateSpecializationType(Template,
2865 TL.getTemplateNameLoc(),
2866 TL.getLAngleLoc(),
2867 NewTemplateArgs.data(),
2868 NewTemplateArgs.size(),
2869 TL.getRAngleLoc());
2870
2871 if (!Result.isNull()) {
2872 TemplateSpecializationTypeLoc NewTL
2873 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2874 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2875 NewTL.setLAngleLoc(TL.getLAngleLoc());
2876 NewTL.setRAngleLoc(TL.getRAngleLoc());
2877 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2878 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002879 }
Mike Stump11289f42009-09-09 15:08:12 +00002880
John McCall0ad16662009-10-29 08:12:44 +00002881 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002882}
Mike Stump11289f42009-09-09 15:08:12 +00002883
2884template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002885QualType
2886TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2887 QualifiedNameTypeLoc TL) {
2888 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002889 NestedNameSpecifier *NNS
2890 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2891 SourceRange());
2892 if (!NNS)
2893 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002894
Douglas Gregord6ff3322009-08-04 16:50:30 +00002895 QualType Named = getDerived().TransformType(T->getNamedType());
2896 if (Named.isNull())
2897 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002898
John McCall550e0c22009-10-21 00:40:46 +00002899 QualType Result = TL.getType();
2900 if (getDerived().AlwaysRebuild() ||
2901 NNS != T->getQualifier() ||
2902 Named != T->getNamedType()) {
2903 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2904 if (Result.isNull())
2905 return QualType();
2906 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002907
John McCall550e0c22009-10-21 00:40:46 +00002908 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2909 NewTL.setNameLoc(TL.getNameLoc());
2910
2911 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002912}
Mike Stump11289f42009-09-09 15:08:12 +00002913
2914template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002915QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2916 TypenameTypeLoc TL) {
2917 TypenameType *T = TL.getTypePtr();
John McCall0ad16662009-10-29 08:12:44 +00002918
2919 /* FIXME: preserve source information better than this */
2920 SourceRange SR(TL.getNameLoc());
2921
Douglas Gregord6ff3322009-08-04 16:50:30 +00002922 NestedNameSpecifier *NNS
John McCall0ad16662009-10-29 08:12:44 +00002923 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002924 if (!NNS)
2925 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002926
John McCall550e0c22009-10-21 00:40:46 +00002927 QualType Result;
2928
Douglas Gregord6ff3322009-08-04 16:50:30 +00002929 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002930 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002931 = getDerived().TransformType(QualType(TemplateId, 0));
2932 if (NewTemplateId.isNull())
2933 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002934
Douglas Gregord6ff3322009-08-04 16:50:30 +00002935 if (!getDerived().AlwaysRebuild() &&
2936 NNS == T->getQualifier() &&
2937 NewTemplateId == QualType(TemplateId, 0))
2938 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002939
John McCall550e0c22009-10-21 00:40:46 +00002940 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2941 } else {
John McCall0ad16662009-10-29 08:12:44 +00002942 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002943 }
John McCall550e0c22009-10-21 00:40:46 +00002944 if (Result.isNull())
2945 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002946
John McCall550e0c22009-10-21 00:40:46 +00002947 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2948 NewTL.setNameLoc(TL.getNameLoc());
2949
2950 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002951}
Mike Stump11289f42009-09-09 15:08:12 +00002952
Douglas Gregord6ff3322009-08-04 16:50:30 +00002953template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002954QualType
2955TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2956 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002957 assert(false && "TransformObjCInterfaceType unimplemented");
2958 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002959}
Mike Stump11289f42009-09-09 15:08:12 +00002960
2961template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002962QualType
2963TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2964 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002965 assert(false && "TransformObjCObjectPointerType unimplemented");
2966 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002967}
2968
Douglas Gregord6ff3322009-08-04 16:50:30 +00002969//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002970// Statement transformation
2971//===----------------------------------------------------------------------===//
2972template<typename Derived>
2973Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002974TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2975 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002976}
2977
2978template<typename Derived>
2979Sema::OwningStmtResult
2980TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2981 return getDerived().TransformCompoundStmt(S, false);
2982}
2983
2984template<typename Derived>
2985Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002986TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002987 bool IsStmtExpr) {
2988 bool SubStmtChanged = false;
2989 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2990 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2991 B != BEnd; ++B) {
2992 OwningStmtResult Result = getDerived().TransformStmt(*B);
2993 if (Result.isInvalid())
2994 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002995
Douglas Gregorebe10102009-08-20 07:17:43 +00002996 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2997 Statements.push_back(Result.takeAs<Stmt>());
2998 }
Mike Stump11289f42009-09-09 15:08:12 +00002999
Douglas Gregorebe10102009-08-20 07:17:43 +00003000 if (!getDerived().AlwaysRebuild() &&
3001 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003002 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003003
3004 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
3005 move_arg(Statements),
3006 S->getRBracLoc(),
3007 IsStmtExpr);
3008}
Mike Stump11289f42009-09-09 15:08:12 +00003009
Douglas Gregorebe10102009-08-20 07:17:43 +00003010template<typename Derived>
3011Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003012TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003013 // The case value expressions are not potentially evaluated.
3014 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003015
Douglas Gregorebe10102009-08-20 07:17:43 +00003016 // Transform the left-hand case value.
3017 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
3018 if (LHS.isInvalid())
3019 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003020
Douglas Gregorebe10102009-08-20 07:17:43 +00003021 // Transform the right-hand case value (for the GNU case-range extension).
3022 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
3023 if (RHS.isInvalid())
3024 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003025
Douglas Gregorebe10102009-08-20 07:17:43 +00003026 // Build the case statement.
3027 // Case statements are always rebuilt so that they will attached to their
3028 // transformed switch statement.
3029 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
3030 move(LHS),
3031 S->getEllipsisLoc(),
3032 move(RHS),
3033 S->getColonLoc());
3034 if (Case.isInvalid())
3035 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003036
Douglas Gregorebe10102009-08-20 07:17:43 +00003037 // Transform the statement following the case
3038 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3039 if (SubStmt.isInvalid())
3040 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003041
Douglas Gregorebe10102009-08-20 07:17:43 +00003042 // Attach the body to the case statement
3043 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
3044}
3045
3046template<typename Derived>
3047Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003048TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003049 // Transform the statement following the default case
3050 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3051 if (SubStmt.isInvalid())
3052 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003053
Douglas Gregorebe10102009-08-20 07:17:43 +00003054 // Default statements are always rebuilt
3055 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3056 move(SubStmt));
3057}
Mike Stump11289f42009-09-09 15:08:12 +00003058
Douglas Gregorebe10102009-08-20 07:17:43 +00003059template<typename Derived>
3060Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003061TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003062 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3063 if (SubStmt.isInvalid())
3064 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003065
Douglas Gregorebe10102009-08-20 07:17:43 +00003066 // FIXME: Pass the real colon location in.
3067 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3068 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3069 move(SubStmt));
3070}
Mike Stump11289f42009-09-09 15:08:12 +00003071
Douglas Gregorebe10102009-08-20 07:17:43 +00003072template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003073Sema::OwningStmtResult
3074TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003075 // Transform the condition
3076 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3077 if (Cond.isInvalid())
3078 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003079
Douglas Gregorebe10102009-08-20 07:17:43 +00003080 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003081
Douglas Gregorebe10102009-08-20 07:17:43 +00003082 // Transform the "then" branch.
3083 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3084 if (Then.isInvalid())
3085 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003086
Douglas Gregorebe10102009-08-20 07:17:43 +00003087 // Transform the "else" branch.
3088 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3089 if (Else.isInvalid())
3090 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003091
Douglas Gregorebe10102009-08-20 07:17:43 +00003092 if (!getDerived().AlwaysRebuild() &&
3093 FullCond->get() == S->getCond() &&
3094 Then.get() == S->getThen() &&
3095 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00003096 return SemaRef.Owned(S->Retain());
3097
Douglas Gregorebe10102009-08-20 07:17:43 +00003098 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00003099 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00003100}
3101
3102template<typename Derived>
3103Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003104TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003105 // Transform the condition.
3106 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3107 if (Cond.isInvalid())
3108 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003109
Douglas Gregorebe10102009-08-20 07:17:43 +00003110 // Rebuild the switch statement.
3111 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3112 if (Switch.isInvalid())
3113 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003114
Douglas Gregorebe10102009-08-20 07:17:43 +00003115 // Transform the body of the switch statement.
3116 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3117 if (Body.isInvalid())
3118 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003119
Douglas Gregorebe10102009-08-20 07:17:43 +00003120 // Complete the switch statement.
3121 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3122 move(Body));
3123}
Mike Stump11289f42009-09-09 15:08:12 +00003124
Douglas Gregorebe10102009-08-20 07:17:43 +00003125template<typename Derived>
3126Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003127TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003128 // Transform the condition
3129 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3130 if (Cond.isInvalid())
3131 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003132
Douglas Gregorebe10102009-08-20 07:17:43 +00003133 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003134
Douglas Gregorebe10102009-08-20 07:17:43 +00003135 // Transform the body
3136 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3137 if (Body.isInvalid())
3138 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003139
Douglas Gregorebe10102009-08-20 07:17:43 +00003140 if (!getDerived().AlwaysRebuild() &&
3141 FullCond->get() == S->getCond() &&
3142 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003143 return SemaRef.Owned(S->Retain());
3144
Douglas Gregorebe10102009-08-20 07:17:43 +00003145 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3146}
Mike Stump11289f42009-09-09 15:08:12 +00003147
Douglas Gregorebe10102009-08-20 07:17:43 +00003148template<typename Derived>
3149Sema::OwningStmtResult
3150TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3151 // Transform the condition
3152 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3153 if (Cond.isInvalid())
3154 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003155
Douglas Gregorebe10102009-08-20 07:17:43 +00003156 // Transform the body
3157 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3158 if (Body.isInvalid())
3159 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003160
Douglas Gregorebe10102009-08-20 07:17:43 +00003161 if (!getDerived().AlwaysRebuild() &&
3162 Cond.get() == S->getCond() &&
3163 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003164 return SemaRef.Owned(S->Retain());
3165
Douglas Gregorebe10102009-08-20 07:17:43 +00003166 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3167 /*FIXME:*/S->getWhileLoc(), move(Cond),
3168 S->getRParenLoc());
3169}
Mike Stump11289f42009-09-09 15:08:12 +00003170
Douglas Gregorebe10102009-08-20 07:17:43 +00003171template<typename Derived>
3172Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003173TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003174 // Transform the initialization statement
3175 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3176 if (Init.isInvalid())
3177 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003178
Douglas Gregorebe10102009-08-20 07:17:43 +00003179 // Transform the condition
3180 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3181 if (Cond.isInvalid())
3182 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003183
Douglas Gregorebe10102009-08-20 07:17:43 +00003184 // Transform the increment
3185 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3186 if (Inc.isInvalid())
3187 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003188
Douglas Gregorebe10102009-08-20 07:17:43 +00003189 // Transform the body
3190 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3191 if (Body.isInvalid())
3192 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003193
Douglas Gregorebe10102009-08-20 07:17:43 +00003194 if (!getDerived().AlwaysRebuild() &&
3195 Init.get() == S->getInit() &&
3196 Cond.get() == S->getCond() &&
3197 Inc.get() == S->getInc() &&
3198 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003199 return SemaRef.Owned(S->Retain());
3200
Douglas Gregorebe10102009-08-20 07:17:43 +00003201 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3202 move(Init), move(Cond), move(Inc),
3203 S->getRParenLoc(), move(Body));
3204}
3205
3206template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003207Sema::OwningStmtResult
3208TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003209 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003210 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003211 S->getLabel());
3212}
3213
3214template<typename Derived>
3215Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003216TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003217 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3218 if (Target.isInvalid())
3219 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003220
Douglas Gregorebe10102009-08-20 07:17:43 +00003221 if (!getDerived().AlwaysRebuild() &&
3222 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003223 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003224
3225 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3226 move(Target));
3227}
3228
3229template<typename Derived>
3230Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003231TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *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>::TransformBreakStmt(BreakStmt *S) {
3238 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003239}
Mike Stump11289f42009-09-09 15:08:12 +00003240
Douglas Gregorebe10102009-08-20 07:17:43 +00003241template<typename Derived>
3242Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003243TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003244 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3245 if (Result.isInvalid())
3246 return SemaRef.StmtError();
3247
Mike Stump11289f42009-09-09 15:08:12 +00003248 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003249 // to tell whether the return type of the function has changed.
3250 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3251}
Mike Stump11289f42009-09-09 15:08:12 +00003252
Douglas Gregorebe10102009-08-20 07:17:43 +00003253template<typename Derived>
3254Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003255TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003256 bool DeclChanged = false;
3257 llvm::SmallVector<Decl *, 4> Decls;
3258 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3259 D != DEnd; ++D) {
3260 Decl *Transformed = getDerived().TransformDefinition(*D);
3261 if (!Transformed)
3262 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003263
Douglas Gregorebe10102009-08-20 07:17:43 +00003264 if (Transformed != *D)
3265 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003266
Douglas Gregorebe10102009-08-20 07:17:43 +00003267 Decls.push_back(Transformed);
3268 }
Mike Stump11289f42009-09-09 15:08:12 +00003269
Douglas Gregorebe10102009-08-20 07:17:43 +00003270 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003271 return SemaRef.Owned(S->Retain());
3272
3273 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003274 S->getStartLoc(), S->getEndLoc());
3275}
Mike Stump11289f42009-09-09 15:08:12 +00003276
Douglas Gregorebe10102009-08-20 07:17:43 +00003277template<typename Derived>
3278Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003279TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003280 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003281 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003282}
3283
3284template<typename Derived>
3285Sema::OwningStmtResult
3286TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3287 // FIXME: Implement!
3288 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003289 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003290}
3291
3292
3293template<typename Derived>
3294Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003295TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003296 // FIXME: Implement this
3297 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003298 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003299}
Mike Stump11289f42009-09-09 15:08:12 +00003300
Douglas Gregorebe10102009-08-20 07:17:43 +00003301template<typename Derived>
3302Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003303TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003304 // FIXME: Implement this
3305 assert(false && "Cannot transform an Objective-C @catch statement");
3306 return SemaRef.Owned(S->Retain());
3307}
Mike Stump11289f42009-09-09 15:08:12 +00003308
Douglas Gregorebe10102009-08-20 07:17:43 +00003309template<typename Derived>
3310Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003311TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003312 // FIXME: Implement this
3313 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003314 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003315}
Mike Stump11289f42009-09-09 15:08:12 +00003316
Douglas Gregorebe10102009-08-20 07:17:43 +00003317template<typename Derived>
3318Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003319TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003320 // FIXME: Implement this
3321 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003322 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003323}
Mike Stump11289f42009-09-09 15:08:12 +00003324
Douglas Gregorebe10102009-08-20 07:17:43 +00003325template<typename Derived>
3326Sema::OwningStmtResult
3327TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003328 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003329 // FIXME: Implement this
3330 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003331 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003332}
3333
3334template<typename Derived>
3335Sema::OwningStmtResult
3336TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003337 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003338 // FIXME: Implement this
3339 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003340 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003341}
3342
3343
3344template<typename Derived>
3345Sema::OwningStmtResult
3346TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3347 // Transform the exception declaration, if any.
3348 VarDecl *Var = 0;
3349 if (S->getExceptionDecl()) {
3350 VarDecl *ExceptionDecl = S->getExceptionDecl();
3351 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3352 ExceptionDecl->getDeclName());
3353
3354 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3355 if (T.isNull())
3356 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003357
Douglas Gregorebe10102009-08-20 07:17:43 +00003358 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3359 T,
3360 ExceptionDecl->getDeclaratorInfo(),
3361 ExceptionDecl->getIdentifier(),
3362 ExceptionDecl->getLocation(),
3363 /*FIXME: Inaccurate*/
3364 SourceRange(ExceptionDecl->getLocation()));
3365 if (!Var || Var->isInvalidDecl()) {
3366 if (Var)
3367 Var->Destroy(SemaRef.Context);
3368 return SemaRef.StmtError();
3369 }
3370 }
Mike Stump11289f42009-09-09 15:08:12 +00003371
Douglas Gregorebe10102009-08-20 07:17:43 +00003372 // Transform the actual exception handler.
3373 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3374 if (Handler.isInvalid()) {
3375 if (Var)
3376 Var->Destroy(SemaRef.Context);
3377 return SemaRef.StmtError();
3378 }
Mike Stump11289f42009-09-09 15:08:12 +00003379
Douglas Gregorebe10102009-08-20 07:17:43 +00003380 if (!getDerived().AlwaysRebuild() &&
3381 !Var &&
3382 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003383 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003384
3385 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3386 Var,
3387 move(Handler));
3388}
Mike Stump11289f42009-09-09 15:08:12 +00003389
Douglas Gregorebe10102009-08-20 07:17:43 +00003390template<typename Derived>
3391Sema::OwningStmtResult
3392TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3393 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003394 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003395 = getDerived().TransformCompoundStmt(S->getTryBlock());
3396 if (TryBlock.isInvalid())
3397 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003398
Douglas Gregorebe10102009-08-20 07:17:43 +00003399 // Transform the handlers.
3400 bool HandlerChanged = false;
3401 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3402 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003403 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003404 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3405 if (Handler.isInvalid())
3406 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003407
Douglas Gregorebe10102009-08-20 07:17:43 +00003408 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3409 Handlers.push_back(Handler.takeAs<Stmt>());
3410 }
Mike Stump11289f42009-09-09 15:08:12 +00003411
Douglas Gregorebe10102009-08-20 07:17:43 +00003412 if (!getDerived().AlwaysRebuild() &&
3413 TryBlock.get() == S->getTryBlock() &&
3414 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003415 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003416
3417 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003418 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003419}
Mike Stump11289f42009-09-09 15:08:12 +00003420
Douglas Gregorebe10102009-08-20 07:17:43 +00003421//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003422// Expression transformation
3423//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003424template<typename Derived>
3425Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003426TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E,
3427 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003428 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003429}
Mike Stump11289f42009-09-09 15:08:12 +00003430
3431template<typename Derived>
3432Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003433TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E,
3434 bool isAddressOfOperand) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003435 NestedNameSpecifier *Qualifier = 0;
3436 if (E->getQualifier()) {
3437 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3438 E->getQualifierRange());
3439 if (!Qualifier)
3440 return SemaRef.ExprError();
3441 }
3442
Mike Stump11289f42009-09-09 15:08:12 +00003443 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003444 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3445 if (!ND)
3446 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003447
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003448 if (!getDerived().AlwaysRebuild() &&
3449 Qualifier == E->getQualifier() &&
3450 ND == E->getDecl() &&
3451 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003452 return SemaRef.Owned(E->Retain());
3453
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003454 // FIXME: We're losing the explicit template arguments in this transformation.
3455
John McCall0ad16662009-10-29 08:12:44 +00003456 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003457 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00003458 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3459 TransArgs[I]))
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003460 return SemaRef.ExprError();
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003461 }
3462
3463 // FIXME: Pass the qualifier/qualifier range along.
3464 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003465 ND, E->getLocation(),
3466 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00003467}
Mike Stump11289f42009-09-09 15:08:12 +00003468
Douglas Gregora16548e2009-08-11 05:31:07 +00003469template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003470Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003471TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E,
3472 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003473 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003474}
Mike Stump11289f42009-09-09 15:08:12 +00003475
Douglas Gregora16548e2009-08-11 05:31:07 +00003476template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003477Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003478TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E,
3479 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003480 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003481}
Mike Stump11289f42009-09-09 15:08:12 +00003482
Douglas Gregora16548e2009-08-11 05:31:07 +00003483template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003484Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003485TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E,
3486 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003487 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003488}
Mike Stump11289f42009-09-09 15:08:12 +00003489
Douglas Gregora16548e2009-08-11 05:31:07 +00003490template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003491Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003492TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E,
3493 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003494 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003495}
Mike Stump11289f42009-09-09 15:08:12 +00003496
Douglas Gregora16548e2009-08-11 05:31:07 +00003497template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003498Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003499TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E,
3500 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003501 return SemaRef.Owned(E->Retain());
3502}
3503
3504template<typename Derived>
3505Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003506TreeTransform<Derived>::TransformParenExpr(ParenExpr *E,
3507 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003508 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3509 if (SubExpr.isInvalid())
3510 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003511
Douglas Gregora16548e2009-08-11 05:31:07 +00003512 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003513 return SemaRef.Owned(E->Retain());
3514
3515 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003516 E->getRParen());
3517}
3518
Mike Stump11289f42009-09-09 15:08:12 +00003519template<typename Derived>
3520Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003521TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E,
3522 bool isAddressOfOperand) {
3523 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr(),
3524 E->getOpcode() == UnaryOperator::AddrOf);
Douglas Gregora16548e2009-08-11 05:31:07 +00003525 if (SubExpr.isInvalid())
3526 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003527
Douglas Gregora16548e2009-08-11 05:31:07 +00003528 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003529 return SemaRef.Owned(E->Retain());
3530
Douglas Gregora16548e2009-08-11 05:31:07 +00003531 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3532 E->getOpcode(),
3533 move(SubExpr));
3534}
Mike Stump11289f42009-09-09 15:08:12 +00003535
Douglas Gregora16548e2009-08-11 05:31:07 +00003536template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003537Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003538TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
3539 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003540 if (E->isArgumentType()) {
John McCall4c98fd82009-11-04 07:28:41 +00003541 DeclaratorInfo *OldT = E->getArgumentTypeInfo();
Douglas Gregor3da3c062009-10-28 00:29:27 +00003542
John McCall4c98fd82009-11-04 07:28:41 +00003543 DeclaratorInfo *NewT = getDerived().TransformType(OldT);
3544 if (!NewT)
Douglas Gregora16548e2009-08-11 05:31:07 +00003545 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003546
John McCall4c98fd82009-11-04 07:28:41 +00003547 if (!getDerived().AlwaysRebuild() && OldT == NewT)
Douglas Gregora16548e2009-08-11 05:31:07 +00003548 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003549
John McCall4c98fd82009-11-04 07:28:41 +00003550 return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003551 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003552 E->getSourceRange());
3553 }
Mike Stump11289f42009-09-09 15:08:12 +00003554
Douglas Gregora16548e2009-08-11 05:31:07 +00003555 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003556 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003557 // C++0x [expr.sizeof]p1:
3558 // The operand is either an expression, which is an unevaluated operand
3559 // [...]
3560 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003561
Douglas Gregora16548e2009-08-11 05:31:07 +00003562 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3563 if (SubExpr.isInvalid())
3564 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003565
Douglas Gregora16548e2009-08-11 05:31:07 +00003566 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3567 return SemaRef.Owned(E->Retain());
3568 }
Mike Stump11289f42009-09-09 15:08:12 +00003569
Douglas Gregora16548e2009-08-11 05:31:07 +00003570 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3571 E->isSizeOf(),
3572 E->getSourceRange());
3573}
Mike Stump11289f42009-09-09 15:08:12 +00003574
Douglas Gregora16548e2009-08-11 05:31:07 +00003575template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003576Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003577TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E,
3578 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003579 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3580 if (LHS.isInvalid())
3581 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003582
Douglas Gregora16548e2009-08-11 05:31:07 +00003583 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3584 if (RHS.isInvalid())
3585 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003586
3587
Douglas Gregora16548e2009-08-11 05:31:07 +00003588 if (!getDerived().AlwaysRebuild() &&
3589 LHS.get() == E->getLHS() &&
3590 RHS.get() == E->getRHS())
3591 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003592
Douglas Gregora16548e2009-08-11 05:31:07 +00003593 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3594 /*FIXME:*/E->getLHS()->getLocStart(),
3595 move(RHS),
3596 E->getRBracketLoc());
3597}
Mike Stump11289f42009-09-09 15:08:12 +00003598
3599template<typename Derived>
3600Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003601TreeTransform<Derived>::TransformCallExpr(CallExpr *E,
3602 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003603 // Transform the callee.
3604 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3605 if (Callee.isInvalid())
3606 return SemaRef.ExprError();
3607
3608 // Transform arguments.
3609 bool ArgChanged = false;
3610 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3611 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3612 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3613 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3614 if (Arg.isInvalid())
3615 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003616
Douglas Gregora16548e2009-08-11 05:31:07 +00003617 // FIXME: Wrong source location information for the ','.
3618 FakeCommaLocs.push_back(
3619 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003620
3621 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003622 Args.push_back(Arg.takeAs<Expr>());
3623 }
Mike Stump11289f42009-09-09 15:08:12 +00003624
Douglas Gregora16548e2009-08-11 05:31:07 +00003625 if (!getDerived().AlwaysRebuild() &&
3626 Callee.get() == E->getCallee() &&
3627 !ArgChanged)
3628 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003629
Douglas Gregora16548e2009-08-11 05:31:07 +00003630 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003631 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003632 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3633 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3634 move_arg(Args),
3635 FakeCommaLocs.data(),
3636 E->getRParenLoc());
3637}
Mike Stump11289f42009-09-09 15:08:12 +00003638
3639template<typename Derived>
3640Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003641TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
3642 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003643 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3644 if (Base.isInvalid())
3645 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003646
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003647 NestedNameSpecifier *Qualifier = 0;
3648 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003649 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003650 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3651 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003652 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003653 return SemaRef.ExprError();
3654 }
Mike Stump11289f42009-09-09 15:08:12 +00003655
3656 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003657 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3658 if (!Member)
3659 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003660
Douglas Gregora16548e2009-08-11 05:31:07 +00003661 if (!getDerived().AlwaysRebuild() &&
3662 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003663 Qualifier == E->getQualifier() &&
Douglas Gregorb184f0d2009-11-04 23:20:05 +00003664 Member == E->getMemberDecl() &&
3665 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003666 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003667
Douglas Gregorb184f0d2009-11-04 23:20:05 +00003668 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs;
3669 if (E->hasExplicitTemplateArgumentList()) {
3670 TransArgs.resize(E->getNumTemplateArgs());
3671 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
3672 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3673 TransArgs[I]))
3674 return SemaRef.ExprError();
3675 }
3676 }
3677
Douglas Gregora16548e2009-08-11 05:31:07 +00003678 // FIXME: Bogus source location for the operator
3679 SourceLocation FakeOperatorLoc
3680 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3681
3682 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3683 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003684 Qualifier,
3685 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003686 E->getMemberLoc(),
Douglas Gregorb184f0d2009-11-04 23:20:05 +00003687 Member,
3688 E->hasExplicitTemplateArgumentList(),
3689 E->getLAngleLoc(),
3690 TransArgs.data(),
3691 TransArgs.size(),
3692 E->getRAngleLoc(),
3693 0);
Douglas Gregora16548e2009-08-11 05:31:07 +00003694}
Mike Stump11289f42009-09-09 15:08:12 +00003695
Douglas Gregora16548e2009-08-11 05:31:07 +00003696template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003697Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003698TreeTransform<Derived>::TransformCastExpr(CastExpr *E,
3699 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003700 assert(false && "Cannot transform abstract class");
3701 return SemaRef.Owned(E->Retain());
3702}
3703
3704template<typename Derived>
3705Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003706TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E,
3707 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003708 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3709 if (LHS.isInvalid())
3710 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003711
Douglas Gregora16548e2009-08-11 05:31:07 +00003712 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3713 if (RHS.isInvalid())
3714 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003715
Douglas Gregora16548e2009-08-11 05:31:07 +00003716 if (!getDerived().AlwaysRebuild() &&
3717 LHS.get() == E->getLHS() &&
3718 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003719 return SemaRef.Owned(E->Retain());
3720
Douglas Gregora16548e2009-08-11 05:31:07 +00003721 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3722 move(LHS), move(RHS));
3723}
3724
Mike Stump11289f42009-09-09 15:08:12 +00003725template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003726Sema::OwningExprResult
3727TreeTransform<Derived>::TransformCompoundAssignOperator(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003728 CompoundAssignOperator *E,
3729 bool isAddressOfOperand) {
3730 return getDerived().TransformBinaryOperator(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00003731}
Mike Stump11289f42009-09-09 15:08:12 +00003732
Douglas Gregora16548e2009-08-11 05:31:07 +00003733template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003734Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003735TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E,
3736 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003737 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3738 if (Cond.isInvalid())
3739 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003740
Douglas Gregora16548e2009-08-11 05:31:07 +00003741 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3742 if (LHS.isInvalid())
3743 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003744
Douglas Gregora16548e2009-08-11 05:31:07 +00003745 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3746 if (RHS.isInvalid())
3747 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003748
Douglas Gregora16548e2009-08-11 05:31:07 +00003749 if (!getDerived().AlwaysRebuild() &&
3750 Cond.get() == E->getCond() &&
3751 LHS.get() == E->getLHS() &&
3752 RHS.get() == E->getRHS())
3753 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003754
3755 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003756 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003757 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003758 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003759 move(RHS));
3760}
Mike Stump11289f42009-09-09 15:08:12 +00003761
3762template<typename Derived>
3763Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003764TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E,
3765 bool isAddressOfOperand) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003766 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3767
3768 // FIXME: Will we ever have type information here? It seems like we won't,
3769 // so do we even need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003770 QualType T = getDerived().TransformType(E->getType());
3771 if (T.isNull())
3772 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003773
Douglas Gregora16548e2009-08-11 05:31:07 +00003774 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3775 if (SubExpr.isInvalid())
3776 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003777
Douglas Gregora16548e2009-08-11 05:31:07 +00003778 if (!getDerived().AlwaysRebuild() &&
3779 T == E->getType() &&
3780 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003781 return SemaRef.Owned(E->Retain());
3782
Douglas Gregora16548e2009-08-11 05:31:07 +00003783 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003784 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003785 E->isLvalueCast());
3786}
Mike Stump11289f42009-09-09 15:08:12 +00003787
Douglas Gregora16548e2009-08-11 05:31:07 +00003788template<typename Derived>
3789Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003790TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E,
3791 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00003792 assert(false && "Cannot transform abstract class");
3793 return SemaRef.Owned(E->Retain());
3794}
3795
3796template<typename Derived>
3797Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003798TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E,
3799 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003800 QualType T;
3801 {
3802 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003803 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003804 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3805 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003806
Douglas Gregora16548e2009-08-11 05:31:07 +00003807 T = getDerived().TransformType(E->getTypeAsWritten());
3808 if (T.isNull())
3809 return SemaRef.ExprError();
3810 }
Mike Stump11289f42009-09-09 15:08:12 +00003811
Douglas Gregora16548e2009-08-11 05:31:07 +00003812 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3813 if (SubExpr.isInvalid())
3814 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003815
Douglas Gregora16548e2009-08-11 05:31:07 +00003816 if (!getDerived().AlwaysRebuild() &&
3817 T == E->getTypeAsWritten() &&
3818 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003819 return SemaRef.Owned(E->Retain());
3820
Douglas Gregora16548e2009-08-11 05:31:07 +00003821 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3822 E->getRParenLoc(),
3823 move(SubExpr));
3824}
Mike Stump11289f42009-09-09 15:08:12 +00003825
Douglas Gregora16548e2009-08-11 05:31:07 +00003826template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003827Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003828TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E,
3829 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003830 QualType T;
3831 {
3832 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003833 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003834 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3835 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003836
Douglas Gregora16548e2009-08-11 05:31:07 +00003837 T = getDerived().TransformType(E->getType());
3838 if (T.isNull())
3839 return SemaRef.ExprError();
3840 }
Mike Stump11289f42009-09-09 15:08:12 +00003841
Douglas Gregora16548e2009-08-11 05:31:07 +00003842 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3843 if (Init.isInvalid())
3844 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003845
Douglas Gregora16548e2009-08-11 05:31:07 +00003846 if (!getDerived().AlwaysRebuild() &&
3847 T == E->getType() &&
3848 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003849 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003850
3851 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3852 /*FIXME:*/E->getInitializer()->getLocEnd(),
3853 move(Init));
3854}
Mike Stump11289f42009-09-09 15:08:12 +00003855
Douglas Gregora16548e2009-08-11 05:31:07 +00003856template<typename Derived>
3857Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003858TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E,
3859 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003860 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3861 if (Base.isInvalid())
3862 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003863
Douglas Gregora16548e2009-08-11 05:31:07 +00003864 if (!getDerived().AlwaysRebuild() &&
3865 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003866 return SemaRef.Owned(E->Retain());
3867
Douglas Gregora16548e2009-08-11 05:31:07 +00003868 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003869 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003870 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3871 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3872 E->getAccessorLoc(),
3873 E->getAccessor());
3874}
Mike Stump11289f42009-09-09 15:08:12 +00003875
Douglas Gregora16548e2009-08-11 05:31:07 +00003876template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003877Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003878TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E,
3879 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003880 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003881
Douglas Gregora16548e2009-08-11 05:31:07 +00003882 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3883 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3884 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3885 if (Init.isInvalid())
3886 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003887
Douglas Gregora16548e2009-08-11 05:31:07 +00003888 InitChanged = InitChanged || Init.get() != E->getInit(I);
3889 Inits.push_back(Init.takeAs<Expr>());
3890 }
Mike Stump11289f42009-09-09 15:08:12 +00003891
Douglas Gregora16548e2009-08-11 05:31:07 +00003892 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003893 return SemaRef.Owned(E->Retain());
3894
Douglas Gregora16548e2009-08-11 05:31:07 +00003895 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3896 E->getRBraceLoc());
3897}
Mike Stump11289f42009-09-09 15:08:12 +00003898
Douglas Gregora16548e2009-08-11 05:31:07 +00003899template<typename Derived>
3900Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003901TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E,
3902 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003903 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003904
Douglas Gregorebe10102009-08-20 07:17:43 +00003905 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003906 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3907 if (Init.isInvalid())
3908 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003909
Douglas Gregorebe10102009-08-20 07:17:43 +00003910 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003911 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3912 bool ExprChanged = false;
3913 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3914 DEnd = E->designators_end();
3915 D != DEnd; ++D) {
3916 if (D->isFieldDesignator()) {
3917 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3918 D->getDotLoc(),
3919 D->getFieldLoc()));
3920 continue;
3921 }
Mike Stump11289f42009-09-09 15:08:12 +00003922
Douglas Gregora16548e2009-08-11 05:31:07 +00003923 if (D->isArrayDesignator()) {
3924 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3925 if (Index.isInvalid())
3926 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003927
3928 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003929 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003930
Douglas Gregora16548e2009-08-11 05:31:07 +00003931 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3932 ArrayExprs.push_back(Index.release());
3933 continue;
3934 }
Mike Stump11289f42009-09-09 15:08:12 +00003935
Douglas Gregora16548e2009-08-11 05:31:07 +00003936 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003937 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003938 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3939 if (Start.isInvalid())
3940 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003941
Douglas Gregora16548e2009-08-11 05:31:07 +00003942 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3943 if (End.isInvalid())
3944 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003945
3946 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003947 End.get(),
3948 D->getLBracketLoc(),
3949 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003950
Douglas Gregora16548e2009-08-11 05:31:07 +00003951 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3952 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003953
Douglas Gregora16548e2009-08-11 05:31:07 +00003954 ArrayExprs.push_back(Start.release());
3955 ArrayExprs.push_back(End.release());
3956 }
Mike Stump11289f42009-09-09 15:08:12 +00003957
Douglas Gregora16548e2009-08-11 05:31:07 +00003958 if (!getDerived().AlwaysRebuild() &&
3959 Init.get() == E->getInit() &&
3960 !ExprChanged)
3961 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003962
Douglas Gregora16548e2009-08-11 05:31:07 +00003963 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3964 E->getEqualOrColonLoc(),
3965 E->usesGNUSyntax(), move(Init));
3966}
Mike Stump11289f42009-09-09 15:08:12 +00003967
Douglas Gregora16548e2009-08-11 05:31:07 +00003968template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003969Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003970TreeTransform<Derived>::TransformImplicitValueInitExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003971 ImplicitValueInitExpr *E,
3972 bool isAddressOfOperand) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003973 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3974
3975 // FIXME: Will we ever have proper type location here? Will we actually
3976 // need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003977 QualType T = getDerived().TransformType(E->getType());
3978 if (T.isNull())
3979 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003980
Douglas Gregora16548e2009-08-11 05:31:07 +00003981 if (!getDerived().AlwaysRebuild() &&
3982 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003983 return SemaRef.Owned(E->Retain());
3984
Douglas Gregora16548e2009-08-11 05:31:07 +00003985 return getDerived().RebuildImplicitValueInitExpr(T);
3986}
Mike Stump11289f42009-09-09 15:08:12 +00003987
Douglas Gregora16548e2009-08-11 05:31:07 +00003988template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003989Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00003990TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E,
3991 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003992 // FIXME: Do we want the type as written?
3993 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003994
Douglas Gregora16548e2009-08-11 05:31:07 +00003995 {
3996 // FIXME: Source location isn't quite accurate.
3997 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3998 T = getDerived().TransformType(E->getType());
3999 if (T.isNull())
4000 return SemaRef.ExprError();
4001 }
Mike Stump11289f42009-09-09 15:08:12 +00004002
Douglas Gregora16548e2009-08-11 05:31:07 +00004003 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4004 if (SubExpr.isInvalid())
4005 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004006
Douglas Gregora16548e2009-08-11 05:31:07 +00004007 if (!getDerived().AlwaysRebuild() &&
4008 T == E->getType() &&
4009 SubExpr.get() == E->getSubExpr())
4010 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004011
Douglas Gregora16548e2009-08-11 05:31:07 +00004012 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
4013 T, E->getRParenLoc());
4014}
4015
4016template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004017Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004018TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E,
4019 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004020 bool ArgumentChanged = false;
4021 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
4022 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
4023 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
4024 if (Init.isInvalid())
4025 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004026
Douglas Gregora16548e2009-08-11 05:31:07 +00004027 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
4028 Inits.push_back(Init.takeAs<Expr>());
4029 }
Mike Stump11289f42009-09-09 15:08:12 +00004030
Douglas Gregora16548e2009-08-11 05:31:07 +00004031 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
4032 move_arg(Inits),
4033 E->getRParenLoc());
4034}
Mike Stump11289f42009-09-09 15:08:12 +00004035
Douglas Gregora16548e2009-08-11 05:31:07 +00004036/// \brief Transform an address-of-label expression.
4037///
4038/// By default, the transformation of an address-of-label expression always
4039/// rebuilds the expression, so that the label identifier can be resolved to
4040/// the corresponding label statement by semantic analysis.
4041template<typename Derived>
4042Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004043TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E,
4044 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004045 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
4046 E->getLabel());
4047}
Mike Stump11289f42009-09-09 15:08:12 +00004048
4049template<typename Derived>
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004050Sema::OwningExprResult
4051TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E,
4052 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004053 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00004054 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
4055 if (SubStmt.isInvalid())
4056 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004057
Douglas Gregora16548e2009-08-11 05:31:07 +00004058 if (!getDerived().AlwaysRebuild() &&
4059 SubStmt.get() == E->getSubStmt())
4060 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004061
4062 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004063 move(SubStmt),
4064 E->getRParenLoc());
4065}
Mike Stump11289f42009-09-09 15:08:12 +00004066
Douglas Gregora16548e2009-08-11 05:31:07 +00004067template<typename Derived>
4068Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004069TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E,
4070 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004071 QualType T1, T2;
4072 {
4073 // FIXME: Source location isn't quite accurate.
4074 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004075
Douglas Gregora16548e2009-08-11 05:31:07 +00004076 T1 = getDerived().TransformType(E->getArgType1());
4077 if (T1.isNull())
4078 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004079
Douglas Gregora16548e2009-08-11 05:31:07 +00004080 T2 = getDerived().TransformType(E->getArgType2());
4081 if (T2.isNull())
4082 return SemaRef.ExprError();
4083 }
4084
4085 if (!getDerived().AlwaysRebuild() &&
4086 T1 == E->getArgType1() &&
4087 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00004088 return SemaRef.Owned(E->Retain());
4089
Douglas Gregora16548e2009-08-11 05:31:07 +00004090 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
4091 T1, T2, E->getRParenLoc());
4092}
Mike Stump11289f42009-09-09 15:08:12 +00004093
Douglas Gregora16548e2009-08-11 05:31:07 +00004094template<typename Derived>
4095Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004096TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E,
4097 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004098 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4099 if (Cond.isInvalid())
4100 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004101
Douglas Gregora16548e2009-08-11 05:31:07 +00004102 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4103 if (LHS.isInvalid())
4104 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004105
Douglas Gregora16548e2009-08-11 05:31:07 +00004106 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4107 if (RHS.isInvalid())
4108 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004109
Douglas Gregora16548e2009-08-11 05:31:07 +00004110 if (!getDerived().AlwaysRebuild() &&
4111 Cond.get() == E->getCond() &&
4112 LHS.get() == E->getLHS() &&
4113 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00004114 return SemaRef.Owned(E->Retain());
4115
Douglas Gregora16548e2009-08-11 05:31:07 +00004116 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4117 move(Cond), move(LHS), move(RHS),
4118 E->getRParenLoc());
4119}
Mike Stump11289f42009-09-09 15:08:12 +00004120
Douglas Gregora16548e2009-08-11 05:31:07 +00004121template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004122Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004123TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E,
4124 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004125 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004126}
4127
4128template<typename Derived>
4129Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004130TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E,
4131 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004132 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4133 if (Callee.isInvalid())
4134 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004135
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004136 OwningExprResult First
4137 = getDerived().TransformExpr(E->getArg(0),
4138 E->getNumArgs() == 1 && E->getOperator() == OO_Amp);
Douglas Gregora16548e2009-08-11 05:31:07 +00004139 if (First.isInvalid())
4140 return SemaRef.ExprError();
4141
4142 OwningExprResult Second(SemaRef);
4143 if (E->getNumArgs() == 2) {
4144 Second = getDerived().TransformExpr(E->getArg(1));
4145 if (Second.isInvalid())
4146 return SemaRef.ExprError();
4147 }
Mike Stump11289f42009-09-09 15:08:12 +00004148
Douglas Gregora16548e2009-08-11 05:31:07 +00004149 if (!getDerived().AlwaysRebuild() &&
4150 Callee.get() == E->getCallee() &&
4151 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00004152 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4153 return SemaRef.Owned(E->Retain());
4154
Douglas Gregora16548e2009-08-11 05:31:07 +00004155 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4156 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004157 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00004158 move(First),
4159 move(Second));
4160}
Mike Stump11289f42009-09-09 15:08:12 +00004161
Douglas Gregora16548e2009-08-11 05:31:07 +00004162template<typename Derived>
4163Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004164TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E,
4165 bool isAddressOfOperand) {
4166 return getDerived().TransformCallExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004167}
Mike Stump11289f42009-09-09 15:08:12 +00004168
Douglas Gregora16548e2009-08-11 05:31:07 +00004169template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004170Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004171TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E,
4172 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004173 QualType ExplicitTy;
4174 {
4175 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00004176 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004177 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4178 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004179
Douglas Gregora16548e2009-08-11 05:31:07 +00004180 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4181 if (ExplicitTy.isNull())
4182 return SemaRef.ExprError();
4183 }
Mike Stump11289f42009-09-09 15:08:12 +00004184
Douglas Gregora16548e2009-08-11 05:31:07 +00004185 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4186 if (SubExpr.isInvalid())
4187 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004188
Douglas Gregora16548e2009-08-11 05:31:07 +00004189 if (!getDerived().AlwaysRebuild() &&
4190 ExplicitTy == E->getTypeAsWritten() &&
4191 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004192 return SemaRef.Owned(E->Retain());
4193
Douglas Gregora16548e2009-08-11 05:31:07 +00004194 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00004195 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004196 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4197 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4198 SourceLocation FakeRParenLoc
4199 = SemaRef.PP.getLocForEndOfToken(
4200 E->getSubExpr()->getSourceRange().getEnd());
4201 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004202 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004203 FakeLAngleLoc,
4204 ExplicitTy,
4205 FakeRAngleLoc,
4206 FakeRAngleLoc,
4207 move(SubExpr),
4208 FakeRParenLoc);
4209}
Mike Stump11289f42009-09-09 15:08:12 +00004210
Douglas Gregora16548e2009-08-11 05:31:07 +00004211template<typename Derived>
4212Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004213TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E,
4214 bool isAddressOfOperand) {
4215 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004216}
Mike Stump11289f42009-09-09 15:08:12 +00004217
4218template<typename Derived>
4219Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004220TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E,
4221 bool isAddressOfOperand) {
4222 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Mike Stump11289f42009-09-09 15:08:12 +00004223}
4224
Douglas Gregora16548e2009-08-11 05:31:07 +00004225template<typename Derived>
4226Sema::OwningExprResult
4227TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004228 CXXReinterpretCastExpr *E,
4229 bool isAddressOfOperand) {
4230 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004231}
Mike Stump11289f42009-09-09 15:08:12 +00004232
Douglas Gregora16548e2009-08-11 05:31:07 +00004233template<typename Derived>
4234Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004235TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E,
4236 bool isAddressOfOperand) {
4237 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004238}
Mike Stump11289f42009-09-09 15:08:12 +00004239
Douglas Gregora16548e2009-08-11 05:31:07 +00004240template<typename Derived>
4241Sema::OwningExprResult
4242TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004243 CXXFunctionalCastExpr *E,
4244 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004245 QualType ExplicitTy;
4246 {
4247 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004248
Douglas Gregora16548e2009-08-11 05:31:07 +00004249 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4250 if (ExplicitTy.isNull())
4251 return SemaRef.ExprError();
4252 }
Mike Stump11289f42009-09-09 15:08:12 +00004253
Douglas Gregora16548e2009-08-11 05:31:07 +00004254 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4255 if (SubExpr.isInvalid())
4256 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004257
Douglas Gregora16548e2009-08-11 05:31:07 +00004258 if (!getDerived().AlwaysRebuild() &&
4259 ExplicitTy == E->getTypeAsWritten() &&
4260 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004261 return SemaRef.Owned(E->Retain());
4262
Douglas Gregora16548e2009-08-11 05:31:07 +00004263 // FIXME: The end of the type's source range is wrong
4264 return getDerived().RebuildCXXFunctionalCastExpr(
4265 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4266 ExplicitTy,
4267 /*FIXME:*/E->getSubExpr()->getLocStart(),
4268 move(SubExpr),
4269 E->getRParenLoc());
4270}
Mike Stump11289f42009-09-09 15:08:12 +00004271
Douglas Gregora16548e2009-08-11 05:31:07 +00004272template<typename Derived>
4273Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004274TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E,
4275 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004276 if (E->isTypeOperand()) {
4277 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004278
Douglas Gregora16548e2009-08-11 05:31:07 +00004279 QualType T = getDerived().TransformType(E->getTypeOperand());
4280 if (T.isNull())
4281 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004282
Douglas Gregora16548e2009-08-11 05:31:07 +00004283 if (!getDerived().AlwaysRebuild() &&
4284 T == E->getTypeOperand())
4285 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004286
Douglas Gregora16548e2009-08-11 05:31:07 +00004287 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4288 /*FIXME:*/E->getLocStart(),
4289 T,
4290 E->getLocEnd());
4291 }
Mike Stump11289f42009-09-09 15:08:12 +00004292
Douglas Gregora16548e2009-08-11 05:31:07 +00004293 // We don't know whether the expression is potentially evaluated until
4294 // after we perform semantic analysis, so the expression is potentially
4295 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004296 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004297 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004298
Douglas Gregora16548e2009-08-11 05:31:07 +00004299 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4300 if (SubExpr.isInvalid())
4301 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004302
Douglas Gregora16548e2009-08-11 05:31:07 +00004303 if (!getDerived().AlwaysRebuild() &&
4304 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004305 return SemaRef.Owned(E->Retain());
4306
Douglas Gregora16548e2009-08-11 05:31:07 +00004307 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4308 /*FIXME:*/E->getLocStart(),
4309 move(SubExpr),
4310 E->getLocEnd());
4311}
4312
4313template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004314Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004315TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E,
4316 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004317 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004318}
Mike Stump11289f42009-09-09 15:08:12 +00004319
Douglas Gregora16548e2009-08-11 05:31:07 +00004320template<typename Derived>
4321Sema::OwningExprResult
4322TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004323 CXXNullPtrLiteralExpr *E,
4324 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004325 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004326}
Mike Stump11289f42009-09-09 15:08:12 +00004327
Douglas Gregora16548e2009-08-11 05:31:07 +00004328template<typename Derived>
4329Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004330TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E,
4331 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004332 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004333
Douglas Gregora16548e2009-08-11 05:31:07 +00004334 QualType T = getDerived().TransformType(E->getType());
4335 if (T.isNull())
4336 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004337
Douglas Gregora16548e2009-08-11 05:31:07 +00004338 if (!getDerived().AlwaysRebuild() &&
4339 T == E->getType())
4340 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004341
Douglas Gregora16548e2009-08-11 05:31:07 +00004342 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4343}
Mike Stump11289f42009-09-09 15:08:12 +00004344
Douglas Gregora16548e2009-08-11 05:31:07 +00004345template<typename Derived>
4346Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004347TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E,
4348 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004349 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4350 if (SubExpr.isInvalid())
4351 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004352
Douglas Gregora16548e2009-08-11 05:31:07 +00004353 if (!getDerived().AlwaysRebuild() &&
4354 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004355 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004356
4357 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4358}
Mike Stump11289f42009-09-09 15:08:12 +00004359
Douglas Gregora16548e2009-08-11 05:31:07 +00004360template<typename Derived>
4361Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004362TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
4363 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004364 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004365 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4366 if (!Param)
4367 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004368
Douglas Gregora16548e2009-08-11 05:31:07 +00004369 if (getDerived().AlwaysRebuild() &&
4370 Param == E->getParam())
4371 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004372
Douglas Gregora16548e2009-08-11 05:31:07 +00004373 return getDerived().RebuildCXXDefaultArgExpr(Param);
4374}
Mike Stump11289f42009-09-09 15:08:12 +00004375
Douglas Gregora16548e2009-08-11 05:31:07 +00004376template<typename Derived>
4377Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004378TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E,
4379 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004380 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4381
4382 QualType T = getDerived().TransformType(E->getType());
4383 if (T.isNull())
4384 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004385
Douglas Gregora16548e2009-08-11 05:31:07 +00004386 if (!getDerived().AlwaysRebuild() &&
4387 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004388 return SemaRef.Owned(E->Retain());
4389
4390 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004391 /*FIXME:*/E->getTypeBeginLoc(),
4392 T,
4393 E->getRParenLoc());
4394}
Mike Stump11289f42009-09-09 15:08:12 +00004395
Douglas Gregora16548e2009-08-11 05:31:07 +00004396template<typename Derived>
4397Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004398TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E,
4399 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004400 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004401 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004402 if (!Var)
4403 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004404
Douglas Gregora16548e2009-08-11 05:31:07 +00004405 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004406 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004407 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004408
4409 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004410 /*FIXME:*/E->getStartLoc(),
4411 Var);
4412}
Mike Stump11289f42009-09-09 15:08:12 +00004413
Douglas Gregora16548e2009-08-11 05:31:07 +00004414template<typename Derived>
4415Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004416TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E,
4417 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004418 // Transform the type that we're allocating
4419 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4420 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4421 if (AllocType.isNull())
4422 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004423
Douglas Gregora16548e2009-08-11 05:31:07 +00004424 // Transform the size of the array we're allocating (if any).
4425 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4426 if (ArraySize.isInvalid())
4427 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004428
Douglas Gregora16548e2009-08-11 05:31:07 +00004429 // Transform the placement arguments (if any).
4430 bool ArgumentChanged = false;
4431 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4432 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4433 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4434 if (Arg.isInvalid())
4435 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004436
Douglas Gregora16548e2009-08-11 05:31:07 +00004437 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4438 PlacementArgs.push_back(Arg.take());
4439 }
Mike Stump11289f42009-09-09 15:08:12 +00004440
Douglas Gregorebe10102009-08-20 07:17:43 +00004441 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004442 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4443 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4444 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4445 if (Arg.isInvalid())
4446 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004447
Douglas Gregora16548e2009-08-11 05:31:07 +00004448 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4449 ConstructorArgs.push_back(Arg.take());
4450 }
Mike Stump11289f42009-09-09 15:08:12 +00004451
Douglas Gregora16548e2009-08-11 05:31:07 +00004452 if (!getDerived().AlwaysRebuild() &&
4453 AllocType == E->getAllocatedType() &&
4454 ArraySize.get() == E->getArraySize() &&
4455 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004456 return SemaRef.Owned(E->Retain());
4457
Douglas Gregora16548e2009-08-11 05:31:07 +00004458 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4459 E->isGlobalNew(),
4460 /*FIXME:*/E->getLocStart(),
4461 move_arg(PlacementArgs),
4462 /*FIXME:*/E->getLocStart(),
4463 E->isParenTypeId(),
4464 AllocType,
4465 /*FIXME:*/E->getLocStart(),
4466 /*FIXME:*/SourceRange(),
4467 move(ArraySize),
4468 /*FIXME:*/E->getLocStart(),
4469 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004470 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004471}
Mike Stump11289f42009-09-09 15:08:12 +00004472
Douglas Gregora16548e2009-08-11 05:31:07 +00004473template<typename Derived>
4474Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004475TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E,
4476 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004477 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4478 if (Operand.isInvalid())
4479 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004480
Douglas Gregora16548e2009-08-11 05:31:07 +00004481 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004482 Operand.get() == E->getArgument())
4483 return SemaRef.Owned(E->Retain());
4484
Douglas Gregora16548e2009-08-11 05:31:07 +00004485 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4486 E->isGlobalDelete(),
4487 E->isArrayForm(),
4488 move(Operand));
4489}
Mike Stump11289f42009-09-09 15:08:12 +00004490
Douglas Gregora16548e2009-08-11 05:31:07 +00004491template<typename Derived>
4492Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004493TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004494 CXXPseudoDestructorExpr *E,
4495 bool isAddressOfOperand) {
Douglas Gregorad8a3362009-09-04 17:36:40 +00004496 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4497 if (Base.isInvalid())
4498 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004499
Douglas Gregorad8a3362009-09-04 17:36:40 +00004500 NestedNameSpecifier *Qualifier
4501 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4502 E->getQualifierRange());
4503 if (E->getQualifier() && !Qualifier)
4504 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004505
Douglas Gregorad8a3362009-09-04 17:36:40 +00004506 QualType DestroyedType;
4507 {
4508 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4509 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4510 if (DestroyedType.isNull())
4511 return SemaRef.ExprError();
4512 }
Mike Stump11289f42009-09-09 15:08:12 +00004513
Douglas Gregorad8a3362009-09-04 17:36:40 +00004514 if (!getDerived().AlwaysRebuild() &&
4515 Base.get() == E->getBase() &&
4516 Qualifier == E->getQualifier() &&
4517 DestroyedType == E->getDestroyedType())
4518 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004519
Douglas Gregorad8a3362009-09-04 17:36:40 +00004520 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4521 E->getOperatorLoc(),
4522 E->isArrow(),
4523 E->getDestroyedTypeLoc(),
4524 DestroyedType,
4525 Qualifier,
4526 E->getQualifierRange());
4527}
Mike Stump11289f42009-09-09 15:08:12 +00004528
Douglas Gregorad8a3362009-09-04 17:36:40 +00004529template<typename Derived>
4530Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004531TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004532 UnresolvedFunctionNameExpr *E,
4533 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004534 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004535 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004536}
Mike Stump11289f42009-09-09 15:08:12 +00004537
Douglas Gregora16548e2009-08-11 05:31:07 +00004538template<typename Derived>
4539Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004540TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E,
4541 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004542 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004543
Douglas Gregora16548e2009-08-11 05:31:07 +00004544 QualType T = getDerived().TransformType(E->getQueriedType());
4545 if (T.isNull())
4546 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004547
Douglas Gregora16548e2009-08-11 05:31:07 +00004548 if (!getDerived().AlwaysRebuild() &&
4549 T == E->getQueriedType())
4550 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004551
Douglas Gregora16548e2009-08-11 05:31:07 +00004552 // FIXME: Bad location information
4553 SourceLocation FakeLParenLoc
4554 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004555
4556 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004557 E->getLocStart(),
4558 /*FIXME:*/FakeLParenLoc,
4559 T,
4560 E->getLocEnd());
4561}
Mike Stump11289f42009-09-09 15:08:12 +00004562
Douglas Gregora16548e2009-08-11 05:31:07 +00004563template<typename Derived>
4564Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004565TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004566 UnresolvedDeclRefExpr *E,
4567 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004568 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004569 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4570 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004571 if (!NNS)
4572 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004573
4574 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004575 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4576 if (!Name)
4577 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004578
4579 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004580 NNS == E->getQualifier() &&
4581 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004582 return SemaRef.Owned(E->Retain());
4583
4584 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004585 E->getQualifierRange(),
4586 Name,
4587 E->getLocation(),
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004588 isAddressOfOperand);
Douglas Gregora16548e2009-08-11 05:31:07 +00004589}
4590
4591template<typename Derived>
4592Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004593TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E,
4594 bool isAddressOfOperand) {
Douglas Gregorba91b892009-10-29 17:56:10 +00004595 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4596
Mike Stump11289f42009-09-09 15:08:12 +00004597 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004598 = getDerived().TransformTemplateName(E->getTemplateName());
4599 if (Template.isNull())
4600 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004601
Douglas Gregord019ff62009-10-22 17:20:55 +00004602 NestedNameSpecifier *Qualifier = 0;
4603 if (E->getQualifier()) {
4604 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4605 E->getQualifierRange());
4606 if (!Qualifier)
4607 return SemaRef.ExprError();
4608 }
4609
John McCall0ad16662009-10-29 08:12:44 +00004610 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora16548e2009-08-11 05:31:07 +00004611 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004612 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4613 TransArgs[I]))
Douglas Gregora16548e2009-08-11 05:31:07 +00004614 return SemaRef.ExprError();
Douglas Gregora16548e2009-08-11 05:31:07 +00004615 }
4616
4617 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4618 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004619
4620 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004621 // actually refers to a type, in which case the caller is actually dealing
4622 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004623 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4624 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004625 E->getLAngleLoc(),
4626 TransArgs.data(),
4627 TransArgs.size(),
4628 E->getRAngleLoc());
4629}
4630
4631template<typename Derived>
4632Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004633TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E,
4634 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004635 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4636
4637 QualType T = getDerived().TransformType(E->getType());
4638 if (T.isNull())
4639 return SemaRef.ExprError();
4640
4641 CXXConstructorDecl *Constructor
4642 = cast_or_null<CXXConstructorDecl>(
4643 getDerived().TransformDecl(E->getConstructor()));
4644 if (!Constructor)
4645 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004646
Douglas Gregora16548e2009-08-11 05:31:07 +00004647 bool ArgumentChanged = false;
4648 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004649 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004650 ArgEnd = E->arg_end();
4651 Arg != ArgEnd; ++Arg) {
4652 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4653 if (TransArg.isInvalid())
4654 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004655
Douglas Gregora16548e2009-08-11 05:31:07 +00004656 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4657 Args.push_back(TransArg.takeAs<Expr>());
4658 }
4659
4660 if (!getDerived().AlwaysRebuild() &&
4661 T == E->getType() &&
4662 Constructor == E->getConstructor() &&
4663 !ArgumentChanged)
4664 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004665
Douglas Gregora16548e2009-08-11 05:31:07 +00004666 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4667 move_arg(Args));
4668}
Mike Stump11289f42009-09-09 15:08:12 +00004669
Douglas Gregora16548e2009-08-11 05:31:07 +00004670/// \brief Transform a C++ temporary-binding expression.
4671///
Mike Stump11289f42009-09-09 15:08:12 +00004672/// The transformation of a temporary-binding expression always attempts to
4673/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004674/// subexpression itself did not change, because the temporary variable itself
4675/// must be unique.
4676template<typename Derived>
4677Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004678TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
4679 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004680 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4681 if (SubExpr.isInvalid())
4682 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004683
Douglas Gregora16548e2009-08-11 05:31:07 +00004684 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4685}
Mike Stump11289f42009-09-09 15:08:12 +00004686
4687/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004688/// be destroyed after the expression is evaluated.
4689///
Mike Stump11289f42009-09-09 15:08:12 +00004690/// The transformation of a full expression always attempts to build a new
4691/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004692/// subexpression itself did not change, because it will need to capture the
4693/// the new temporary variables introduced in the subexpression.
4694template<typename Derived>
4695Sema::OwningExprResult
4696TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004697 CXXExprWithTemporaries *E,
4698 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004699 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4700 if (SubExpr.isInvalid())
4701 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004702
Douglas Gregora16548e2009-08-11 05:31:07 +00004703 return SemaRef.Owned(
4704 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4705 E->shouldDestroyTemporaries()));
4706}
Mike Stump11289f42009-09-09 15:08:12 +00004707
Douglas Gregora16548e2009-08-11 05:31:07 +00004708template<typename Derived>
4709Sema::OwningExprResult
4710TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004711 CXXTemporaryObjectExpr *E,
4712 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004713 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4714 QualType T = getDerived().TransformType(E->getType());
4715 if (T.isNull())
4716 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004717
Douglas Gregora16548e2009-08-11 05:31:07 +00004718 CXXConstructorDecl *Constructor
4719 = cast_or_null<CXXConstructorDecl>(
4720 getDerived().TransformDecl(E->getConstructor()));
4721 if (!Constructor)
4722 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004723
Douglas Gregora16548e2009-08-11 05:31:07 +00004724 bool ArgumentChanged = false;
4725 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4726 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004727 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004728 ArgEnd = E->arg_end();
4729 Arg != ArgEnd; ++Arg) {
4730 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4731 if (TransArg.isInvalid())
4732 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004733
Douglas Gregora16548e2009-08-11 05:31:07 +00004734 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4735 Args.push_back((Expr *)TransArg.release());
4736 }
Mike Stump11289f42009-09-09 15:08:12 +00004737
Douglas Gregora16548e2009-08-11 05:31:07 +00004738 if (!getDerived().AlwaysRebuild() &&
4739 T == E->getType() &&
4740 Constructor == E->getConstructor() &&
4741 !ArgumentChanged)
4742 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004743
Douglas Gregora16548e2009-08-11 05:31:07 +00004744 // FIXME: Bogus location information
4745 SourceLocation CommaLoc;
4746 if (Args.size() > 1) {
4747 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004748 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004749 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4750 }
4751 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4752 T,
4753 /*FIXME:*/E->getTypeBeginLoc(),
4754 move_arg(Args),
4755 &CommaLoc,
4756 E->getLocEnd());
4757}
Mike Stump11289f42009-09-09 15:08:12 +00004758
Douglas Gregora16548e2009-08-11 05:31:07 +00004759template<typename Derived>
4760Sema::OwningExprResult
4761TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004762 CXXUnresolvedConstructExpr *E,
4763 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004764 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4765 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4766 if (T.isNull())
4767 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004768
Douglas Gregora16548e2009-08-11 05:31:07 +00004769 bool ArgumentChanged = false;
4770 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4771 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4772 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4773 ArgEnd = E->arg_end();
4774 Arg != ArgEnd; ++Arg) {
4775 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4776 if (TransArg.isInvalid())
4777 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004778
Douglas Gregora16548e2009-08-11 05:31:07 +00004779 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4780 FakeCommaLocs.push_back(
4781 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4782 Args.push_back(TransArg.takeAs<Expr>());
4783 }
Mike Stump11289f42009-09-09 15:08:12 +00004784
Douglas Gregora16548e2009-08-11 05:31:07 +00004785 if (!getDerived().AlwaysRebuild() &&
4786 T == E->getTypeAsWritten() &&
4787 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004788 return SemaRef.Owned(E->Retain());
4789
Douglas Gregora16548e2009-08-11 05:31:07 +00004790 // FIXME: we're faking the locations of the commas
4791 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4792 T,
4793 E->getLParenLoc(),
4794 move_arg(Args),
4795 FakeCommaLocs.data(),
4796 E->getRParenLoc());
4797}
Mike Stump11289f42009-09-09 15:08:12 +00004798
Douglas Gregora16548e2009-08-11 05:31:07 +00004799template<typename Derived>
4800Sema::OwningExprResult
4801TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004802 CXXUnresolvedMemberExpr *E,
4803 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004804 // Transform the base of the expression.
4805 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4806 if (Base.isInvalid())
4807 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004808
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004809 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004810 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004811 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004812 E->getOperatorLoc(),
4813 E->isArrow()? tok::arrow : tok::period,
4814 ObjectType);
4815 if (Base.isInvalid())
4816 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004817
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004818 // Transform the first part of the nested-name-specifier that qualifies
4819 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004820 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004821 = getDerived().TransformFirstQualifierInScope(
4822 E->getFirstQualifierFoundInScope(),
4823 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004824
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004825 NestedNameSpecifier *Qualifier = 0;
4826 if (E->getQualifier()) {
4827 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4828 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004829 QualType::getFromOpaquePtr(ObjectType),
4830 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004831 if (!Qualifier)
4832 return SemaRef.ExprError();
4833 }
Mike Stump11289f42009-09-09 15:08:12 +00004834
4835 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004836 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4837 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004838 if (!Name)
4839 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004840
Douglas Gregor308047d2009-09-09 00:23:06 +00004841 if (!E->hasExplicitTemplateArgumentList()) {
4842 // This is a reference to a member without an explicitly-specified
4843 // template argument list. Optimize for this common case.
4844 if (!getDerived().AlwaysRebuild() &&
4845 Base.get() == E->getBase() &&
4846 Qualifier == E->getQualifier() &&
4847 Name == E->getMember() &&
4848 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004849 return SemaRef.Owned(E->Retain());
4850
Douglas Gregor308047d2009-09-09 00:23:06 +00004851 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4852 E->isArrow(),
4853 E->getOperatorLoc(),
4854 Qualifier,
4855 E->getQualifierRange(),
4856 Name,
4857 E->getMemberLoc(),
4858 FirstQualifierInScope);
4859 }
4860
4861 // FIXME: This is an ugly hack, which forces the same template name to
4862 // be looked up multiple times. Yuck!
Douglas Gregor71395fa2009-11-04 00:56:37 +00004863 TemporaryBase Rebase(*this, E->getMemberLoc(), DeclarationName());
4864 TemplateName OrigTemplateName;
4865 if (const IdentifierInfo *II = Name.getAsIdentifierInfo())
4866 OrigTemplateName = SemaRef.Context.getDependentTemplateName(0, II);
4867 else
4868 OrigTemplateName
4869 = SemaRef.Context.getDependentTemplateName(0,
4870 Name.getCXXOverloadedOperator());
Mike Stump11289f42009-09-09 15:08:12 +00004871
4872 TemplateName Template
4873 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004874 QualType::getFromOpaquePtr(ObjectType));
4875 if (Template.isNull())
4876 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004877
John McCall0ad16662009-10-29 08:12:44 +00004878 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor308047d2009-09-09 00:23:06 +00004879 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004880 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4881 TransArgs[I]))
Douglas Gregor308047d2009-09-09 00:23:06 +00004882 return SemaRef.ExprError();
Douglas Gregor308047d2009-09-09 00:23:06 +00004883 }
Mike Stump11289f42009-09-09 15:08:12 +00004884
Douglas Gregora16548e2009-08-11 05:31:07 +00004885 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4886 E->isArrow(),
4887 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004888 Qualifier,
4889 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004890 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004891 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004892 FirstQualifierInScope,
4893 E->getLAngleLoc(),
4894 TransArgs.data(),
4895 TransArgs.size(),
4896 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004897}
4898
4899template<typename Derived>
4900Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004901TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E,
4902 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004903 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004904}
4905
Mike Stump11289f42009-09-09 15:08:12 +00004906template<typename Derived>
4907Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004908TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E,
4909 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004910 // FIXME: poor source location
4911 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4912 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4913 if (EncodedType.isNull())
4914 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004915
Douglas Gregora16548e2009-08-11 05:31:07 +00004916 if (!getDerived().AlwaysRebuild() &&
4917 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004918 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004919
4920 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4921 EncodedType,
4922 E->getRParenLoc());
4923}
Mike Stump11289f42009-09-09 15:08:12 +00004924
Douglas Gregora16548e2009-08-11 05:31:07 +00004925template<typename Derived>
4926Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004927TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E,
4928 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004929 // FIXME: Implement this!
4930 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004931 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004932}
4933
Mike Stump11289f42009-09-09 15:08:12 +00004934template<typename Derived>
4935Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004936TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E,
4937 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004938 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004939}
4940
Mike Stump11289f42009-09-09 15:08:12 +00004941template<typename Derived>
4942Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004943TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E,
4944 bool isAddressOfOperand) {
Mike Stump11289f42009-09-09 15:08:12 +00004945 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004946 = cast_or_null<ObjCProtocolDecl>(
4947 getDerived().TransformDecl(E->getProtocol()));
4948 if (!Protocol)
4949 return SemaRef.ExprError();
4950
4951 if (!getDerived().AlwaysRebuild() &&
4952 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004953 return SemaRef.Owned(E->Retain());
4954
Douglas Gregora16548e2009-08-11 05:31:07 +00004955 return getDerived().RebuildObjCProtocolExpr(Protocol,
4956 E->getAtLoc(),
4957 /*FIXME:*/E->getAtLoc(),
4958 /*FIXME:*/E->getAtLoc(),
4959 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004960
Douglas Gregora16548e2009-08-11 05:31:07 +00004961}
4962
Mike Stump11289f42009-09-09 15:08:12 +00004963template<typename Derived>
4964Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004965TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E,
4966 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004967 // FIXME: Implement this!
4968 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004969 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004970}
4971
Mike Stump11289f42009-09-09 15:08:12 +00004972template<typename Derived>
4973Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004974TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E,
4975 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004976 // FIXME: Implement this!
4977 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004978 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004979}
4980
Mike Stump11289f42009-09-09 15:08:12 +00004981template<typename Derived>
4982Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004983TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004984 ObjCImplicitSetterGetterRefExpr *E,
4985 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004986 // FIXME: Implement this!
4987 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004988 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004989}
4990
Mike Stump11289f42009-09-09 15:08:12 +00004991template<typename Derived>
4992Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00004993TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E,
4994 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004995 // FIXME: Implement this!
4996 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004997 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004998}
4999
Mike Stump11289f42009-09-09 15:08:12 +00005000template<typename Derived>
5001Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00005002TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E,
5003 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005004 // FIXME: Implement this!
5005 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00005006 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00005007}
5008
Mike Stump11289f42009-09-09 15:08:12 +00005009template<typename Derived>
5010Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00005011TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E,
5012 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005013 bool ArgumentChanged = false;
5014 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
5015 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
5016 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
5017 if (SubExpr.isInvalid())
5018 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005019
Douglas Gregora16548e2009-08-11 05:31:07 +00005020 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
5021 SubExprs.push_back(SubExpr.takeAs<Expr>());
5022 }
Mike Stump11289f42009-09-09 15:08:12 +00005023
Douglas Gregora16548e2009-08-11 05:31:07 +00005024 if (!getDerived().AlwaysRebuild() &&
5025 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00005026 return SemaRef.Owned(E->Retain());
5027
Douglas Gregora16548e2009-08-11 05:31:07 +00005028 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
5029 move_arg(SubExprs),
5030 E->getRParenLoc());
5031}
5032
Mike Stump11289f42009-09-09 15:08:12 +00005033template<typename Derived>
5034Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00005035TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E,
5036 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005037 // FIXME: Implement this!
5038 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00005039 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00005040}
5041
Mike Stump11289f42009-09-09 15:08:12 +00005042template<typename Derived>
5043Sema::OwningExprResult
Douglas Gregorc95a1fa2009-11-04 07:01:15 +00005044TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E,
5045 bool isAddressOfOperand) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005046 // FIXME: Implement this!
5047 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00005048 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00005049}
Mike Stump11289f42009-09-09 15:08:12 +00005050
Douglas Gregora16548e2009-08-11 05:31:07 +00005051//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00005052// Type reconstruction
5053//===----------------------------------------------------------------------===//
5054
Mike Stump11289f42009-09-09 15:08:12 +00005055template<typename Derived>
John McCall70dd5f62009-10-30 00:06:24 +00005056QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
5057 SourceLocation Star) {
5058 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005059 getDerived().getBaseEntity());
5060}
5061
Mike Stump11289f42009-09-09 15:08:12 +00005062template<typename Derived>
John McCall70dd5f62009-10-30 00:06:24 +00005063QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
5064 SourceLocation Star) {
5065 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005066 getDerived().getBaseEntity());
5067}
5068
Mike Stump11289f42009-09-09 15:08:12 +00005069template<typename Derived>
5070QualType
John McCall70dd5f62009-10-30 00:06:24 +00005071TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
5072 bool WrittenAsLValue,
5073 SourceLocation Sigil) {
5074 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
5075 Sigil, getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00005076}
5077
5078template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005079QualType
John McCall70dd5f62009-10-30 00:06:24 +00005080TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
5081 QualType ClassType,
5082 SourceLocation Sigil) {
John McCall8ccfcb52009-09-24 19:53:00 +00005083 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
John McCall70dd5f62009-10-30 00:06:24 +00005084 Sigil, getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00005085}
5086
5087template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005088QualType
John McCall70dd5f62009-10-30 00:06:24 +00005089TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType,
5090 SourceLocation Sigil) {
5091 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Sigil,
John McCall550e0c22009-10-21 00:40:46 +00005092 getDerived().getBaseEntity());
5093}
5094
5095template<typename Derived>
5096QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00005097TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
5098 ArrayType::ArraySizeModifier SizeMod,
5099 const llvm::APInt *Size,
5100 Expr *SizeExpr,
5101 unsigned IndexTypeQuals,
5102 SourceRange BracketsRange) {
5103 if (SizeExpr || !Size)
5104 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
5105 IndexTypeQuals, BracketsRange,
5106 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00005107
5108 QualType Types[] = {
5109 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
5110 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
5111 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00005112 };
5113 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
5114 QualType SizeType;
5115 for (unsigned I = 0; I != NumTypes; ++I)
5116 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
5117 SizeType = Types[I];
5118 break;
5119 }
Mike Stump11289f42009-09-09 15:08:12 +00005120
Douglas Gregord6ff3322009-08-04 16:50:30 +00005121 if (SizeType.isNull())
5122 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00005123
Douglas Gregord6ff3322009-08-04 16:50:30 +00005124 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00005125 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005126 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00005127 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00005128}
Mike Stump11289f42009-09-09 15:08:12 +00005129
Douglas Gregord6ff3322009-08-04 16:50:30 +00005130template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005131QualType
5132TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005133 ArrayType::ArraySizeModifier SizeMod,
5134 const llvm::APInt &Size,
John McCall70dd5f62009-10-30 00:06:24 +00005135 unsigned IndexTypeQuals,
5136 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005137 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
John McCall70dd5f62009-10-30 00:06:24 +00005138 IndexTypeQuals, BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005139}
5140
5141template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005142QualType
Mike Stump11289f42009-09-09 15:08:12 +00005143TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005144 ArrayType::ArraySizeModifier SizeMod,
John McCall70dd5f62009-10-30 00:06:24 +00005145 unsigned IndexTypeQuals,
5146 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005147 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
John McCall70dd5f62009-10-30 00:06:24 +00005148 IndexTypeQuals, BracketsRange);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005149}
Mike Stump11289f42009-09-09 15:08:12 +00005150
Douglas Gregord6ff3322009-08-04 16:50:30 +00005151template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005152QualType
5153TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005154 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005155 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005156 unsigned IndexTypeQuals,
5157 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005158 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005159 SizeExpr.takeAs<Expr>(),
5160 IndexTypeQuals, BracketsRange);
5161}
5162
5163template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005164QualType
5165TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005166 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005167 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005168 unsigned IndexTypeQuals,
5169 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005170 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005171 SizeExpr.takeAs<Expr>(),
5172 IndexTypeQuals, BracketsRange);
5173}
5174
5175template<typename Derived>
5176QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5177 unsigned NumElements) {
5178 // FIXME: semantic checking!
5179 return SemaRef.Context.getVectorType(ElementType, NumElements);
5180}
Mike Stump11289f42009-09-09 15:08:12 +00005181
Douglas Gregord6ff3322009-08-04 16:50:30 +00005182template<typename Derived>
5183QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5184 unsigned NumElements,
5185 SourceLocation AttributeLoc) {
5186 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5187 NumElements, true);
5188 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00005189 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005190 AttributeLoc);
5191 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5192 AttributeLoc);
5193}
Mike Stump11289f42009-09-09 15:08:12 +00005194
Douglas Gregord6ff3322009-08-04 16:50:30 +00005195template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005196QualType
5197TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00005198 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005199 SourceLocation AttributeLoc) {
5200 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5201}
Mike Stump11289f42009-09-09 15:08:12 +00005202
Douglas Gregord6ff3322009-08-04 16:50:30 +00005203template<typename Derived>
5204QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00005205 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005206 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00005207 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005208 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00005209 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005210 Quals,
5211 getDerived().getBaseLocation(),
5212 getDerived().getBaseEntity());
5213}
Mike Stump11289f42009-09-09 15:08:12 +00005214
Douglas Gregord6ff3322009-08-04 16:50:30 +00005215template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00005216QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5217 return SemaRef.Context.getFunctionNoProtoType(T);
5218}
5219
5220template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005221QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005222 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5223}
5224
5225template<typename Derived>
5226QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5227 return SemaRef.Context.getTypeOfType(Underlying);
5228}
5229
5230template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005231QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005232 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5233}
5234
5235template<typename Derived>
5236QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00005237 TemplateName Template,
5238 SourceLocation TemplateNameLoc,
5239 SourceLocation LAngleLoc,
5240 const TemplateArgumentLoc *Args,
5241 unsigned NumArgs,
5242 SourceLocation RAngleLoc) {
5243 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
5244 Args, NumArgs, RAngleLoc);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005245}
Mike Stump11289f42009-09-09 15:08:12 +00005246
Douglas Gregor1135c352009-08-06 05:28:30 +00005247template<typename Derived>
5248NestedNameSpecifier *
5249TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5250 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00005251 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005252 QualType ObjectType,
5253 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00005254 CXXScopeSpec SS;
5255 // FIXME: The source location information is all wrong.
5256 SS.setRange(Range);
5257 SS.setScopeRep(Prefix);
5258 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005259 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005260 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005261 ObjectType,
5262 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005263 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005264}
5265
5266template<typename Derived>
5267NestedNameSpecifier *
5268TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5269 SourceRange Range,
5270 NamespaceDecl *NS) {
5271 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5272}
5273
5274template<typename Derived>
5275NestedNameSpecifier *
5276TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5277 SourceRange Range,
5278 bool TemplateKW,
5279 QualType T) {
5280 if (T->isDependentType() || T->isRecordType() ||
5281 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005282 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005283 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5284 T.getTypePtr());
5285 }
Mike Stump11289f42009-09-09 15:08:12 +00005286
Douglas Gregor1135c352009-08-06 05:28:30 +00005287 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5288 return 0;
5289}
Mike Stump11289f42009-09-09 15:08:12 +00005290
Douglas Gregor71dc5092009-08-06 06:41:21 +00005291template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005292TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005293TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5294 bool TemplateKW,
5295 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005296 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005297 Template);
5298}
5299
5300template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005301TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005302TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5303 bool TemplateKW,
5304 OverloadedFunctionDecl *Ovl) {
5305 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5306}
5307
5308template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005309TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005310TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005311 const IdentifierInfo &II,
5312 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005313 CXXScopeSpec SS;
5314 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005315 SS.setScopeRep(Qualifier);
Douglas Gregor3cf81312009-11-03 23:16:33 +00005316 UnqualifiedId Name;
5317 Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
Douglas Gregor308047d2009-09-09 00:23:06 +00005318 return getSema().ActOnDependentTemplateName(
5319 /*FIXME:*/getDerived().getBaseLocation(),
Douglas Gregor308047d2009-09-09 00:23:06 +00005320 SS,
Douglas Gregor3cf81312009-11-03 23:16:33 +00005321 Name,
Douglas Gregor308047d2009-09-09 00:23:06 +00005322 ObjectType.getAsOpaquePtr())
5323 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005324}
Mike Stump11289f42009-09-09 15:08:12 +00005325
Douglas Gregora16548e2009-08-11 05:31:07 +00005326template<typename Derived>
Douglas Gregor71395fa2009-11-04 00:56:37 +00005327TemplateName
5328TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5329 OverloadedOperatorKind Operator,
5330 QualType ObjectType) {
5331 CXXScopeSpec SS;
5332 SS.setRange(SourceRange(getDerived().getBaseLocation()));
5333 SS.setScopeRep(Qualifier);
5334 UnqualifiedId Name;
5335 SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
5336 Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
5337 Operator, SymbolLocations);
5338 return getSema().ActOnDependentTemplateName(
5339 /*FIXME:*/getDerived().getBaseLocation(),
5340 SS,
5341 Name,
5342 ObjectType.getAsOpaquePtr())
5343 .template getAsVal<TemplateName>();
5344}
5345
5346template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005347Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005348TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5349 SourceLocation OpLoc,
5350 ExprArg Callee,
5351 ExprArg First,
5352 ExprArg Second) {
5353 Expr *FirstExpr = (Expr *)First.get();
5354 Expr *SecondExpr = (Expr *)Second.get();
Sebastian Redladba46e2009-10-29 20:17:01 +00005355 DeclRefExpr *DRE
5356 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregora16548e2009-08-11 05:31:07 +00005357 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005358
Douglas Gregora16548e2009-08-11 05:31:07 +00005359 // Determine whether this should be a builtin operation.
Sebastian Redladba46e2009-10-29 20:17:01 +00005360 if (Op == OO_Subscript) {
5361 if (!FirstExpr->getType()->isOverloadableType() &&
5362 !SecondExpr->getType()->isOverloadableType())
5363 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
5364 DRE->getLocStart(),
5365 move(Second), OpLoc);
5366 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005367 if (!FirstExpr->getType()->isOverloadableType()) {
5368 // The argument is not of overloadable type, so try to create a
5369 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005370 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005371 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005372
Douglas Gregora16548e2009-08-11 05:31:07 +00005373 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5374 }
5375 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005376 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005377 !SecondExpr->getType()->isOverloadableType()) {
5378 // Neither of the arguments is an overloadable type, so try to
5379 // create a built-in binary operation.
5380 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005381 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005382 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5383 if (Result.isInvalid())
5384 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005385
Douglas Gregora16548e2009-08-11 05:31:07 +00005386 First.release();
5387 Second.release();
5388 return move(Result);
5389 }
5390 }
Mike Stump11289f42009-09-09 15:08:12 +00005391
5392 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005393 // used during overload resolution.
5394 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005395
Douglas Gregora16548e2009-08-11 05:31:07 +00005396 // FIXME: Do we have to check
5397 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005398 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005399 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005400
Douglas Gregora16548e2009-08-11 05:31:07 +00005401 // Add any functions found via argument-dependent lookup.
5402 Expr *Args[2] = { FirstExpr, SecondExpr };
5403 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005404 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005405 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redlc057f422009-10-23 19:23:15 +00005406 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5407 Functions);
Mike Stump11289f42009-09-09 15:08:12 +00005408
Douglas Gregora16548e2009-08-11 05:31:07 +00005409 // Create the overloaded operator invocation for unary operators.
5410 if (NumArgs == 1 || isPostIncDec) {
Mike Stump11289f42009-09-09 15:08:12 +00005411 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005412 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5413 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5414 }
Mike Stump11289f42009-09-09 15:08:12 +00005415
Sebastian Redladba46e2009-10-29 20:17:01 +00005416 if (Op == OO_Subscript)
5417 return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
5418 move(First),move(Second));
5419
Douglas Gregora16548e2009-08-11 05:31:07 +00005420 // Create the overloaded operator invocation for binary operators.
Mike Stump11289f42009-09-09 15:08:12 +00005421 BinaryOperator::Opcode Opc =
Douglas Gregora16548e2009-08-11 05:31:07 +00005422 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005423 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005424 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5425 if (Result.isInvalid())
5426 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005427
Douglas Gregora16548e2009-08-11 05:31:07 +00005428 First.release();
5429 Second.release();
Mike Stump11289f42009-09-09 15:08:12 +00005430 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00005431}
Mike Stump11289f42009-09-09 15:08:12 +00005432
Douglas Gregord6ff3322009-08-04 16:50:30 +00005433} // end namespace clang
5434
5435#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H