blob: d19653d157c3b37fe0c1c52378832da5b512dd26 [file] [log] [blame]
Douglas Gregor577f75a2009-08-04 16:50:30 +00001//===------- TreeTransform.h - Semantic Tree Transformation ---------------===/
2//
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 Gregordcee1a12009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregorc68afe22009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor657c1ac2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregor43959a92009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000025#include "clang/Parse/Ownership.h"
26#include "clang/Parse/Designator.h"
27#include "clang/Lex/Preprocessor.h"
Douglas Gregor577f75a2009-08-04 16:50:30 +000028#include <algorithm>
29
30namespace clang {
31
32/// \brief A semantic tree transformation that allows one to transform one
33/// abstract syntax tree into another.
34///
35/// A new tree transformation is defined by creating a new subclass \c X of
36/// \c TreeTransform<X> and then overriding certain operations to provide
37/// behavior specific to that transformation. For example, template
38/// instantiation is implemented as a tree transformation where the
39/// transformation of TemplateTypeParmType nodes involves substituting the
40/// template arguments for their corresponding template parameters; a similar
41/// transformation is performed for non-type template parameters and
42/// template template parameters.
43///
44/// This tree-transformation template uses static polymorphism to allow
45/// subclasses to customize any of its operations. Thus, a subclass can
46/// override any of the transformation or rebuild operators by providing an
47/// operation with the same signature as the default implementation. The
48/// overridding function should not be virtual.
49///
50/// Semantic tree transformations are split into two stages, either of which
51/// can be replaced by a subclass. The "transform" step transforms an AST node
52/// or the parts of an AST node using the various transformation functions,
53/// then passes the pieces on to the "rebuild" step, which constructs a new AST
54/// node of the appropriate kind from the pieces. The default transformation
55/// routines recursively transform the operands to composite AST nodes (e.g.,
56/// the pointee type of a PointerType node) and, if any of those operand nodes
57/// were changed by the transformation, invokes the rebuild operation to create
58/// a new AST node.
59///
60/// Subclasses can customize the transformation at various levels. The
Douglas Gregor670444e2009-08-04 22:27:00 +000061/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor577f75a2009-08-04 16:50:30 +000062/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
63/// TransformTemplateName(), or TransformTemplateArgument() with entirely
64/// new implementations.
65///
66/// For more fine-grained transformations, subclasses can replace any of the
67/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
Douglas Gregor43959a92009-08-20 07:17:43 +000068/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregor577f75a2009-08-04 16:50:30 +000069/// replacing TransformTemplateTypeParmType() allows template instantiation
70/// to substitute template arguments for their corresponding template
71/// parameters. Additionally, subclasses can override the \c RebuildXXX
72/// functions to control how AST nodes are rebuilt when their operands change.
73/// By default, \c TreeTransform will invoke semantic analysis to rebuild
74/// AST nodes. However, certain other tree transformations (e.g, cloning) may
75/// be able to use more efficient rebuild steps.
76///
77/// There are a handful of other functions that can be overridden, allowing one
78/// to avoid traversing nodes that don't need any transformation
79/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
80/// operands have not changed (\c AlwaysRebuild()), and customize the
81/// default locations and entity names used for type-checking
82/// (\c getBaseLocation(), \c getBaseEntity()).
Douglas Gregor577f75a2009-08-04 16:50:30 +000083template<typename Derived>
84class TreeTransform {
85protected:
86 Sema &SemaRef;
87
88public:
Douglas Gregorb98b1992009-08-11 05:31:07 +000089 typedef Sema::OwningStmtResult OwningStmtResult;
90 typedef Sema::OwningExprResult OwningExprResult;
91 typedef Sema::StmtArg StmtArg;
92 typedef Sema::ExprArg ExprArg;
93 typedef Sema::MultiExprArg MultiExprArg;
Douglas Gregor43959a92009-08-20 07:17:43 +000094 typedef Sema::MultiStmtArg MultiStmtArg;
Douglas Gregorb98b1992009-08-11 05:31:07 +000095
Douglas Gregor577f75a2009-08-04 16:50:30 +000096 /// \brief Initializes a new tree transformer.
97 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
98
99 /// \brief Retrieves a reference to the derived class.
100 Derived &getDerived() { return static_cast<Derived&>(*this); }
101
102 /// \brief Retrieves a reference to the derived class.
103 const Derived &getDerived() const {
104 return static_cast<const Derived&>(*this);
105 }
106
107 /// \brief Retrieves a reference to the semantic analysis object used for
108 /// this tree transform.
109 Sema &getSema() const { return SemaRef; }
110
111 /// \brief Whether the transformation should always rebuild AST nodes, even
112 /// if none of the children have changed.
113 ///
114 /// Subclasses may override this function to specify when the transformation
115 /// should rebuild all AST nodes.
116 bool AlwaysRebuild() { return false; }
117
118 /// \brief Returns the location of the entity being transformed, if that
119 /// information was not available elsewhere in the AST.
120 ///
121 /// By default, returns no source-location information. Subclasses can
122 /// provide an alternative implementation that provides better location
123 /// information.
124 SourceLocation getBaseLocation() { return SourceLocation(); }
125
126 /// \brief Returns the name of the entity being transformed, if that
127 /// information was not available elsewhere in the AST.
128 ///
129 /// By default, returns an empty name. Subclasses can provide an alternative
130 /// implementation with a more precise name.
131 DeclarationName getBaseEntity() { return DeclarationName(); }
132
Douglas Gregorb98b1992009-08-11 05:31:07 +0000133 /// \brief Sets the "base" location and entity when that
134 /// information is known based on another transformation.
135 ///
136 /// By default, the source location and entity are ignored. Subclasses can
137 /// override this function to provide a customized implementation.
138 void setBase(SourceLocation Loc, DeclarationName Entity) { }
139
140 /// \brief RAII object that temporarily sets the base location and entity
141 /// used for reporting diagnostics in types.
142 class TemporaryBase {
143 TreeTransform &Self;
144 SourceLocation OldLocation;
145 DeclarationName OldEntity;
146
147 public:
148 TemporaryBase(TreeTransform &Self, SourceLocation Location,
149 DeclarationName Entity) : Self(Self)
150 {
151 OldLocation = Self.getDerived().getBaseLocation();
152 OldEntity = Self.getDerived().getBaseEntity();
153 Self.getDerived().setBase(Location, Entity);
154 }
155
156 ~TemporaryBase() {
157 Self.getDerived().setBase(OldLocation, OldEntity);
158 }
159 };
160
Douglas Gregor577f75a2009-08-04 16:50:30 +0000161 /// \brief Determine whether the given type \p T has already been
162 /// transformed.
163 ///
164 /// Subclasses can provide an alternative implementation of this routine
165 /// to short-circuit evaluation when it is known that a given type will
166 /// not change. For example, template instantiation need not traverse
167 /// non-dependent types.
168 bool AlreadyTransformed(QualType T) {
169 return T.isNull();
170 }
171
172 /// \brief Transforms the given type into another type.
173 ///
174 /// By default, this routine transforms a type by delegating to the
175 /// appropriate TransformXXXType to build a new type, then applying
176 /// the qualifiers on \p T to the resulting type with AddTypeQualifiers.
177 /// Subclasses may override this function (to take over all type
178 /// transformations), some set of the TransformXXXType functions, or
179 /// the AddTypeQualifiers function to alter the transformation.
180 ///
181 /// \returns the transformed type.
182 QualType TransformType(QualType T);
183
184 /// \brief Transform the given type by adding the given set of qualifiers
185 /// and returning the result.
186 ///
187 /// FIXME: By default, this routine adds type qualifiers only to types that
188 /// can have qualifiers, and silently suppresses those qualifiers that are
189 /// not permitted (e.g., qualifiers on reference or function types). This
190 /// is the right thing for template instantiation, but probably not for
191 /// other clients.
192 QualType AddTypeQualifiers(QualType T, unsigned CVRQualifiers);
193
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000194 /// \brief Transform the given statement.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000195 ///
Douglas Gregor43959a92009-08-20 07:17:43 +0000196 /// By default, this routine transforms a statement by delegating to the
197 /// appropriate TransformXXXStmt function to transform a specific kind of
198 /// statement or the TransformExpr() function to transform an expression.
199 /// Subclasses may override this function to transform statements using some
200 /// other mechanism.
201 ///
202 /// \returns the transformed statement.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000203 OwningStmtResult TransformStmt(Stmt *S);
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000204
205 /// \brief Transform the given expression.
206 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000207 /// By default, this routine transforms an expression by delegating to the
208 /// appropriate TransformXXXExpr function to build a new expression.
209 /// Subclasses may override this function to transform expressions using some
210 /// other mechanism.
211 ///
212 /// \returns the transformed expression.
213 OwningExprResult TransformExpr(Expr *E) {
214 return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
215 }
216
217 /// \brief Transform the given expression.
218 ///
219 /// By default, this routine transforms an expression by delegating to the
220 /// appropriate TransformXXXExpr function to build a new expression.
221 /// Subclasses may override this function to transform expressions using some
222 /// other mechanism.
223 ///
224 /// \returns the transformed expression.
225 OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000226
227 /// \brief Transform the given declaration, which is referenced from a type
228 /// or expression.
229 ///
Douglas Gregordcee1a12009-08-06 05:28:30 +0000230 /// By default, acts as the identity function on declarations. Subclasses
231 /// may override this function to provide alternate behavior.
232 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregor43959a92009-08-20 07:17:43 +0000233
234 /// \brief Transform the definition of the given declaration.
235 ///
236 /// By default, invokes TransformDecl() to transform the declaration.
237 /// Subclasses may override this function to provide alternate behavior.
238 Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000239
240 /// \brief Transform the given nested-name-specifier.
241 ///
Douglas Gregordcee1a12009-08-06 05:28:30 +0000242 /// By default, transforms all of the types and declarations within the
243 /// nested-name-specifier. Subclasses may override this function to provide
244 /// alternate behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000245 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +0000246 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000247 QualType ObjectType = QualType(),
248 NamedDecl *FirstQualifierInScope = 0);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000249
Douglas Gregor81499bb2009-09-03 22:13:48 +0000250 /// \brief Transform the given declaration name.
251 ///
252 /// By default, transforms the types of conversion function, constructor,
253 /// and destructor names and then (if needed) rebuilds the declaration name.
254 /// Identifiers and selectors are returned unmodified. Sublcasses may
255 /// override this function to provide alternate behavior.
256 DeclarationName TransformDeclarationName(DeclarationName Name,
257 SourceLocation Loc);
258
Douglas Gregor577f75a2009-08-04 16:50:30 +0000259 /// \brief Transform the given template name.
260 ///
Douglas Gregord1067e52009-08-06 06:41:21 +0000261 /// By default, transforms the template name by transforming the declarations
262 /// and nested-name-specifiers that occur within the template name.
263 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000264 TemplateName TransformTemplateName(TemplateName Name,
265 QualType ObjectType = QualType());
Douglas Gregor577f75a2009-08-04 16:50:30 +0000266
267 /// \brief Transform the given template argument.
268 ///
Douglas Gregor670444e2009-08-04 22:27:00 +0000269 /// By default, this operation transforms the type, expression, or
270 /// declaration stored within the template argument and constructs a
271 /// new template argument from the transformed result. Subclasses may
272 /// override this function to provide alternate behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000273 TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
274
275#define ABSTRACT_TYPE(CLASS, PARENT)
276#define TYPE(CLASS, PARENT) \
277 QualType Transform##CLASS##Type(const CLASS##Type *T);
278#include "clang/AST/TypeNodes.def"
279
Douglas Gregor43959a92009-08-20 07:17:43 +0000280 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000281
Douglas Gregor43959a92009-08-20 07:17:43 +0000282#define STMT(Node, Parent) \
283 OwningStmtResult Transform##Node(Node *S);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000284#define EXPR(Node, Parent) \
285 OwningExprResult Transform##Node(Node *E);
286#define ABSTRACT_EXPR(Node, Parent)
287#include "clang/AST/StmtNodes.def"
288
Douglas Gregor577f75a2009-08-04 16:50:30 +0000289 /// \brief Build a new pointer type given its pointee type.
290 ///
291 /// By default, performs semantic analysis when building the pointer type.
292 /// Subclasses may override this routine to provide different behavior.
293 QualType RebuildPointerType(QualType PointeeType);
294
295 /// \brief Build a new block pointer type given its pointee type.
296 ///
297 /// By default, performs semantic analysis when building the block pointer
298 /// type. Subclasses may override this routine to provide different behavior.
299 QualType RebuildBlockPointerType(QualType PointeeType);
300
301 /// \brief Build a new lvalue reference type given the type it references.
302 ///
303 /// By default, performs semantic analysis when building the lvalue reference
304 /// type. Subclasses may override this routine to provide different behavior.
305 QualType RebuildLValueReferenceType(QualType ReferentType);
306
307 /// \brief Build a new rvalue reference type given the type it references.
308 ///
309 /// By default, performs semantic analysis when building the rvalue reference
310 /// type. Subclasses may override this routine to provide different behavior.
311 QualType RebuildRValueReferenceType(QualType ReferentType);
312
313 /// \brief Build a new member pointer type given the pointee type and the
314 /// class type it refers into.
315 ///
316 /// By default, performs semantic analysis when building the member pointer
317 /// type. Subclasses may override this routine to provide different behavior.
318 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
319
320 /// \brief Build a new array type given the element type, size
321 /// modifier, size of the array (if known), size expression, and index type
322 /// qualifiers.
323 ///
324 /// By default, performs semantic analysis when building the array type.
325 /// Subclasses may override this routine to provide different behavior.
326 /// Also by default, all of the other Rebuild*Array
327 QualType RebuildArrayType(QualType ElementType,
328 ArrayType::ArraySizeModifier SizeMod,
329 const llvm::APInt *Size,
330 Expr *SizeExpr,
331 unsigned IndexTypeQuals,
332 SourceRange BracketsRange);
333
334 /// \brief Build a new constant array type given the element type, size
335 /// modifier, (known) size of the array, and index type qualifiers.
336 ///
337 /// By default, performs semantic analysis when building the array type.
338 /// Subclasses may override this routine to provide different behavior.
339 QualType RebuildConstantArrayType(QualType ElementType,
340 ArrayType::ArraySizeModifier SizeMod,
341 const llvm::APInt &Size,
342 unsigned IndexTypeQuals);
343
344 /// \brief Build a new constant array type given the element type, size
345 /// modifier, (known) size of the array, size expression, and index type
346 /// qualifiers.
347 ///
348 /// By default, performs semantic analysis when building the array type.
349 /// Subclasses may override this routine to provide different behavior.
350 QualType RebuildConstantArrayWithExprType(QualType ElementType,
351 ArrayType::ArraySizeModifier SizeMod,
352 const llvm::APInt &Size,
353 Expr *SizeExpr,
354 unsigned IndexTypeQuals,
355 SourceRange BracketsRange);
356
357 /// \brief Build a new constant array type given the element type, size
358 /// modifier, (known) size of the array, and index type qualifiers.
359 ///
360 /// By default, performs semantic analysis when building the array type.
361 /// Subclasses may override this routine to provide different behavior.
362 QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
363 ArrayType::ArraySizeModifier SizeMod,
364 const llvm::APInt &Size,
365 unsigned IndexTypeQuals);
366
367 /// \brief Build a new incomplete array type given the element type, size
368 /// modifier, and index type qualifiers.
369 ///
370 /// By default, performs semantic analysis when building the array type.
371 /// Subclasses may override this routine to provide different behavior.
372 QualType RebuildIncompleteArrayType(QualType ElementType,
373 ArrayType::ArraySizeModifier SizeMod,
374 unsigned IndexTypeQuals);
375
376 /// \brief Build a new variable-length array type given the element type,
377 /// size modifier, size expression, and index type qualifiers.
378 ///
379 /// By default, performs semantic analysis when building the array type.
380 /// Subclasses may override this routine to provide different behavior.
381 QualType RebuildVariableArrayType(QualType ElementType,
382 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000383 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000384 unsigned IndexTypeQuals,
385 SourceRange BracketsRange);
386
387 /// \brief Build a new dependent-sized array type given the element type,
388 /// size modifier, size expression, and index type qualifiers.
389 ///
390 /// By default, performs semantic analysis when building the array type.
391 /// Subclasses may override this routine to provide different behavior.
392 QualType RebuildDependentSizedArrayType(QualType ElementType,
393 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000394 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000395 unsigned IndexTypeQuals,
396 SourceRange BracketsRange);
397
398 /// \brief Build a new vector type given the element type and
399 /// number of elements.
400 ///
401 /// By default, performs semantic analysis when building the vector type.
402 /// Subclasses may override this routine to provide different behavior.
403 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
404
405 /// \brief Build a new extended vector type given the element type and
406 /// number of elements.
407 ///
408 /// By default, performs semantic analysis when building the vector type.
409 /// Subclasses may override this routine to provide different behavior.
410 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
411 SourceLocation AttributeLoc);
412
413 /// \brief Build a new potentially dependently-sized extended vector type
414 /// given the element type and number of elements.
415 ///
416 /// By default, performs semantic analysis when building the vector type.
417 /// Subclasses may override this routine to provide different behavior.
418 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000419 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000420 SourceLocation AttributeLoc);
421
422 /// \brief Build a new function type.
423 ///
424 /// By default, performs semantic analysis when building the function type.
425 /// Subclasses may override this routine to provide different behavior.
426 QualType RebuildFunctionProtoType(QualType T,
427 QualType *ParamTypes,
428 unsigned NumParamTypes,
429 bool Variadic, unsigned Quals);
430
431 /// \brief Build a new typedef type.
432 QualType RebuildTypedefType(TypedefDecl *Typedef) {
433 return SemaRef.Context.getTypeDeclType(Typedef);
434 }
435
436 /// \brief Build a new class/struct/union type.
437 QualType RebuildRecordType(RecordDecl *Record) {
438 return SemaRef.Context.getTypeDeclType(Record);
439 }
440
441 /// \brief Build a new Enum type.
442 QualType RebuildEnumType(EnumDecl *Enum) {
443 return SemaRef.Context.getTypeDeclType(Enum);
444 }
John McCall7da24312009-09-05 00:15:47 +0000445
446 /// \brief Build a new elaborated type.
447 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
448 return SemaRef.Context.getElaboratedType(T, Tag);
449 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000450
451 /// \brief Build a new typeof(expr) type.
452 ///
453 /// By default, performs semantic analysis when building the typeof type.
454 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000455 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000456
457 /// \brief Build a new typeof(type) type.
458 ///
459 /// By default, builds a new TypeOfType with the given underlying type.
460 QualType RebuildTypeOfType(QualType Underlying);
461
462 /// \brief Build a new C++0x decltype type.
463 ///
464 /// By default, performs semantic analysis when building the decltype type.
465 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000466 QualType RebuildDecltypeType(ExprArg Underlying);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000467
468 /// \brief Build a new template specialization type.
469 ///
470 /// By default, performs semantic analysis when building the template
471 /// specialization type. Subclasses may override this routine to provide
472 /// different behavior.
473 QualType RebuildTemplateSpecializationType(TemplateName Template,
474 const TemplateArgument *Args,
475 unsigned NumArgs);
476
477 /// \brief Build a new qualified name type.
478 ///
479 /// By default, builds a new QualifiedNameType type from the
480 /// nested-name-specifier and the named type. Subclasses may override
481 /// this routine to provide different behavior.
482 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
483 return SemaRef.Context.getQualifiedNameType(NNS, Named);
484 }
485
486 /// \brief Build a new typename type that refers to a template-id.
487 ///
488 /// By default, builds a new TypenameType type from the nested-name-specifier
489 /// and the given type. Subclasses may override this routine to provide
490 /// different behavior.
491 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
492 if (NNS->isDependent())
493 return SemaRef.Context.getTypenameType(NNS,
494 cast<TemplateSpecializationType>(T));
495
496 return SemaRef.Context.getQualifiedNameType(NNS, T);
497 }
498
499 /// \brief Build a new typename type that refers to an identifier.
500 ///
501 /// By default, performs semantic analysis when building the typename type
502 /// (or qualified name type). Subclasses may override this routine to provide
503 /// different behavior.
504 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
505 const IdentifierInfo *Id) {
506 return SemaRef.CheckTypenameType(NNS, *Id,
507 SourceRange(getDerived().getBaseLocation()));
Douglas Gregordcee1a12009-08-06 05:28:30 +0000508 }
509
510 /// \brief Build a new nested-name-specifier given the prefix and an
511 /// identifier that names the next step in the nested-name-specifier.
512 ///
513 /// By default, performs semantic analysis when building the new
514 /// nested-name-specifier. Subclasses may override this routine to provide
515 /// different behavior.
516 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
517 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +0000518 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000519 QualType ObjectType,
520 NamedDecl *FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000521
522 /// \brief Build a new nested-name-specifier given the prefix and the
523 /// namespace named in the next step in the nested-name-specifier.
524 ///
525 /// By default, performs semantic analysis when building the new
526 /// nested-name-specifier. Subclasses may override this routine to provide
527 /// different behavior.
528 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
529 SourceRange Range,
530 NamespaceDecl *NS);
531
532 /// \brief Build a new nested-name-specifier given the prefix and the
533 /// type named in the next step in the nested-name-specifier.
534 ///
535 /// By default, performs semantic analysis when building the new
536 /// nested-name-specifier. Subclasses may override this routine to provide
537 /// different behavior.
538 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
539 SourceRange Range,
540 bool TemplateKW,
541 QualType T);
Douglas Gregord1067e52009-08-06 06:41:21 +0000542
543 /// \brief Build a new template name given a nested name specifier, a flag
544 /// indicating whether the "template" keyword was provided, and the template
545 /// that the template name refers to.
546 ///
547 /// By default, builds the new template name directly. Subclasses may override
548 /// this routine to provide different behavior.
549 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
550 bool TemplateKW,
551 TemplateDecl *Template);
552
553 /// \brief Build a new template name given a nested name specifier, a flag
554 /// indicating whether the "template" keyword was provided, and a set of
555 /// overloaded function templates.
556 ///
557 /// By default, builds the new template name directly. Subclasses may override
558 /// this routine to provide different behavior.
559 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
560 bool TemplateKW,
561 OverloadedFunctionDecl *Ovl);
562
563 /// \brief Build a new template name given a nested name specifier and the
564 /// name that is referred to as a template.
565 ///
566 /// By default, performs semantic analysis to determine whether the name can
567 /// be resolved to a specific template, then builds the appropriate kind of
568 /// template name. Subclasses may override this routine to provide different
569 /// behavior.
570 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000571 const IdentifierInfo &II,
572 QualType ObjectType);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000573
574
Douglas Gregor43959a92009-08-20 07:17:43 +0000575 /// \brief Build a new compound statement.
576 ///
577 /// By default, performs semantic analysis to build the new statement.
578 /// Subclasses may override this routine to provide different behavior.
579 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
580 MultiStmtArg Statements,
581 SourceLocation RBraceLoc,
582 bool IsStmtExpr) {
583 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
584 IsStmtExpr);
585 }
586
587 /// \brief Build a new case statement.
588 ///
589 /// By default, performs semantic analysis to build the new statement.
590 /// Subclasses may override this routine to provide different behavior.
591 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
592 ExprArg LHS,
593 SourceLocation EllipsisLoc,
594 ExprArg RHS,
595 SourceLocation ColonLoc) {
596 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
597 ColonLoc);
598 }
599
600 /// \brief Attach the body to a new case statement.
601 ///
602 /// By default, performs semantic analysis to build the new statement.
603 /// Subclasses may override this routine to provide different behavior.
604 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
605 getSema().ActOnCaseStmtBody(S.get(), move(Body));
606 return move(S);
607 }
608
609 /// \brief Build a new default statement.
610 ///
611 /// By default, performs semantic analysis to build the new statement.
612 /// Subclasses may override this routine to provide different behavior.
613 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
614 SourceLocation ColonLoc,
615 StmtArg SubStmt) {
616 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
617 /*CurScope=*/0);
618 }
619
620 /// \brief Build a new label statement.
621 ///
622 /// By default, performs semantic analysis to build the new statement.
623 /// Subclasses may override this routine to provide different behavior.
624 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
625 IdentifierInfo *Id,
626 SourceLocation ColonLoc,
627 StmtArg SubStmt) {
628 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
629 }
630
631 /// \brief Build a new "if" 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 RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
636 StmtArg Then, SourceLocation ElseLoc,
637 StmtArg Else) {
638 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
639 }
640
641 /// \brief Start building a new switch statement.
642 ///
643 /// By default, performs semantic analysis to build the new statement.
644 /// Subclasses may override this routine to provide different behavior.
645 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
646 return getSema().ActOnStartOfSwitchStmt(move(Cond));
647 }
648
649 /// \brief Attach the body to the switch statement.
650 ///
651 /// By default, performs semantic analysis to build the new statement.
652 /// Subclasses may override this routine to provide different behavior.
653 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
654 StmtArg Switch, StmtArg Body) {
655 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
656 move(Body));
657 }
658
659 /// \brief Build a new while statement.
660 ///
661 /// By default, performs semantic analysis to build the new statement.
662 /// Subclasses may override this routine to provide different behavior.
663 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
664 Sema::FullExprArg Cond,
665 StmtArg Body) {
666 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
667 }
668
669 /// \brief Build a new do-while statement.
670 ///
671 /// By default, performs semantic analysis to build the new statement.
672 /// Subclasses may override this routine to provide different behavior.
673 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
674 SourceLocation WhileLoc,
675 SourceLocation LParenLoc,
676 ExprArg Cond,
677 SourceLocation RParenLoc) {
678 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
679 move(Cond), RParenLoc);
680 }
681
682 /// \brief Build a new for statement.
683 ///
684 /// By default, performs semantic analysis to build the new statement.
685 /// Subclasses may override this routine to provide different behavior.
686 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
687 SourceLocation LParenLoc,
688 StmtArg Init, ExprArg Cond, ExprArg Inc,
689 SourceLocation RParenLoc, StmtArg Body) {
690 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
691 move(Inc), RParenLoc, move(Body));
692 }
693
694 /// \brief Build a new goto statement.
695 ///
696 /// By default, performs semantic analysis to build the new statement.
697 /// Subclasses may override this routine to provide different behavior.
698 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
699 SourceLocation LabelLoc,
700 LabelStmt *Label) {
701 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
702 }
703
704 /// \brief Build a new indirect goto statement.
705 ///
706 /// By default, performs semantic analysis to build the new statement.
707 /// Subclasses may override this routine to provide different behavior.
708 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
709 SourceLocation StarLoc,
710 ExprArg Target) {
711 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
712 }
713
714 /// \brief Build a new return statement.
715 ///
716 /// By default, performs semantic analysis to build the new statement.
717 /// Subclasses may override this routine to provide different behavior.
718 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
719 ExprArg Result) {
720
721 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
722 }
723
724 /// \brief Build a new declaration statement.
725 ///
726 /// By default, performs semantic analysis to build the new statement.
727 /// Subclasses may override this routine to provide different behavior.
728 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
729 SourceLocation StartLoc,
730 SourceLocation EndLoc) {
731 return getSema().Owned(
732 new (getSema().Context) DeclStmt(
733 DeclGroupRef::Create(getSema().Context,
734 Decls, NumDecls),
735 StartLoc, EndLoc));
736 }
737
738 /// \brief Build a new C++ exception declaration.
739 ///
740 /// By default, performs semantic analysis to build the new decaration.
741 /// Subclasses may override this routine to provide different behavior.
742 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
743 DeclaratorInfo *Declarator,
744 IdentifierInfo *Name,
745 SourceLocation Loc,
746 SourceRange TypeRange) {
747 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
748 TypeRange);
749 }
750
751 /// \brief Build a new C++ catch statement.
752 ///
753 /// By default, performs semantic analysis to build the new statement.
754 /// Subclasses may override this routine to provide different behavior.
755 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
756 VarDecl *ExceptionDecl,
757 StmtArg Handler) {
758 return getSema().Owned(
759 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
760 Handler.takeAs<Stmt>()));
761 }
762
763 /// \brief Build a new C++ try statement.
764 ///
765 /// By default, performs semantic analysis to build the new statement.
766 /// Subclasses may override this routine to provide different behavior.
767 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
768 StmtArg TryBlock,
769 MultiStmtArg Handlers) {
770 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
771 }
772
Douglas Gregorb98b1992009-08-11 05:31:07 +0000773 /// \brief Build a new expression that references a declaration.
774 ///
775 /// By default, performs semantic analysis to build the new expression.
776 /// Subclasses may override this routine to provide different behavior.
777 OwningExprResult RebuildDeclRefExpr(NamedDecl *ND, SourceLocation Loc) {
778 return getSema().BuildDeclarationNameExpr(Loc, ND,
779 /*FIXME:*/false,
780 /*SS=*/0,
781 /*FIXME:*/false);
782 }
783
784 /// \brief Build a new expression in parentheses.
785 ///
786 /// By default, performs semantic analysis to build the new expression.
787 /// Subclasses may override this routine to provide different behavior.
788 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
789 SourceLocation RParen) {
790 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
791 }
792
Douglas Gregora71d8192009-09-04 17:36:40 +0000793 /// \brief Build a new pseudo-destructor expression.
794 ///
795 /// By default, performs semantic analysis to build the new expression.
796 /// Subclasses may override this routine to provide different behavior.
797 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
798 SourceLocation OperatorLoc,
799 bool isArrow,
800 SourceLocation DestroyedTypeLoc,
801 QualType DestroyedType,
802 NestedNameSpecifier *Qualifier,
803 SourceRange QualifierRange) {
804 CXXScopeSpec SS;
805 if (Qualifier) {
806 SS.setRange(QualifierRange);
807 SS.setScopeRep(Qualifier);
808 }
809
810 DeclarationName Name
811 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
812 SemaRef.Context.getCanonicalType(DestroyedType));
813
814 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
815 OperatorLoc,
816 isArrow? tok::arrow : tok::period,
817 DestroyedTypeLoc,
818 Name,
819 Sema::DeclPtrTy::make((Decl *)0),
820 &SS);
821 }
822
Douglas Gregorb98b1992009-08-11 05:31:07 +0000823 /// \brief Build a new unary operator expression.
824 ///
825 /// By default, performs semantic analysis to build the new expression.
826 /// Subclasses may override this routine to provide different behavior.
827 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
828 UnaryOperator::Opcode Opc,
829 ExprArg SubExpr) {
830 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
831 }
832
833 /// \brief Build a new sizeof or alignof expression with a type argument.
834 ///
835 /// By default, performs semantic analysis to build the new expression.
836 /// Subclasses may override this routine to provide different behavior.
837 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
838 bool isSizeOf, SourceRange R) {
839 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
840 }
841
842 /// \brief Build a new sizeof or alignof expression with an expression
843 /// argument.
844 ///
845 /// By default, performs semantic analysis to build the new expression.
846 /// Subclasses may override this routine to provide different behavior.
847 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
848 bool isSizeOf, SourceRange R) {
849 OwningExprResult Result
850 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
851 OpLoc, isSizeOf, R);
852 if (Result.isInvalid())
853 return getSema().ExprError();
854
855 SubExpr.release();
856 return move(Result);
857 }
858
859 /// \brief Build a new array subscript expression.
860 ///
861 /// By default, performs semantic analysis to build the new expression.
862 /// Subclasses may override this routine to provide different behavior.
863 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
864 SourceLocation LBracketLoc,
865 ExprArg RHS,
866 SourceLocation RBracketLoc) {
867 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
868 LBracketLoc, move(RHS),
869 RBracketLoc);
870 }
871
872 /// \brief Build a new call expression.
873 ///
874 /// By default, performs semantic analysis to build the new expression.
875 /// Subclasses may override this routine to provide different behavior.
876 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
877 MultiExprArg Args,
878 SourceLocation *CommaLocs,
879 SourceLocation RParenLoc) {
880 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
881 move(Args), CommaLocs, RParenLoc);
882 }
883
884 /// \brief Build a new member access expression.
885 ///
886 /// By default, performs semantic analysis to build the new expression.
887 /// Subclasses may override this routine to provide different behavior.
888 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000889 bool isArrow,
890 NestedNameSpecifier *Qualifier,
891 SourceRange QualifierRange,
892 SourceLocation MemberLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000893 NamedDecl *Member) {
Anders Carlssond8b285f2009-09-01 04:26:58 +0000894 if (!Member->getDeclName()) {
895 // We have a reference to an unnamed field.
896 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
897
898 MemberExpr *ME =
899 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
900 Member, MemberLoc,
901 cast<FieldDecl>(Member)->getType());
902 return getSema().Owned(ME);
903 }
904
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000905 CXXScopeSpec SS;
906 if (Qualifier) {
907 SS.setRange(QualifierRange);
908 SS.setScopeRep(Qualifier);
909 }
910
Douglas Gregor017dde52009-08-31 20:00:26 +0000911 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000912 isArrow? tok::arrow : tok::period,
913 MemberLoc,
Douglas Gregor017dde52009-08-31 20:00:26 +0000914 Member->getDeclName(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000915 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
916 &SS);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000917 }
918
919 /// \brief Build a new binary operator expression.
920 ///
921 /// By default, performs semantic analysis to build the new expression.
922 /// Subclasses may override this routine to provide different behavior.
923 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
924 BinaryOperator::Opcode Opc,
925 ExprArg LHS, ExprArg RHS) {
926 OwningExprResult Result
927 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
928 (Expr *)RHS.get());
929 if (Result.isInvalid())
930 return SemaRef.ExprError();
931
932 LHS.release();
933 RHS.release();
934 return move(Result);
935 }
936
937 /// \brief Build a new conditional operator expression.
938 ///
939 /// By default, performs semantic analysis to build the new expression.
940 /// Subclasses may override this routine to provide different behavior.
941 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
942 SourceLocation QuestionLoc,
943 ExprArg LHS,
944 SourceLocation ColonLoc,
945 ExprArg RHS) {
946 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
947 move(LHS), move(RHS));
948 }
949
950 /// \brief Build a new implicit cast expression.
951 ///
952 /// By default, builds a new implicit cast without any semantic analysis.
953 /// Subclasses may override this routine to provide different behavior.
954 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
955 ExprArg SubExpr, bool isLvalue) {
956 ImplicitCastExpr *ICE
957 = new (getSema().Context) ImplicitCastExpr(T, Kind,
958 (Expr *)SubExpr.release(),
959 isLvalue);
960 return getSema().Owned(ICE);
961 }
962
963 /// \brief Build a new C-style cast expression.
964 ///
965 /// By default, performs semantic analysis to build the new expression.
966 /// Subclasses may override this routine to provide different behavior.
967 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
968 QualType ExplicitTy,
969 SourceLocation RParenLoc,
970 ExprArg SubExpr) {
971 return getSema().ActOnCastExpr(/*Scope=*/0,
972 LParenLoc,
973 ExplicitTy.getAsOpaquePtr(),
974 RParenLoc,
975 move(SubExpr));
976 }
977
978 /// \brief Build a new compound literal expression.
979 ///
980 /// By default, performs semantic analysis to build the new expression.
981 /// Subclasses may override this routine to provide different behavior.
982 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
983 QualType T,
984 SourceLocation RParenLoc,
985 ExprArg Init) {
986 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
987 RParenLoc, move(Init));
988 }
989
990 /// \brief Build a new extended vector element access expression.
991 ///
992 /// By default, performs semantic analysis to build the new expression.
993 /// Subclasses may override this routine to provide different behavior.
994 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
995 SourceLocation OpLoc,
996 SourceLocation AccessorLoc,
997 IdentifierInfo &Accessor) {
998 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
999 tok::period, AccessorLoc,
1000 Accessor,
1001 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1002 }
1003
1004 /// \brief Build a new initializer list expression.
1005 ///
1006 /// By default, performs semantic analysis to build the new expression.
1007 /// Subclasses may override this routine to provide different behavior.
1008 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1009 MultiExprArg Inits,
1010 SourceLocation RBraceLoc) {
1011 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1012 }
1013
1014 /// \brief Build a new designated initializer expression.
1015 ///
1016 /// By default, performs semantic analysis to build the new expression.
1017 /// Subclasses may override this routine to provide different behavior.
1018 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1019 MultiExprArg ArrayExprs,
1020 SourceLocation EqualOrColonLoc,
1021 bool GNUSyntax,
1022 ExprArg Init) {
1023 OwningExprResult Result
1024 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1025 move(Init));
1026 if (Result.isInvalid())
1027 return SemaRef.ExprError();
1028
1029 ArrayExprs.release();
1030 return move(Result);
1031 }
1032
1033 /// \brief Build a new value-initialized expression.
1034 ///
1035 /// By default, builds the implicit value initialization without performing
1036 /// any semantic analysis. Subclasses may override this routine to provide
1037 /// different behavior.
1038 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1039 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1040 }
1041
1042 /// \brief Build a new \c va_arg expression.
1043 ///
1044 /// By default, performs semantic analysis to build the new expression.
1045 /// Subclasses may override this routine to provide different behavior.
1046 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1047 QualType T, SourceLocation RParenLoc) {
1048 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
1049 RParenLoc);
1050 }
1051
1052 /// \brief Build a new expression list in parentheses.
1053 ///
1054 /// By default, performs semantic analysis to build the new expression.
1055 /// Subclasses may override this routine to provide different behavior.
1056 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1057 MultiExprArg SubExprs,
1058 SourceLocation RParenLoc) {
1059 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1060 }
1061
1062 /// \brief Build a new address-of-label expression.
1063 ///
1064 /// By default, performs semantic analysis, using the name of the label
1065 /// rather than attempting to map the label statement itself.
1066 /// Subclasses may override this routine to provide different behavior.
1067 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1068 SourceLocation LabelLoc,
1069 LabelStmt *Label) {
1070 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1071 }
1072
1073 /// \brief Build a new GNU statement expression.
1074 ///
1075 /// By default, performs semantic analysis to build the new expression.
1076 /// Subclasses may override this routine to provide different behavior.
1077 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1078 StmtArg SubStmt,
1079 SourceLocation RParenLoc) {
1080 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1081 }
1082
1083 /// \brief Build a new __builtin_types_compatible_p expression.
1084 ///
1085 /// By default, performs semantic analysis to build the new expression.
1086 /// Subclasses may override this routine to provide different behavior.
1087 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1088 QualType T1, QualType T2,
1089 SourceLocation RParenLoc) {
1090 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1091 T1.getAsOpaquePtr(),
1092 T2.getAsOpaquePtr(),
1093 RParenLoc);
1094 }
1095
1096 /// \brief Build a new __builtin_choose_expr expression.
1097 ///
1098 /// By default, performs semantic analysis to build the new expression.
1099 /// Subclasses may override this routine to provide different behavior.
1100 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1101 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1102 SourceLocation RParenLoc) {
1103 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1104 move(Cond), move(LHS), move(RHS),
1105 RParenLoc);
1106 }
1107
1108 /// \brief Build a new overloaded operator call expression.
1109 ///
1110 /// By default, performs semantic analysis to build the new expression.
1111 /// The semantic analysis provides the behavior of template instantiation,
1112 /// copying with transformations that turn what looks like an overloaded
1113 /// operator call into a use of a builtin operator, performing
1114 /// argument-dependent lookup, etc. Subclasses may override this routine to
1115 /// provide different behavior.
1116 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1117 SourceLocation OpLoc,
1118 ExprArg Callee,
1119 ExprArg First,
1120 ExprArg Second);
1121
1122 /// \brief Build a new C++ "named" cast expression, such as static_cast or
1123 /// reinterpret_cast.
1124 ///
1125 /// By default, this routine dispatches to one of the more-specific routines
1126 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
1127 /// Subclasses may override this routine to provide different behavior.
1128 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1129 Stmt::StmtClass Class,
1130 SourceLocation LAngleLoc,
1131 QualType T,
1132 SourceLocation RAngleLoc,
1133 SourceLocation LParenLoc,
1134 ExprArg SubExpr,
1135 SourceLocation RParenLoc) {
1136 switch (Class) {
1137 case Stmt::CXXStaticCastExprClass:
1138 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1139 RAngleLoc, LParenLoc,
1140 move(SubExpr), RParenLoc);
1141
1142 case Stmt::CXXDynamicCastExprClass:
1143 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1144 RAngleLoc, LParenLoc,
1145 move(SubExpr), RParenLoc);
1146
1147 case Stmt::CXXReinterpretCastExprClass:
1148 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1149 RAngleLoc, LParenLoc,
1150 move(SubExpr),
1151 RParenLoc);
1152
1153 case Stmt::CXXConstCastExprClass:
1154 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1155 RAngleLoc, LParenLoc,
1156 move(SubExpr), RParenLoc);
1157
1158 default:
1159 assert(false && "Invalid C++ named cast");
1160 break;
1161 }
1162
1163 return getSema().ExprError();
1164 }
1165
1166 /// \brief Build a new C++ static_cast expression.
1167 ///
1168 /// By default, performs semantic analysis to build the new expression.
1169 /// Subclasses may override this routine to provide different behavior.
1170 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1171 SourceLocation LAngleLoc,
1172 QualType T,
1173 SourceLocation RAngleLoc,
1174 SourceLocation LParenLoc,
1175 ExprArg SubExpr,
1176 SourceLocation RParenLoc) {
1177 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
1178 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1179 LParenLoc, move(SubExpr), RParenLoc);
1180 }
1181
1182 /// \brief Build a new C++ dynamic_cast expression.
1183 ///
1184 /// By default, performs semantic analysis to build the new expression.
1185 /// Subclasses may override this routine to provide different behavior.
1186 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1187 SourceLocation LAngleLoc,
1188 QualType T,
1189 SourceLocation RAngleLoc,
1190 SourceLocation LParenLoc,
1191 ExprArg SubExpr,
1192 SourceLocation RParenLoc) {
1193 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
1194 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1195 LParenLoc, move(SubExpr), RParenLoc);
1196 }
1197
1198 /// \brief Build a new C++ reinterpret_cast expression.
1199 ///
1200 /// By default, performs semantic analysis to build the new expression.
1201 /// Subclasses may override this routine to provide different behavior.
1202 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1203 SourceLocation LAngleLoc,
1204 QualType T,
1205 SourceLocation RAngleLoc,
1206 SourceLocation LParenLoc,
1207 ExprArg SubExpr,
1208 SourceLocation RParenLoc) {
1209 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1210 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1211 LParenLoc, move(SubExpr), RParenLoc);
1212 }
1213
1214 /// \brief Build a new C++ const_cast expression.
1215 ///
1216 /// By default, performs semantic analysis to build the new expression.
1217 /// Subclasses may override this routine to provide different behavior.
1218 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1219 SourceLocation LAngleLoc,
1220 QualType T,
1221 SourceLocation RAngleLoc,
1222 SourceLocation LParenLoc,
1223 ExprArg SubExpr,
1224 SourceLocation RParenLoc) {
1225 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
1226 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1227 LParenLoc, move(SubExpr), RParenLoc);
1228 }
1229
1230 /// \brief Build a new C++ functional-style cast expression.
1231 ///
1232 /// By default, performs semantic analysis to build the new expression.
1233 /// Subclasses may override this routine to provide different behavior.
1234 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1235 QualType T,
1236 SourceLocation LParenLoc,
1237 ExprArg SubExpr,
1238 SourceLocation RParenLoc) {
Chris Lattner88650c32009-08-24 05:19:01 +00001239 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregorb98b1992009-08-11 05:31:07 +00001240 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1241 T.getAsOpaquePtr(),
1242 LParenLoc,
Chris Lattner88650c32009-08-24 05:19:01 +00001243 Sema::MultiExprArg(getSema(), &Sub, 1),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001244 /*CommaLocs=*/0,
1245 RParenLoc);
1246 }
1247
1248 /// \brief Build a new C++ typeid(type) expression.
1249 ///
1250 /// By default, performs semantic analysis to build the new expression.
1251 /// Subclasses may override this routine to provide different behavior.
1252 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1253 SourceLocation LParenLoc,
1254 QualType T,
1255 SourceLocation RParenLoc) {
1256 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
1257 T.getAsOpaquePtr(), RParenLoc);
1258 }
1259
1260 /// \brief Build a new C++ typeid(expr) expression.
1261 ///
1262 /// By default, performs semantic analysis to build the new expression.
1263 /// Subclasses may override this routine to provide different behavior.
1264 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1265 SourceLocation LParenLoc,
1266 ExprArg Operand,
1267 SourceLocation RParenLoc) {
1268 OwningExprResult Result
1269 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1270 RParenLoc);
1271 if (Result.isInvalid())
1272 return getSema().ExprError();
1273
1274 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1275 return move(Result);
1276 }
1277
1278 /// \brief Build a new C++ "this" expression.
1279 ///
1280 /// By default, builds a new "this" expression without performing any
1281 /// semantic analysis. Subclasses may override this routine to provide
1282 /// different behavior.
1283 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
1284 QualType ThisType) {
1285 return getSema().Owned(
1286 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1287 }
1288
1289 /// \brief Build a new C++ throw expression.
1290 ///
1291 /// By default, performs semantic analysis to build the new expression.
1292 /// Subclasses may override this routine to provide different behavior.
1293 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1294 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1295 }
1296
1297 /// \brief Build a new C++ default-argument expression.
1298 ///
1299 /// By default, builds a new default-argument expression, which does not
1300 /// require any semantic analysis. Subclasses may override this routine to
1301 /// provide different behavior.
1302 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssonf1480ee2009-08-14 18:30:22 +00001303 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001304 }
1305
1306 /// \brief Build a new C++ zero-initialization expression.
1307 ///
1308 /// By default, performs semantic analysis to build the new expression.
1309 /// Subclasses may override this routine to provide different behavior.
1310 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
1311 SourceLocation LParenLoc,
1312 QualType T,
1313 SourceLocation RParenLoc) {
1314 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1315 T.getAsOpaquePtr(), LParenLoc,
1316 MultiExprArg(getSema(), 0, 0),
1317 0, RParenLoc);
1318 }
1319
1320 /// \brief Build a new C++ conditional declaration expression.
1321 ///
1322 /// By default, performs semantic analysis to build the new expression.
1323 /// Subclasses may override this routine to provide different behavior.
1324 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
1325 SourceLocation EqLoc,
1326 VarDecl *Var) {
1327 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1328 EqLoc,
1329 Var));
1330 }
1331
1332 /// \brief Build a new C++ "new" expression.
1333 ///
1334 /// By default, performs semantic analysis to build the new expression.
1335 /// Subclasses may override this routine to provide different behavior.
1336 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
1337 bool UseGlobal,
1338 SourceLocation PlacementLParen,
1339 MultiExprArg PlacementArgs,
1340 SourceLocation PlacementRParen,
1341 bool ParenTypeId,
1342 QualType AllocType,
1343 SourceLocation TypeLoc,
1344 SourceRange TypeRange,
1345 ExprArg ArraySize,
1346 SourceLocation ConstructorLParen,
1347 MultiExprArg ConstructorArgs,
1348 SourceLocation ConstructorRParen) {
1349 return getSema().BuildCXXNew(StartLoc, UseGlobal,
1350 PlacementLParen,
1351 move(PlacementArgs),
1352 PlacementRParen,
1353 ParenTypeId,
1354 AllocType,
1355 TypeLoc,
1356 TypeRange,
1357 move(ArraySize),
1358 ConstructorLParen,
1359 move(ConstructorArgs),
1360 ConstructorRParen);
1361 }
1362
1363 /// \brief Build a new C++ "delete" expression.
1364 ///
1365 /// By default, performs semantic analysis to build the new expression.
1366 /// Subclasses may override this routine to provide different behavior.
1367 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1368 bool IsGlobalDelete,
1369 bool IsArrayForm,
1370 ExprArg Operand) {
1371 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1372 move(Operand));
1373 }
1374
1375 /// \brief Build a new unary type trait expression.
1376 ///
1377 /// By default, performs semantic analysis to build the new expression.
1378 /// Subclasses may override this routine to provide different behavior.
1379 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1380 SourceLocation StartLoc,
1381 SourceLocation LParenLoc,
1382 QualType T,
1383 SourceLocation RParenLoc) {
1384 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
1385 T.getAsOpaquePtr(), RParenLoc);
1386 }
1387
1388 /// \brief Build a new qualified declaration reference expression.
1389 ///
1390 /// By default, performs semantic analysis to build the new expression.
1391 /// Subclasses may override this routine to provide different behavior.
1392 OwningExprResult RebuildQualifiedDeclRefExpr(NestedNameSpecifier *NNS,
1393 SourceRange QualifierRange,
1394 NamedDecl *ND,
1395 SourceLocation Location,
1396 bool IsAddressOfOperand) {
1397 CXXScopeSpec SS;
1398 SS.setRange(QualifierRange);
1399 SS.setScopeRep(NNS);
1400 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
1401 Location,
1402 ND->getDeclName(),
1403 /*Trailing lparen=*/false,
1404 &SS,
1405 IsAddressOfOperand);
1406 }
1407
1408 /// \brief Build a new (previously unresolved) declaration reference
1409 /// expression.
1410 ///
1411 /// By default, performs semantic analysis to build the new expression.
1412 /// Subclasses may override this routine to provide different behavior.
1413 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1414 SourceRange QualifierRange,
1415 DeclarationName Name,
1416 SourceLocation Location,
1417 bool IsAddressOfOperand) {
1418 CXXScopeSpec SS;
1419 SS.setRange(QualifierRange);
1420 SS.setScopeRep(NNS);
1421 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
1422 Location,
1423 Name,
1424 /*Trailing lparen=*/false,
1425 &SS,
1426 IsAddressOfOperand);
1427 }
1428
1429 /// \brief Build a new template-id expression.
1430 ///
1431 /// By default, performs semantic analysis to build the new expression.
1432 /// Subclasses may override this routine to provide different behavior.
1433 OwningExprResult RebuildTemplateIdExpr(TemplateName Template,
1434 SourceLocation TemplateLoc,
1435 SourceLocation LAngleLoc,
1436 TemplateArgument *TemplateArgs,
1437 unsigned NumTemplateArgs,
1438 SourceLocation RAngleLoc) {
1439 return getSema().BuildTemplateIdExpr(Template, TemplateLoc,
1440 LAngleLoc,
1441 TemplateArgs, NumTemplateArgs,
1442 RAngleLoc);
1443 }
1444
1445 /// \brief Build a new object-construction 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 RebuildCXXConstructExpr(QualType T,
1450 CXXConstructorDecl *Constructor,
1451 bool IsElidable,
1452 MultiExprArg Args) {
Anders Carlssonec8e5ea2009-09-05 07:40:38 +00001453 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1454 SourceLocation(),
1455 T, Constructor, IsElidable,
Anders Carlssonf47511a2009-09-07 22:23:31 +00001456 move(Args));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001457 }
1458
1459 /// \brief Build a new object-construction expression.
1460 ///
1461 /// By default, performs semantic analysis to build the new expression.
1462 /// Subclasses may override this routine to provide different behavior.
1463 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1464 QualType T,
1465 SourceLocation LParenLoc,
1466 MultiExprArg Args,
1467 SourceLocation *Commas,
1468 SourceLocation RParenLoc) {
1469 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1470 T.getAsOpaquePtr(),
1471 LParenLoc,
1472 move(Args),
1473 Commas,
1474 RParenLoc);
1475 }
1476
1477 /// \brief Build a new object-construction expression.
1478 ///
1479 /// By default, performs semantic analysis to build the new expression.
1480 /// Subclasses may override this routine to provide different behavior.
1481 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1482 QualType T,
1483 SourceLocation LParenLoc,
1484 MultiExprArg Args,
1485 SourceLocation *Commas,
1486 SourceLocation RParenLoc) {
1487 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1488 /*FIXME*/LParenLoc),
1489 T.getAsOpaquePtr(),
1490 LParenLoc,
1491 move(Args),
1492 Commas,
1493 RParenLoc);
1494 }
1495
1496 /// \brief Build a new member reference expression.
1497 ///
1498 /// By default, performs semantic analysis to build the new expression.
1499 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001500 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001501 bool IsArrow,
1502 SourceLocation OperatorLoc,
Douglas Gregora38c6872009-09-03 16:14:30 +00001503 NestedNameSpecifier *Qualifier,
1504 SourceRange QualifierRange,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001505 DeclarationName Name,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001506 SourceLocation MemberLoc,
1507 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001508 OwningExprResult Base = move(BaseE);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001509 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregora38c6872009-09-03 16:14:30 +00001510
Douglas Gregorb98b1992009-08-11 05:31:07 +00001511 CXXScopeSpec SS;
Douglas Gregora38c6872009-09-03 16:14:30 +00001512 SS.setRange(QualifierRange);
1513 SS.setScopeRep(Qualifier);
1514
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001515 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001516 move(Base), OperatorLoc, OpKind,
Douglas Gregor017dde52009-08-31 20:00:26 +00001517 MemberLoc,
1518 Name,
Douglas Gregora38c6872009-09-03 16:14:30 +00001519 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001520 &SS,
1521 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001522 }
1523
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001524 /// \brief Build a new member reference expression with explicit template
1525 /// arguments.
1526 ///
1527 /// By default, performs semantic analysis to build the new expression.
1528 /// Subclasses may override this routine to provide different behavior.
1529 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1530 bool IsArrow,
1531 SourceLocation OperatorLoc,
1532 NestedNameSpecifier *Qualifier,
1533 SourceRange QualifierRange,
1534 TemplateName Template,
1535 SourceLocation TemplateNameLoc,
1536 NamedDecl *FirstQualifierInScope,
1537 SourceLocation LAngleLoc,
1538 const TemplateArgument *TemplateArgs,
1539 unsigned NumTemplateArgs,
1540 SourceLocation RAngleLoc) {
1541 OwningExprResult Base = move(BaseE);
1542 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
1543
1544 CXXScopeSpec SS;
1545 SS.setRange(QualifierRange);
1546 SS.setScopeRep(Qualifier);
1547
1548 // FIXME: We're going to end up looking up the template based on its name,
1549 // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
1550 DeclarationName Name;
1551 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1552 Name = ActualTemplate->getDeclName();
1553 else if (OverloadedFunctionDecl *Ovl
1554 = Template.getAsOverloadedFunctionDecl())
1555 Name = Ovl->getDeclName();
1556 else
1557 Name = Template.getAsDependentTemplateName()->getName();
1558
1559 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
1560 OperatorLoc, OpKind,
1561 TemplateNameLoc, Name, true,
1562 LAngleLoc, TemplateArgs,
1563 NumTemplateArgs, RAngleLoc,
1564 Sema::DeclPtrTy(), &SS);
1565 }
1566
Douglas Gregorb98b1992009-08-11 05:31:07 +00001567 /// \brief Build a new Objective-C @encode expression.
1568 ///
1569 /// By default, performs semantic analysis to build the new expression.
1570 /// Subclasses may override this routine to provide different behavior.
1571 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1572 QualType T,
1573 SourceLocation RParenLoc) {
1574 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1575 RParenLoc));
1576 }
1577
1578 /// \brief Build a new Objective-C protocol expression.
1579 ///
1580 /// By default, performs semantic analysis to build the new expression.
1581 /// Subclasses may override this routine to provide different behavior.
1582 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1583 SourceLocation AtLoc,
1584 SourceLocation ProtoLoc,
1585 SourceLocation LParenLoc,
1586 SourceLocation RParenLoc) {
1587 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1588 Protocol->getIdentifier(),
1589 AtLoc,
1590 ProtoLoc,
1591 LParenLoc,
1592 RParenLoc));
1593 }
1594
1595 /// \brief Build a new shuffle vector expression.
1596 ///
1597 /// By default, performs semantic analysis to build the new expression.
1598 /// Subclasses may override this routine to provide different behavior.
1599 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1600 MultiExprArg SubExprs,
1601 SourceLocation RParenLoc) {
1602 // Find the declaration for __builtin_shufflevector
1603 const IdentifierInfo &Name
1604 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1605 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1606 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1607 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
1608
1609 // Build a reference to the __builtin_shufflevector builtin
1610 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
1611 Expr *Callee
1612 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1613 BuiltinLoc, false, false);
1614 SemaRef.UsualUnaryConversions(Callee);
1615
1616 // Build the CallExpr
1617 unsigned NumSubExprs = SubExprs.size();
1618 Expr **Subs = (Expr **)SubExprs.release();
1619 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1620 Subs, NumSubExprs,
1621 Builtin->getResultType(),
1622 RParenLoc);
1623 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
1624
1625 // Type-check the __builtin_shufflevector expression.
1626 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1627 if (Result.isInvalid())
1628 return SemaRef.ExprError();
1629
1630 OwnedCall.release();
1631 return move(Result);
1632 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00001633};
Douglas Gregorb98b1992009-08-11 05:31:07 +00001634
Douglas Gregor43959a92009-08-20 07:17:43 +00001635template<typename Derived>
1636Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1637 if (!S)
1638 return SemaRef.Owned(S);
1639
1640 switch (S->getStmtClass()) {
1641 case Stmt::NoStmtClass: break;
1642
1643 // Transform individual statement nodes
1644#define STMT(Node, Parent) \
1645 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1646#define EXPR(Node, Parent)
1647#include "clang/AST/StmtNodes.def"
1648
1649 // Transform expressions by calling TransformExpr.
1650#define STMT(Node, Parent)
1651#define EXPR(Node, Parent) case Stmt::Node##Class:
1652#include "clang/AST/StmtNodes.def"
1653 {
1654 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1655 if (E.isInvalid())
1656 return getSema().StmtError();
1657
1658 return getSema().Owned(E.takeAs<Stmt>());
1659 }
1660 }
1661
1662 return SemaRef.Owned(S->Retain());
1663}
1664
Douglas Gregor577f75a2009-08-04 16:50:30 +00001665
Douglas Gregor670444e2009-08-04 22:27:00 +00001666template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00001667Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1668 bool isAddressOfOperand) {
1669 if (!E)
1670 return SemaRef.Owned(E);
1671
1672 switch (E->getStmtClass()) {
1673 case Stmt::NoStmtClass: break;
1674#define STMT(Node, Parent) case Stmt::Node##Class: break;
1675#define EXPR(Node, Parent) \
1676 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1677#include "clang/AST/StmtNodes.def"
1678 }
1679
1680 return SemaRef.Owned(E->Retain());
Douglas Gregor657c1ac2009-08-06 22:17:10 +00001681}
1682
1683template<typename Derived>
Douglas Gregordcee1a12009-08-06 05:28:30 +00001684NestedNameSpecifier *
1685TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +00001686 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001687 QualType ObjectType,
1688 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0979c802009-08-31 21:41:48 +00001689 if (!NNS)
1690 return 0;
1691
Douglas Gregor43959a92009-08-20 07:17:43 +00001692 // Transform the prefix of this nested name specifier.
Douglas Gregordcee1a12009-08-06 05:28:30 +00001693 NestedNameSpecifier *Prefix = NNS->getPrefix();
1694 if (Prefix) {
Douglas Gregora38c6872009-09-03 16:14:30 +00001695 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001696 ObjectType,
1697 FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +00001698 if (!Prefix)
1699 return 0;
Douglas Gregora38c6872009-09-03 16:14:30 +00001700
Douglas Gregorc68afe22009-09-03 21:38:09 +00001701 // Clear out the object type and the first qualifier in scope; they only
1702 // apply to the first element in the nested-name-specifier.
Douglas Gregora38c6872009-09-03 16:14:30 +00001703 ObjectType = QualType();
Douglas Gregorc68afe22009-09-03 21:38:09 +00001704 FirstQualifierInScope = 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001705 }
1706
1707 switch (NNS->getKind()) {
1708 case NestedNameSpecifier::Identifier:
Douglas Gregora38c6872009-09-03 16:14:30 +00001709 assert((Prefix || !ObjectType.isNull()) &&
1710 "Identifier nested-name-specifier with no prefix or object type");
1711 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1712 ObjectType.isNull())
Douglas Gregordcee1a12009-08-06 05:28:30 +00001713 return NNS;
1714
1715 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00001716 *NNS->getAsIdentifier(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001717 ObjectType,
1718 FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +00001719
1720 case NestedNameSpecifier::Namespace: {
1721 NamespaceDecl *NS
1722 = cast_or_null<NamespaceDecl>(
1723 getDerived().TransformDecl(NNS->getAsNamespace()));
1724 if (!getDerived().AlwaysRebuild() &&
1725 Prefix == NNS->getPrefix() &&
1726 NS == NNS->getAsNamespace())
1727 return NNS;
1728
1729 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1730 }
1731
1732 case NestedNameSpecifier::Global:
1733 // There is no meaningful transformation that one could perform on the
1734 // global scope.
1735 return NNS;
1736
1737 case NestedNameSpecifier::TypeSpecWithTemplate:
1738 case NestedNameSpecifier::TypeSpec: {
1739 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregord1067e52009-08-06 06:41:21 +00001740 if (T.isNull())
1741 return 0;
1742
Douglas Gregordcee1a12009-08-06 05:28:30 +00001743 if (!getDerived().AlwaysRebuild() &&
1744 Prefix == NNS->getPrefix() &&
1745 T == QualType(NNS->getAsType(), 0))
1746 return NNS;
1747
1748 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1749 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
1750 T);
1751 }
1752 }
1753
1754 // Required to silence a GCC warning
1755 return 0;
1756}
1757
1758template<typename Derived>
Douglas Gregor81499bb2009-09-03 22:13:48 +00001759DeclarationName
1760TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
1761 SourceLocation Loc) {
1762 if (!Name)
1763 return Name;
1764
1765 switch (Name.getNameKind()) {
1766 case DeclarationName::Identifier:
1767 case DeclarationName::ObjCZeroArgSelector:
1768 case DeclarationName::ObjCOneArgSelector:
1769 case DeclarationName::ObjCMultiArgSelector:
1770 case DeclarationName::CXXOperatorName:
1771 case DeclarationName::CXXUsingDirective:
1772 return Name;
1773
1774 case DeclarationName::CXXConstructorName:
1775 case DeclarationName::CXXDestructorName:
1776 case DeclarationName::CXXConversionFunctionName: {
1777 TemporaryBase Rebase(*this, Loc, Name);
1778 QualType T = getDerived().TransformType(Name.getCXXNameType());
1779 if (T.isNull())
1780 return DeclarationName();
1781
1782 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
1783 Name.getNameKind(),
1784 SemaRef.Context.getCanonicalType(T));
1785 }
1786 }
1787
1788 return DeclarationName();
1789}
1790
1791template<typename Derived>
Douglas Gregord1067e52009-08-06 06:41:21 +00001792TemplateName
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001793TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1794 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00001795 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
1796 NestedNameSpecifier *NNS
1797 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1798 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1799 if (!NNS)
1800 return TemplateName();
1801
1802 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
1803 TemplateDecl *TransTemplate
1804 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1805 if (!TransTemplate)
1806 return TemplateName();
1807
1808 if (!getDerived().AlwaysRebuild() &&
1809 NNS == QTN->getQualifier() &&
1810 TransTemplate == Template)
1811 return Name;
1812
1813 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1814 TransTemplate);
1815 }
1816
1817 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1818 assert(Ovl && "Not a template name or an overload set?");
1819 OverloadedFunctionDecl *TransOvl
1820 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1821 if (!TransOvl)
1822 return TemplateName();
1823
1824 if (!getDerived().AlwaysRebuild() &&
1825 NNS == QTN->getQualifier() &&
1826 TransOvl == Ovl)
1827 return Name;
1828
1829 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1830 TransOvl);
1831 }
1832
1833 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
1834 NestedNameSpecifier *NNS
1835 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1836 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001837 if (!NNS && DTN->getQualifier())
Douglas Gregord1067e52009-08-06 06:41:21 +00001838 return TemplateName();
1839
1840 if (!getDerived().AlwaysRebuild() &&
1841 NNS == DTN->getQualifier())
1842 return Name;
1843
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001844 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregord1067e52009-08-06 06:41:21 +00001845 }
1846
1847 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1848 TemplateDecl *TransTemplate
1849 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1850 if (!TransTemplate)
1851 return TemplateName();
1852
1853 if (!getDerived().AlwaysRebuild() &&
1854 TransTemplate == Template)
1855 return Name;
1856
1857 return TemplateName(TransTemplate);
1858 }
1859
1860 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1861 assert(Ovl && "Not a template name or an overload set?");
1862 OverloadedFunctionDecl *TransOvl
1863 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1864 if (!TransOvl)
1865 return TemplateName();
1866
1867 if (!getDerived().AlwaysRebuild() &&
1868 TransOvl == Ovl)
1869 return Name;
1870
1871 return TemplateName(TransOvl);
1872}
1873
1874template<typename Derived>
Douglas Gregor670444e2009-08-04 22:27:00 +00001875TemplateArgument
1876TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
1877 switch (Arg.getKind()) {
1878 case TemplateArgument::Null:
1879 case TemplateArgument::Integral:
1880 return Arg;
1881
1882 case TemplateArgument::Type: {
1883 QualType T = getDerived().TransformType(Arg.getAsType());
1884 if (T.isNull())
1885 return TemplateArgument();
1886 return TemplateArgument(Arg.getLocation(), T);
1887 }
1888
1889 case TemplateArgument::Declaration: {
1890 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
1891 if (!D)
1892 return TemplateArgument();
1893 return TemplateArgument(Arg.getLocation(), D);
1894 }
1895
1896 case TemplateArgument::Expression: {
1897 // Template argument expressions are not potentially evaluated.
1898 EnterExpressionEvaluationContext Unevaluated(getSema(),
1899 Action::Unevaluated);
1900
1901 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
1902 if (E.isInvalid())
1903 return TemplateArgument();
1904 return TemplateArgument(E.takeAs<Expr>());
1905 }
1906
1907 case TemplateArgument::Pack: {
1908 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1909 TransformedArgs.reserve(Arg.pack_size());
1910 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
1911 AEnd = Arg.pack_end();
1912 A != AEnd; ++A) {
1913 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
1914 if (TA.isNull())
1915 return TA;
1916
1917 TransformedArgs.push_back(TA);
1918 }
1919 TemplateArgument Result;
1920 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
1921 true);
1922 return Result;
1923 }
1924 }
1925
1926 // Work around bogus GCC warning
1927 return TemplateArgument();
1928}
1929
Douglas Gregor577f75a2009-08-04 16:50:30 +00001930//===----------------------------------------------------------------------===//
1931// Type transformation
1932//===----------------------------------------------------------------------===//
1933
1934template<typename Derived>
1935QualType TreeTransform<Derived>::TransformType(QualType T) {
1936 if (getDerived().AlreadyTransformed(T))
1937 return T;
1938
1939 QualType Result;
1940 switch (T->getTypeClass()) {
1941#define ABSTRACT_TYPE(CLASS, PARENT)
1942#define TYPE(CLASS, PARENT) \
1943 case Type::CLASS: \
1944 Result = getDerived().Transform##CLASS##Type( \
1945 static_cast<CLASS##Type*>(T.getTypePtr())); \
1946 break;
1947#include "clang/AST/TypeNodes.def"
1948 }
1949
1950 if (Result.isNull() || T == Result)
1951 return Result;
1952
1953 return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
1954}
1955
1956template<typename Derived>
1957QualType
1958TreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
1959 if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
1960 return T.getWithAdditionalQualifiers(CVRQualifiers);
1961
1962 return T;
1963}
Argyrios Kyrtzidis1bb8a452009-08-19 01:28:17 +00001964
Douglas Gregor577f75a2009-08-04 16:50:30 +00001965template<typename Derived>
1966QualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
1967 // FIXME: Implement
1968 return QualType(T, 0);
1969}
1970
1971template<typename Derived>
1972QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
1973 // Nothing to do
1974 return QualType(T, 0);
1975}
1976
1977template<typename Derived>
1978QualType TreeTransform<Derived>::TransformFixedWidthIntType(
1979 const FixedWidthIntType *T) {
1980 // FIXME: Implement
1981 return QualType(T, 0);
1982}
1983
1984template<typename Derived>
1985QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
1986 // FIXME: Implement
1987 return QualType(T, 0);
1988}
1989
1990template<typename Derived>
1991QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
1992 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1993 if (PointeeType.isNull())
1994 return QualType();
1995
1996 if (!getDerived().AlwaysRebuild() &&
1997 PointeeType == T->getPointeeType())
1998 return QualType(T, 0);
1999
2000 return getDerived().RebuildPointerType(PointeeType);
2001}
2002
2003template<typename Derived>
2004QualType
2005TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
2006 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2007 if (PointeeType.isNull())
2008 return QualType();
2009
2010 if (!getDerived().AlwaysRebuild() &&
2011 PointeeType == T->getPointeeType())
2012 return QualType(T, 0);
2013
2014 return getDerived().RebuildBlockPointerType(PointeeType);
2015}
2016
2017template<typename Derived>
2018QualType
2019TreeTransform<Derived>::TransformLValueReferenceType(
2020 const LValueReferenceType *T) {
2021 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2022 if (PointeeType.isNull())
2023 return QualType();
2024
2025 if (!getDerived().AlwaysRebuild() &&
2026 PointeeType == T->getPointeeType())
2027 return QualType(T, 0);
2028
2029 return getDerived().RebuildLValueReferenceType(PointeeType);
2030}
2031
2032template<typename Derived>
2033QualType
2034TreeTransform<Derived>::TransformRValueReferenceType(
2035 const RValueReferenceType *T) {
2036 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2037 if (PointeeType.isNull())
2038 return QualType();
2039
2040 if (!getDerived().AlwaysRebuild() &&
2041 PointeeType == T->getPointeeType())
2042 return QualType(T, 0);
2043
2044 return getDerived().RebuildRValueReferenceType(PointeeType);
2045}
2046
2047template<typename Derived>
2048QualType
2049TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
2050 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2051 if (PointeeType.isNull())
2052 return QualType();
2053
2054 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
2055 if (ClassType.isNull())
2056 return QualType();
2057
2058 if (!getDerived().AlwaysRebuild() &&
2059 PointeeType == T->getPointeeType() &&
2060 ClassType == QualType(T->getClass(), 0))
2061 return QualType(T, 0);
2062
2063 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2064}
2065
2066template<typename Derived>
2067QualType
2068TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
2069 QualType ElementType = getDerived().TransformType(T->getElementType());
2070 if (ElementType.isNull())
2071 return QualType();
2072
2073 if (!getDerived().AlwaysRebuild() &&
2074 ElementType == T->getElementType())
2075 return QualType(T, 0);
2076
2077 return getDerived().RebuildConstantArrayType(ElementType,
2078 T->getSizeModifier(),
2079 T->getSize(),
2080 T->getIndexTypeQualifier());
2081}
2082
2083template<typename Derived>
2084QualType
2085TreeTransform<Derived>::TransformConstantArrayWithExprType(
2086 const ConstantArrayWithExprType *T) {
2087 QualType ElementType = getDerived().TransformType(T->getElementType());
2088 if (ElementType.isNull())
2089 return QualType();
2090
Douglas Gregor670444e2009-08-04 22:27:00 +00002091 // Array bounds are not potentially evaluated contexts
2092 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2093
2094 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2095 if (Size.isInvalid())
2096 return QualType();
2097
Douglas Gregor577f75a2009-08-04 16:50:30 +00002098 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor670444e2009-08-04 22:27:00 +00002099 ElementType == T->getElementType() &&
2100 Size.get() == T->getSizeExpr())
Douglas Gregor577f75a2009-08-04 16:50:30 +00002101 return QualType(T, 0);
2102
2103 return getDerived().RebuildConstantArrayWithExprType(ElementType,
2104 T->getSizeModifier(),
2105 T->getSize(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002106 Size.takeAs<Expr>(),
Douglas Gregor577f75a2009-08-04 16:50:30 +00002107 T->getIndexTypeQualifier(),
2108 T->getBracketsRange());
2109}
2110
2111template<typename Derived>
2112QualType
2113TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
2114 const ConstantArrayWithoutExprType *T) {
2115 QualType ElementType = getDerived().TransformType(T->getElementType());
2116 if (ElementType.isNull())
2117 return QualType();
2118
2119 if (!getDerived().AlwaysRebuild() &&
2120 ElementType == T->getElementType())
2121 return QualType(T, 0);
2122
2123 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
2124 T->getSizeModifier(),
2125 T->getSize(),
2126 T->getIndexTypeQualifier());
2127}
2128
2129template<typename Derived>
2130QualType TreeTransform<Derived>::TransformIncompleteArrayType(
2131 const IncompleteArrayType *T) {
2132 QualType ElementType = getDerived().TransformType(T->getElementType());
2133 if (ElementType.isNull())
2134 return QualType();
2135
2136 if (!getDerived().AlwaysRebuild() &&
2137 ElementType == T->getElementType())
2138 return QualType(T, 0);
2139
2140 return getDerived().RebuildIncompleteArrayType(ElementType,
2141 T->getSizeModifier(),
2142 T->getIndexTypeQualifier());
2143}
2144
2145template<typename Derived>
2146QualType TreeTransform<Derived>::TransformVariableArrayType(
2147 const VariableArrayType *T) {
2148 QualType ElementType = getDerived().TransformType(T->getElementType());
2149 if (ElementType.isNull())
2150 return QualType();
2151
Douglas Gregor670444e2009-08-04 22:27:00 +00002152 // Array bounds are not potentially evaluated contexts
2153 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2154
Douglas Gregor577f75a2009-08-04 16:50:30 +00002155 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2156 if (Size.isInvalid())
2157 return QualType();
2158
2159 if (!getDerived().AlwaysRebuild() &&
2160 ElementType == T->getElementType() &&
2161 Size.get() == T->getSizeExpr()) {
2162 Size.take();
2163 return QualType(T, 0);
2164 }
2165
2166 return getDerived().RebuildVariableArrayType(ElementType,
2167 T->getSizeModifier(),
2168 move(Size),
2169 T->getIndexTypeQualifier(),
2170 T->getBracketsRange());
2171}
2172
2173template<typename Derived>
2174QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
2175 const DependentSizedArrayType *T) {
2176 QualType ElementType = getDerived().TransformType(T->getElementType());
2177 if (ElementType.isNull())
2178 return QualType();
2179
Douglas Gregor670444e2009-08-04 22:27:00 +00002180 // Array bounds are not potentially evaluated contexts
2181 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2182
Douglas Gregor577f75a2009-08-04 16:50:30 +00002183 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2184 if (Size.isInvalid())
2185 return QualType();
2186
2187 if (!getDerived().AlwaysRebuild() &&
2188 ElementType == T->getElementType() &&
2189 Size.get() == T->getSizeExpr()) {
2190 Size.take();
2191 return QualType(T, 0);
2192 }
2193
2194 return getDerived().RebuildDependentSizedArrayType(ElementType,
2195 T->getSizeModifier(),
2196 move(Size),
2197 T->getIndexTypeQualifier(),
2198 T->getBracketsRange());
2199}
2200
2201template<typename Derived>
2202QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
2203 const DependentSizedExtVectorType *T) {
2204 QualType ElementType = getDerived().TransformType(T->getElementType());
2205 if (ElementType.isNull())
2206 return QualType();
2207
Douglas Gregor670444e2009-08-04 22:27:00 +00002208 // Vector sizes are not potentially evaluated contexts
2209 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2210
Douglas Gregor577f75a2009-08-04 16:50:30 +00002211 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2212 if (Size.isInvalid())
2213 return QualType();
2214
2215 if (!getDerived().AlwaysRebuild() &&
2216 ElementType == T->getElementType() &&
2217 Size.get() == T->getSizeExpr()) {
2218 Size.take();
2219 return QualType(T, 0);
2220 }
2221
2222 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
2223 move(Size),
2224 T->getAttributeLoc());
2225}
2226
2227template<typename Derived>
2228QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
2229 QualType ElementType = getDerived().TransformType(T->getElementType());
2230 if (ElementType.isNull())
2231 return QualType();
2232
2233 if (!getDerived().AlwaysRebuild() &&
2234 ElementType == T->getElementType())
2235 return QualType(T, 0);
2236
2237 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
2238}
2239
2240template<typename Derived>
2241QualType
2242TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
2243 QualType ElementType = getDerived().TransformType(T->getElementType());
2244 if (ElementType.isNull())
2245 return QualType();
2246
2247 if (!getDerived().AlwaysRebuild() &&
2248 ElementType == T->getElementType())
2249 return QualType(T, 0);
2250
2251 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
2252 /*FIXME*/SourceLocation());
2253}
2254
2255template<typename Derived>
2256QualType TreeTransform<Derived>::TransformFunctionProtoType(
2257 const FunctionProtoType *T) {
2258 QualType ResultType = getDerived().TransformType(T->getResultType());
2259 if (ResultType.isNull())
2260 return QualType();
2261
2262 llvm::SmallVector<QualType, 4> ParamTypes;
2263 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
2264 ParamEnd = T->arg_type_end();
2265 Param != ParamEnd; ++Param) {
2266 QualType P = getDerived().TransformType(*Param);
2267 if (P.isNull())
2268 return QualType();
2269
2270 ParamTypes.push_back(P);
2271 }
2272
2273 if (!getDerived().AlwaysRebuild() &&
2274 ResultType == T->getResultType() &&
2275 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
2276 return QualType(T, 0);
2277
2278 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
2279 ParamTypes.size(), T->isVariadic(),
2280 T->getTypeQuals());
2281}
2282
2283template<typename Derived>
2284QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
2285 const FunctionNoProtoType *T) {
2286 // FIXME: Implement
2287 return QualType(T, 0);
2288}
2289
2290template<typename Derived>
2291QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
2292 TypedefDecl *Typedef
2293 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2294 if (!Typedef)
2295 return QualType();
2296
2297 if (!getDerived().AlwaysRebuild() &&
2298 Typedef == T->getDecl())
2299 return QualType(T, 0);
2300
2301 return getDerived().RebuildTypedefType(Typedef);
2302}
2303
2304template<typename Derived>
2305QualType TreeTransform<Derived>::TransformTypeOfExprType(
2306 const TypeOfExprType *T) {
Douglas Gregor670444e2009-08-04 22:27:00 +00002307 // typeof expressions are not potentially evaluated contexts
2308 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2309
Douglas Gregor577f75a2009-08-04 16:50:30 +00002310 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2311 if (E.isInvalid())
2312 return QualType();
2313
2314 if (!getDerived().AlwaysRebuild() &&
2315 E.get() == T->getUnderlyingExpr()) {
2316 E.take();
2317 return QualType(T, 0);
2318 }
2319
2320 return getDerived().RebuildTypeOfExprType(move(E));
2321}
2322
2323template<typename Derived>
2324QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
2325 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2326 if (Underlying.isNull())
2327 return QualType();
2328
2329 if (!getDerived().AlwaysRebuild() &&
2330 Underlying == T->getUnderlyingType())
2331 return QualType(T, 0);
2332
2333 return getDerived().RebuildTypeOfType(Underlying);
2334}
2335
2336template<typename Derived>
2337QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor670444e2009-08-04 22:27:00 +00002338 // decltype expressions are not potentially evaluated contexts
2339 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2340
Douglas Gregor577f75a2009-08-04 16:50:30 +00002341 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2342 if (E.isInvalid())
2343 return QualType();
2344
2345 if (!getDerived().AlwaysRebuild() &&
2346 E.get() == T->getUnderlyingExpr()) {
2347 E.take();
2348 return QualType(T, 0);
2349 }
2350
2351 return getDerived().RebuildDecltypeType(move(E));
2352}
2353
2354template<typename Derived>
2355QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
2356 RecordDecl *Record
2357 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
2358 if (!Record)
2359 return QualType();
2360
2361 if (!getDerived().AlwaysRebuild() &&
2362 Record == T->getDecl())
2363 return QualType(T, 0);
2364
2365 return getDerived().RebuildRecordType(Record);
2366}
2367
2368template<typename Derived>
2369QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
2370 EnumDecl *Enum
2371 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
2372 if (!Enum)
2373 return QualType();
2374
2375 if (!getDerived().AlwaysRebuild() &&
2376 Enum == T->getDecl())
2377 return QualType(T, 0);
2378
2379 return getDerived().RebuildEnumType(Enum);
2380}
John McCall7da24312009-09-05 00:15:47 +00002381
2382template <typename Derived>
2383QualType TreeTransform<Derived>::TransformElaboratedType(
2384 const ElaboratedType *T) {
2385 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2386 if (Underlying.isNull())
2387 return QualType();
2388
2389 if (!getDerived().AlwaysRebuild() &&
2390 Underlying == T->getUnderlyingType())
2391 return QualType(T, 0);
2392
2393 return getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2394}
2395
Douglas Gregor577f75a2009-08-04 16:50:30 +00002396
2397template<typename Derived>
2398QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
2399 const TemplateTypeParmType *T) {
2400 // Nothing to do
2401 return QualType(T, 0);
2402}
2403
2404template<typename Derived>
2405QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2406 const TemplateSpecializationType *T) {
2407 TemplateName Template
2408 = getDerived().TransformTemplateName(T->getTemplateName());
2409 if (Template.isNull())
2410 return QualType();
2411
2412 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2413 NewTemplateArgs.reserve(T->getNumArgs());
2414 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2415 Arg != ArgEnd; ++Arg) {
2416 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2417 if (NewArg.isNull())
2418 return QualType();
2419
2420 NewTemplateArgs.push_back(NewArg);
2421 }
2422
2423 // FIXME: early abort if all of the template arguments and such are the
2424 // same.
2425
2426 // FIXME: We're missing the locations of the template name, '<', and '>'.
2427 return getDerived().RebuildTemplateSpecializationType(Template,
2428 NewTemplateArgs.data(),
2429 NewTemplateArgs.size());
2430}
2431
2432template<typename Derived>
2433QualType TreeTransform<Derived>::TransformQualifiedNameType(
2434 const QualifiedNameType *T) {
2435 NestedNameSpecifier *NNS
2436 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2437 SourceRange());
2438 if (!NNS)
2439 return QualType();
2440
2441 QualType Named = getDerived().TransformType(T->getNamedType());
2442 if (Named.isNull())
2443 return QualType();
2444
2445 if (!getDerived().AlwaysRebuild() &&
2446 NNS == T->getQualifier() &&
2447 Named == T->getNamedType())
2448 return QualType(T, 0);
2449
2450 return getDerived().RebuildQualifiedNameType(NNS, Named);
2451}
2452
2453template<typename Derived>
2454QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
2455 NestedNameSpecifier *NNS
2456 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor4a959d82009-08-06 16:20:37 +00002457 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002458 if (!NNS)
2459 return QualType();
2460
2461 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
2462 QualType NewTemplateId
2463 = getDerived().TransformType(QualType(TemplateId, 0));
2464 if (NewTemplateId.isNull())
2465 return QualType();
2466
2467 if (!getDerived().AlwaysRebuild() &&
2468 NNS == T->getQualifier() &&
2469 NewTemplateId == QualType(TemplateId, 0))
2470 return QualType(T, 0);
2471
2472 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
2473 }
2474
2475 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
2476}
2477
2478template<typename Derived>
2479QualType TreeTransform<Derived>::TransformObjCInterfaceType(
2480 const ObjCInterfaceType *T) {
2481 // FIXME: Implement
2482 return QualType(T, 0);
2483}
2484
2485template<typename Derived>
2486QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
2487 const ObjCObjectPointerType *T) {
2488 // FIXME: Implement
2489 return QualType(T, 0);
2490}
2491
2492//===----------------------------------------------------------------------===//
Douglas Gregor43959a92009-08-20 07:17:43 +00002493// Statement transformation
2494//===----------------------------------------------------------------------===//
2495template<typename Derived>
2496Sema::OwningStmtResult
2497TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2498 return SemaRef.Owned(S->Retain());
2499}
2500
2501template<typename Derived>
2502Sema::OwningStmtResult
2503TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2504 return getDerived().TransformCompoundStmt(S, false);
2505}
2506
2507template<typename Derived>
2508Sema::OwningStmtResult
2509TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
2510 bool IsStmtExpr) {
2511 bool SubStmtChanged = false;
2512 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2513 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2514 B != BEnd; ++B) {
2515 OwningStmtResult Result = getDerived().TransformStmt(*B);
2516 if (Result.isInvalid())
2517 return getSema().StmtError();
2518
2519 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2520 Statements.push_back(Result.takeAs<Stmt>());
2521 }
2522
2523 if (!getDerived().AlwaysRebuild() &&
2524 !SubStmtChanged)
2525 return SemaRef.Owned(S->Retain());
2526
2527 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2528 move_arg(Statements),
2529 S->getRBracLoc(),
2530 IsStmtExpr);
2531}
2532
2533template<typename Derived>
2534Sema::OwningStmtResult
2535TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
2536 // The case value expressions are not potentially evaluated.
2537 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2538
2539 // Transform the left-hand case value.
2540 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2541 if (LHS.isInvalid())
2542 return SemaRef.StmtError();
2543
2544 // Transform the right-hand case value (for the GNU case-range extension).
2545 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2546 if (RHS.isInvalid())
2547 return SemaRef.StmtError();
2548
2549 // Build the case statement.
2550 // Case statements are always rebuilt so that they will attached to their
2551 // transformed switch statement.
2552 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2553 move(LHS),
2554 S->getEllipsisLoc(),
2555 move(RHS),
2556 S->getColonLoc());
2557 if (Case.isInvalid())
2558 return SemaRef.StmtError();
2559
2560 // Transform the statement following the case
2561 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2562 if (SubStmt.isInvalid())
2563 return SemaRef.StmtError();
2564
2565 // Attach the body to the case statement
2566 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2567}
2568
2569template<typename Derived>
2570Sema::OwningStmtResult
2571TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
2572 // Transform the statement following the default case
2573 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2574 if (SubStmt.isInvalid())
2575 return SemaRef.StmtError();
2576
2577 // Default statements are always rebuilt
2578 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2579 move(SubStmt));
2580}
2581
2582template<typename Derived>
2583Sema::OwningStmtResult
2584TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
2585 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2586 if (SubStmt.isInvalid())
2587 return SemaRef.StmtError();
2588
2589 // FIXME: Pass the real colon location in.
2590 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2591 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2592 move(SubStmt));
2593}
2594
2595template<typename Derived>
2596Sema::OwningStmtResult
2597TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
2598 // Transform the condition
2599 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2600 if (Cond.isInvalid())
2601 return SemaRef.StmtError();
2602
2603 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
2604
2605 // Transform the "then" branch.
2606 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2607 if (Then.isInvalid())
2608 return SemaRef.StmtError();
2609
2610 // Transform the "else" branch.
2611 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2612 if (Else.isInvalid())
2613 return SemaRef.StmtError();
2614
2615 if (!getDerived().AlwaysRebuild() &&
2616 FullCond->get() == S->getCond() &&
2617 Then.get() == S->getThen() &&
2618 Else.get() == S->getElse())
2619 return SemaRef.Owned(S->Retain());
2620
2621 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
2622 S->getElseLoc(), move(Else));
2623}
2624
2625template<typename Derived>
2626Sema::OwningStmtResult
2627TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
2628 // Transform the condition.
2629 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2630 if (Cond.isInvalid())
2631 return SemaRef.StmtError();
2632
2633 // Rebuild the switch statement.
2634 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2635 if (Switch.isInvalid())
2636 return SemaRef.StmtError();
2637
2638 // Transform the body of the switch statement.
2639 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2640 if (Body.isInvalid())
2641 return SemaRef.StmtError();
2642
2643 // Complete the switch statement.
2644 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2645 move(Body));
2646}
2647
2648template<typename Derived>
2649Sema::OwningStmtResult
2650TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
2651 // Transform the condition
2652 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2653 if (Cond.isInvalid())
2654 return SemaRef.StmtError();
2655
2656 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
2657
2658 // Transform the body
2659 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2660 if (Body.isInvalid())
2661 return SemaRef.StmtError();
2662
2663 if (!getDerived().AlwaysRebuild() &&
2664 FullCond->get() == S->getCond() &&
2665 Body.get() == S->getBody())
2666 return SemaRef.Owned(S->Retain());
2667
2668 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2669}
2670
2671template<typename Derived>
2672Sema::OwningStmtResult
2673TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2674 // Transform the condition
2675 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2676 if (Cond.isInvalid())
2677 return SemaRef.StmtError();
2678
2679 // Transform the body
2680 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2681 if (Body.isInvalid())
2682 return SemaRef.StmtError();
2683
2684 if (!getDerived().AlwaysRebuild() &&
2685 Cond.get() == S->getCond() &&
2686 Body.get() == S->getBody())
2687 return SemaRef.Owned(S->Retain());
2688
2689 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
2690 /*FIXME:*/S->getWhileLoc(), move(Cond),
2691 S->getRParenLoc());
2692}
2693
2694template<typename Derived>
2695Sema::OwningStmtResult
2696TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
2697 // Transform the initialization statement
2698 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
2699 if (Init.isInvalid())
2700 return SemaRef.StmtError();
2701
2702 // Transform the condition
2703 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2704 if (Cond.isInvalid())
2705 return SemaRef.StmtError();
2706
2707 // Transform the increment
2708 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
2709 if (Inc.isInvalid())
2710 return SemaRef.StmtError();
2711
2712 // Transform the body
2713 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2714 if (Body.isInvalid())
2715 return SemaRef.StmtError();
2716
2717 if (!getDerived().AlwaysRebuild() &&
2718 Init.get() == S->getInit() &&
2719 Cond.get() == S->getCond() &&
2720 Inc.get() == S->getInc() &&
2721 Body.get() == S->getBody())
2722 return SemaRef.Owned(S->Retain());
2723
2724 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
2725 move(Init), move(Cond), move(Inc),
2726 S->getRParenLoc(), move(Body));
2727}
2728
2729template<typename Derived>
2730Sema::OwningStmtResult
2731TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
2732 // Goto statements must always be rebuilt, to resolve the label.
2733 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
2734 S->getLabel());
2735}
2736
2737template<typename Derived>
2738Sema::OwningStmtResult
2739TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
2740 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
2741 if (Target.isInvalid())
2742 return SemaRef.StmtError();
2743
2744 if (!getDerived().AlwaysRebuild() &&
2745 Target.get() == S->getTarget())
2746 return SemaRef.Owned(S->Retain());
2747
2748 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
2749 move(Target));
2750}
2751
2752template<typename Derived>
2753Sema::OwningStmtResult
2754TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
2755 return SemaRef.Owned(S->Retain());
2756}
2757
2758template<typename Derived>
2759Sema::OwningStmtResult
2760TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
2761 return SemaRef.Owned(S->Retain());
2762}
2763
2764template<typename Derived>
2765Sema::OwningStmtResult
2766TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
2767 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
2768 if (Result.isInvalid())
2769 return SemaRef.StmtError();
2770
2771 // FIXME: We always rebuild the return statement because there is no way
2772 // to tell whether the return type of the function has changed.
2773 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
2774}
2775
2776template<typename Derived>
2777Sema::OwningStmtResult
2778TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
2779 bool DeclChanged = false;
2780 llvm::SmallVector<Decl *, 4> Decls;
2781 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
2782 D != DEnd; ++D) {
2783 Decl *Transformed = getDerived().TransformDefinition(*D);
2784 if (!Transformed)
2785 return SemaRef.StmtError();
2786
2787 if (Transformed != *D)
2788 DeclChanged = true;
2789
2790 Decls.push_back(Transformed);
2791 }
2792
2793 if (!getDerived().AlwaysRebuild() && !DeclChanged)
2794 return SemaRef.Owned(S->Retain());
2795
2796 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
2797 S->getStartLoc(), S->getEndLoc());
2798}
2799
2800template<typename Derived>
2801Sema::OwningStmtResult
2802TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
2803 assert(false && "SwitchCase is abstract and cannot be transformed");
2804 return SemaRef.Owned(S->Retain());
2805}
2806
2807template<typename Derived>
2808Sema::OwningStmtResult
2809TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
2810 // FIXME: Implement!
2811 assert(false && "Inline assembly cannot be transformed");
2812 return SemaRef.Owned(S->Retain());
2813}
2814
2815
2816template<typename Derived>
2817Sema::OwningStmtResult
2818TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
2819 // FIXME: Implement this
2820 assert(false && "Cannot transform an Objective-C @try statement");
2821 return SemaRef.Owned(S->Retain());
2822}
2823
2824template<typename Derived>
2825Sema::OwningStmtResult
2826TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
2827 // FIXME: Implement this
2828 assert(false && "Cannot transform an Objective-C @catch statement");
2829 return SemaRef.Owned(S->Retain());
2830}
2831
2832template<typename Derived>
2833Sema::OwningStmtResult
2834TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
2835 // FIXME: Implement this
2836 assert(false && "Cannot transform an Objective-C @finally statement");
2837 return SemaRef.Owned(S->Retain());
2838}
2839
2840template<typename Derived>
2841Sema::OwningStmtResult
2842TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
2843 // FIXME: Implement this
2844 assert(false && "Cannot transform an Objective-C @throw statement");
2845 return SemaRef.Owned(S->Retain());
2846}
2847
2848template<typename Derived>
2849Sema::OwningStmtResult
2850TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
2851 ObjCAtSynchronizedStmt *S) {
2852 // FIXME: Implement this
2853 assert(false && "Cannot transform an Objective-C @synchronized statement");
2854 return SemaRef.Owned(S->Retain());
2855}
2856
2857template<typename Derived>
2858Sema::OwningStmtResult
2859TreeTransform<Derived>::TransformObjCForCollectionStmt(
2860 ObjCForCollectionStmt *S) {
2861 // FIXME: Implement this
2862 assert(false && "Cannot transform an Objective-C for-each statement");
2863 return SemaRef.Owned(S->Retain());
2864}
2865
2866
2867template<typename Derived>
2868Sema::OwningStmtResult
2869TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
2870 // Transform the exception declaration, if any.
2871 VarDecl *Var = 0;
2872 if (S->getExceptionDecl()) {
2873 VarDecl *ExceptionDecl = S->getExceptionDecl();
2874 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
2875 ExceptionDecl->getDeclName());
2876
2877 QualType T = getDerived().TransformType(ExceptionDecl->getType());
2878 if (T.isNull())
2879 return SemaRef.StmtError();
2880
2881 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
2882 T,
2883 ExceptionDecl->getDeclaratorInfo(),
2884 ExceptionDecl->getIdentifier(),
2885 ExceptionDecl->getLocation(),
2886 /*FIXME: Inaccurate*/
2887 SourceRange(ExceptionDecl->getLocation()));
2888 if (!Var || Var->isInvalidDecl()) {
2889 if (Var)
2890 Var->Destroy(SemaRef.Context);
2891 return SemaRef.StmtError();
2892 }
2893 }
2894
2895 // Transform the actual exception handler.
2896 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
2897 if (Handler.isInvalid()) {
2898 if (Var)
2899 Var->Destroy(SemaRef.Context);
2900 return SemaRef.StmtError();
2901 }
2902
2903 if (!getDerived().AlwaysRebuild() &&
2904 !Var &&
2905 Handler.get() == S->getHandlerBlock())
2906 return SemaRef.Owned(S->Retain());
2907
2908 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
2909 Var,
2910 move(Handler));
2911}
2912
2913template<typename Derived>
2914Sema::OwningStmtResult
2915TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
2916 // Transform the try block itself.
2917 OwningStmtResult TryBlock
2918 = getDerived().TransformCompoundStmt(S->getTryBlock());
2919 if (TryBlock.isInvalid())
2920 return SemaRef.StmtError();
2921
2922 // Transform the handlers.
2923 bool HandlerChanged = false;
2924 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
2925 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
2926 OwningStmtResult Handler
2927 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
2928 if (Handler.isInvalid())
2929 return SemaRef.StmtError();
2930
2931 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
2932 Handlers.push_back(Handler.takeAs<Stmt>());
2933 }
2934
2935 if (!getDerived().AlwaysRebuild() &&
2936 TryBlock.get() == S->getTryBlock() &&
2937 !HandlerChanged)
2938 return SemaRef.Owned(S->Retain());
2939
2940 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
2941 move_arg(Handlers));
2942}
2943
2944//===----------------------------------------------------------------------===//
Douglas Gregorb98b1992009-08-11 05:31:07 +00002945// Expression transformation
2946//===----------------------------------------------------------------------===//
2947template<typename Derived>
2948Sema::OwningExprResult
2949TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
2950 return SemaRef.Owned(E->Retain());
2951}
2952
2953template<typename Derived>
2954Sema::OwningExprResult
2955TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
2956 NamedDecl *ND
2957 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
2958 if (!ND)
2959 return SemaRef.ExprError();
2960
2961 if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
2962 return SemaRef.Owned(E->Retain());
2963
2964 return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
2965}
2966
2967template<typename Derived>
2968Sema::OwningExprResult
2969TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
2970 return SemaRef.Owned(E->Retain());
2971}
2972
2973template<typename Derived>
2974Sema::OwningExprResult
2975TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
2976 return SemaRef.Owned(E->Retain());
2977}
2978
2979template<typename Derived>
2980Sema::OwningExprResult
2981TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
2982 return SemaRef.Owned(E->Retain());
2983}
2984
2985template<typename Derived>
2986Sema::OwningExprResult
2987TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
2988 return SemaRef.Owned(E->Retain());
2989}
2990
2991template<typename Derived>
2992Sema::OwningExprResult
2993TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
2994 return SemaRef.Owned(E->Retain());
2995}
2996
2997template<typename Derived>
2998Sema::OwningExprResult
2999TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
3000 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3001 if (SubExpr.isInvalid())
3002 return SemaRef.ExprError();
3003
3004 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
3005 return SemaRef.Owned(E->Retain());
3006
3007 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
3008 E->getRParen());
3009}
3010
3011template<typename Derived>
3012Sema::OwningExprResult
3013TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
3014 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3015 if (SubExpr.isInvalid())
3016 return SemaRef.ExprError();
3017
3018 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
3019 return SemaRef.Owned(E->Retain());
3020
3021 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3022 E->getOpcode(),
3023 move(SubExpr));
3024}
3025
3026template<typename Derived>
3027Sema::OwningExprResult
3028TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
3029 if (E->isArgumentType()) {
3030 QualType T = getDerived().TransformType(E->getArgumentType());
3031 if (T.isNull())
3032 return SemaRef.ExprError();
3033
3034 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3035 return SemaRef.Owned(E->Retain());
3036
3037 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3038 E->isSizeOf(),
3039 E->getSourceRange());
3040 }
3041
3042 Sema::OwningExprResult SubExpr(SemaRef);
3043 {
3044 // C++0x [expr.sizeof]p1:
3045 // The operand is either an expression, which is an unevaluated operand
3046 // [...]
3047 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
3048
3049 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3050 if (SubExpr.isInvalid())
3051 return SemaRef.ExprError();
3052
3053 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3054 return SemaRef.Owned(E->Retain());
3055 }
3056
3057 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3058 E->isSizeOf(),
3059 E->getSourceRange());
3060}
3061
3062template<typename Derived>
3063Sema::OwningExprResult
3064TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3065 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3066 if (LHS.isInvalid())
3067 return SemaRef.ExprError();
3068
3069 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3070 if (RHS.isInvalid())
3071 return SemaRef.ExprError();
3072
3073
3074 if (!getDerived().AlwaysRebuild() &&
3075 LHS.get() == E->getLHS() &&
3076 RHS.get() == E->getRHS())
3077 return SemaRef.Owned(E->Retain());
3078
3079 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3080 /*FIXME:*/E->getLHS()->getLocStart(),
3081 move(RHS),
3082 E->getRBracketLoc());
3083}
3084
3085template<typename Derived>
3086Sema::OwningExprResult
3087TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3088 // Transform the callee.
3089 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3090 if (Callee.isInvalid())
3091 return SemaRef.ExprError();
3092
3093 // Transform arguments.
3094 bool ArgChanged = false;
3095 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3096 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3097 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3098 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3099 if (Arg.isInvalid())
3100 return SemaRef.ExprError();
3101
3102 // FIXME: Wrong source location information for the ','.
3103 FakeCommaLocs.push_back(
3104 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
3105
3106 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
3107 Args.push_back(Arg.takeAs<Expr>());
3108 }
3109
3110 if (!getDerived().AlwaysRebuild() &&
3111 Callee.get() == E->getCallee() &&
3112 !ArgChanged)
3113 return SemaRef.Owned(E->Retain());
3114
3115 // FIXME: Wrong source location information for the '('.
3116 SourceLocation FakeLParenLoc
3117 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3118 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3119 move_arg(Args),
3120 FakeCommaLocs.data(),
3121 E->getRParenLoc());
3122}
3123
3124template<typename Derived>
3125Sema::OwningExprResult
3126TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
3127 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3128 if (Base.isInvalid())
3129 return SemaRef.ExprError();
3130
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003131 NestedNameSpecifier *Qualifier = 0;
3132 if (E->hasQualifier()) {
3133 Qualifier
3134 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3135 E->getQualifierRange());
Douglas Gregorc4bf26f2009-09-01 00:37:14 +00003136 if (Qualifier == 0)
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003137 return SemaRef.ExprError();
3138 }
3139
Douglas Gregorb98b1992009-08-11 05:31:07 +00003140 NamedDecl *Member
3141 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3142 if (!Member)
3143 return SemaRef.ExprError();
3144
3145 if (!getDerived().AlwaysRebuild() &&
3146 Base.get() == E->getBase() &&
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003147 Qualifier == E->getQualifier() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00003148 Member == E->getMemberDecl())
3149 return SemaRef.Owned(E->Retain());
3150
3151 // FIXME: Bogus source location for the operator
3152 SourceLocation FakeOperatorLoc
3153 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3154
3155 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3156 E->isArrow(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003157 Qualifier,
3158 E->getQualifierRange(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003159 E->getMemberLoc(),
3160 Member);
3161}
3162
3163template<typename Derived>
3164Sema::OwningExprResult
3165TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3166 assert(false && "Cannot transform abstract class");
3167 return SemaRef.Owned(E->Retain());
3168}
3169
3170template<typename Derived>
3171Sema::OwningExprResult
3172TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
3173 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3174 if (LHS.isInvalid())
3175 return SemaRef.ExprError();
3176
3177 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3178 if (RHS.isInvalid())
3179 return SemaRef.ExprError();
3180
3181 if (!getDerived().AlwaysRebuild() &&
3182 LHS.get() == E->getLHS() &&
3183 RHS.get() == E->getRHS())
3184 return SemaRef.Owned(E->Retain());
3185
3186 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3187 move(LHS), move(RHS));
3188}
3189
3190template<typename Derived>
3191Sema::OwningExprResult
3192TreeTransform<Derived>::TransformCompoundAssignOperator(
3193 CompoundAssignOperator *E) {
3194 return getDerived().TransformBinaryOperator(E);
3195}
3196
3197template<typename Derived>
3198Sema::OwningExprResult
3199TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
3200 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3201 if (Cond.isInvalid())
3202 return SemaRef.ExprError();
3203
3204 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3205 if (LHS.isInvalid())
3206 return SemaRef.ExprError();
3207
3208 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3209 if (RHS.isInvalid())
3210 return SemaRef.ExprError();
3211
3212 if (!getDerived().AlwaysRebuild() &&
3213 Cond.get() == E->getCond() &&
3214 LHS.get() == E->getLHS() &&
3215 RHS.get() == E->getRHS())
3216 return SemaRef.Owned(E->Retain());
3217
Douglas Gregorb98b1992009-08-11 05:31:07 +00003218 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003219 E->getQuestionLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003220 move(LHS),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003221 E->getColonLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003222 move(RHS));
3223}
3224
3225template<typename Derived>
3226Sema::OwningExprResult
3227TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
3228 QualType T = getDerived().TransformType(E->getType());
3229 if (T.isNull())
3230 return SemaRef.ExprError();
3231
3232 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3233 if (SubExpr.isInvalid())
3234 return SemaRef.ExprError();
3235
3236 if (!getDerived().AlwaysRebuild() &&
3237 T == E->getType() &&
3238 SubExpr.get() == E->getSubExpr())
3239 return SemaRef.Owned(E->Retain());
3240
3241 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
3242 move(SubExpr),
3243 E->isLvalueCast());
3244}
3245
3246template<typename Derived>
3247Sema::OwningExprResult
3248TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3249 assert(false && "Cannot transform abstract class");
3250 return SemaRef.Owned(E->Retain());
3251}
3252
3253template<typename Derived>
3254Sema::OwningExprResult
3255TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
3256 QualType T;
3257 {
3258 // FIXME: Source location isn't quite accurate.
3259 SourceLocation TypeStartLoc
3260 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3261 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
3262
3263 T = getDerived().TransformType(E->getTypeAsWritten());
3264 if (T.isNull())
3265 return SemaRef.ExprError();
3266 }
3267
3268 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3269 if (SubExpr.isInvalid())
3270 return SemaRef.ExprError();
3271
3272 if (!getDerived().AlwaysRebuild() &&
3273 T == E->getTypeAsWritten() &&
3274 SubExpr.get() == E->getSubExpr())
3275 return SemaRef.Owned(E->Retain());
3276
3277 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3278 E->getRParenLoc(),
3279 move(SubExpr));
3280}
3281
3282template<typename Derived>
3283Sema::OwningExprResult
3284TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3285 QualType T;
3286 {
3287 // FIXME: Source location isn't quite accurate.
3288 SourceLocation FakeTypeLoc
3289 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3290 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
3291
3292 T = getDerived().TransformType(E->getType());
3293 if (T.isNull())
3294 return SemaRef.ExprError();
3295 }
3296
3297 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3298 if (Init.isInvalid())
3299 return SemaRef.ExprError();
3300
3301 if (!getDerived().AlwaysRebuild() &&
3302 T == E->getType() &&
3303 Init.get() == E->getInitializer())
3304 return SemaRef.Owned(E->Retain());
3305
3306 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3307 /*FIXME:*/E->getInitializer()->getLocEnd(),
3308 move(Init));
3309}
3310
3311template<typename Derived>
3312Sema::OwningExprResult
3313TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
3314 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3315 if (Base.isInvalid())
3316 return SemaRef.ExprError();
3317
3318 if (!getDerived().AlwaysRebuild() &&
3319 Base.get() == E->getBase())
3320 return SemaRef.Owned(E->Retain());
3321
3322 // FIXME: Bad source location
3323 SourceLocation FakeOperatorLoc
3324 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3325 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3326 E->getAccessorLoc(),
3327 E->getAccessor());
3328}
3329
3330template<typename Derived>
3331Sema::OwningExprResult
3332TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
3333 bool InitChanged = false;
3334
3335 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3336 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3337 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3338 if (Init.isInvalid())
3339 return SemaRef.ExprError();
3340
3341 InitChanged = InitChanged || Init.get() != E->getInit(I);
3342 Inits.push_back(Init.takeAs<Expr>());
3343 }
3344
3345 if (!getDerived().AlwaysRebuild() && !InitChanged)
3346 return SemaRef.Owned(E->Retain());
3347
3348 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3349 E->getRBraceLoc());
3350}
3351
3352template<typename Derived>
3353Sema::OwningExprResult
3354TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
3355 Designation Desig;
3356
Douglas Gregor43959a92009-08-20 07:17:43 +00003357 // transform the initializer value
Douglas Gregorb98b1992009-08-11 05:31:07 +00003358 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3359 if (Init.isInvalid())
3360 return SemaRef.ExprError();
3361
Douglas Gregor43959a92009-08-20 07:17:43 +00003362 // transform the designators.
Douglas Gregorb98b1992009-08-11 05:31:07 +00003363 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3364 bool ExprChanged = false;
3365 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3366 DEnd = E->designators_end();
3367 D != DEnd; ++D) {
3368 if (D->isFieldDesignator()) {
3369 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3370 D->getDotLoc(),
3371 D->getFieldLoc()));
3372 continue;
3373 }
3374
3375 if (D->isArrayDesignator()) {
3376 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3377 if (Index.isInvalid())
3378 return SemaRef.ExprError();
3379
3380 Desig.AddDesignator(Designator::getArray(Index.get(),
3381 D->getLBracketLoc()));
3382
3383 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3384 ArrayExprs.push_back(Index.release());
3385 continue;
3386 }
3387
3388 assert(D->isArrayRangeDesignator() && "New kind of designator?");
3389 OwningExprResult Start
3390 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3391 if (Start.isInvalid())
3392 return SemaRef.ExprError();
3393
3394 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3395 if (End.isInvalid())
3396 return SemaRef.ExprError();
3397
3398 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
3399 End.get(),
3400 D->getLBracketLoc(),
3401 D->getEllipsisLoc()));
3402
3403 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3404 End.get() != E->getArrayRangeEnd(*D);
3405
3406 ArrayExprs.push_back(Start.release());
3407 ArrayExprs.push_back(End.release());
3408 }
3409
3410 if (!getDerived().AlwaysRebuild() &&
3411 Init.get() == E->getInit() &&
3412 !ExprChanged)
3413 return SemaRef.Owned(E->Retain());
3414
3415 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3416 E->getEqualOrColonLoc(),
3417 E->usesGNUSyntax(), move(Init));
3418}
3419
3420template<typename Derived>
3421Sema::OwningExprResult
3422TreeTransform<Derived>::TransformImplicitValueInitExpr(
3423 ImplicitValueInitExpr *E) {
3424 QualType T = getDerived().TransformType(E->getType());
3425 if (T.isNull())
3426 return SemaRef.ExprError();
3427
3428 if (!getDerived().AlwaysRebuild() &&
3429 T == E->getType())
3430 return SemaRef.Owned(E->Retain());
3431
3432 return getDerived().RebuildImplicitValueInitExpr(T);
3433}
3434
3435template<typename Derived>
3436Sema::OwningExprResult
3437TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3438 // FIXME: Do we want the type as written?
3439 QualType T;
3440
3441 {
3442 // FIXME: Source location isn't quite accurate.
3443 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3444 T = getDerived().TransformType(E->getType());
3445 if (T.isNull())
3446 return SemaRef.ExprError();
3447 }
3448
3449 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3450 if (SubExpr.isInvalid())
3451 return SemaRef.ExprError();
3452
3453 if (!getDerived().AlwaysRebuild() &&
3454 T == E->getType() &&
3455 SubExpr.get() == E->getSubExpr())
3456 return SemaRef.Owned(E->Retain());
3457
3458 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3459 T, E->getRParenLoc());
3460}
3461
3462template<typename Derived>
3463Sema::OwningExprResult
3464TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3465 bool ArgumentChanged = false;
3466 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3467 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3468 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3469 if (Init.isInvalid())
3470 return SemaRef.ExprError();
3471
3472 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3473 Inits.push_back(Init.takeAs<Expr>());
3474 }
3475
3476 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3477 move_arg(Inits),
3478 E->getRParenLoc());
3479}
3480
3481/// \brief Transform an address-of-label expression.
3482///
3483/// By default, the transformation of an address-of-label expression always
3484/// rebuilds the expression, so that the label identifier can be resolved to
3485/// the corresponding label statement by semantic analysis.
3486template<typename Derived>
3487Sema::OwningExprResult
3488TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
3489 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3490 E->getLabel());
3491}
3492
3493template<typename Derived>
3494Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
3495 OwningStmtResult SubStmt
3496 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3497 if (SubStmt.isInvalid())
3498 return SemaRef.ExprError();
3499
3500 if (!getDerived().AlwaysRebuild() &&
3501 SubStmt.get() == E->getSubStmt())
3502 return SemaRef.Owned(E->Retain());
3503
3504 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
3505 move(SubStmt),
3506 E->getRParenLoc());
3507}
3508
3509template<typename Derived>
3510Sema::OwningExprResult
3511TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
3512 QualType T1, T2;
3513 {
3514 // FIXME: Source location isn't quite accurate.
3515 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3516
3517 T1 = getDerived().TransformType(E->getArgType1());
3518 if (T1.isNull())
3519 return SemaRef.ExprError();
3520
3521 T2 = getDerived().TransformType(E->getArgType2());
3522 if (T2.isNull())
3523 return SemaRef.ExprError();
3524 }
3525
3526 if (!getDerived().AlwaysRebuild() &&
3527 T1 == E->getArgType1() &&
3528 T2 == E->getArgType2())
3529 return SemaRef.Owned(E->Retain());
3530
3531 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3532 T1, T2, E->getRParenLoc());
3533}
3534
3535template<typename Derived>
3536Sema::OwningExprResult
3537TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
3538 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3539 if (Cond.isInvalid())
3540 return SemaRef.ExprError();
3541
3542 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3543 if (LHS.isInvalid())
3544 return SemaRef.ExprError();
3545
3546 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3547 if (RHS.isInvalid())
3548 return SemaRef.ExprError();
3549
3550 if (!getDerived().AlwaysRebuild() &&
3551 Cond.get() == E->getCond() &&
3552 LHS.get() == E->getLHS() &&
3553 RHS.get() == E->getRHS())
3554 return SemaRef.Owned(E->Retain());
3555
3556 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3557 move(Cond), move(LHS), move(RHS),
3558 E->getRParenLoc());
3559}
3560
3561template<typename Derived>
3562Sema::OwningExprResult
3563TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3564 return SemaRef.Owned(E->Retain());
3565}
3566
3567template<typename Derived>
3568Sema::OwningExprResult
3569TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3570 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3571 if (Callee.isInvalid())
3572 return SemaRef.ExprError();
3573
3574 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3575 if (First.isInvalid())
3576 return SemaRef.ExprError();
3577
3578 OwningExprResult Second(SemaRef);
3579 if (E->getNumArgs() == 2) {
3580 Second = getDerived().TransformExpr(E->getArg(1));
3581 if (Second.isInvalid())
3582 return SemaRef.ExprError();
3583 }
3584
3585 if (!getDerived().AlwaysRebuild() &&
3586 Callee.get() == E->getCallee() &&
3587 First.get() == E->getArg(0) &&
3588 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3589 return SemaRef.Owned(E->Retain());
3590
3591 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3592 E->getOperatorLoc(),
3593 move(Callee),
3594 move(First),
3595 move(Second));
3596}
3597
3598template<typename Derived>
3599Sema::OwningExprResult
3600TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
3601 return getDerived().TransformCallExpr(E);
3602}
3603
3604template<typename Derived>
3605Sema::OwningExprResult
3606TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3607 QualType ExplicitTy;
3608 {
3609 // FIXME: Source location isn't quite accurate.
3610 SourceLocation TypeStartLoc
3611 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3612 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
3613
3614 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3615 if (ExplicitTy.isNull())
3616 return SemaRef.ExprError();
3617 }
3618
3619 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3620 if (SubExpr.isInvalid())
3621 return SemaRef.ExprError();
3622
3623 if (!getDerived().AlwaysRebuild() &&
3624 ExplicitTy == E->getTypeAsWritten() &&
3625 SubExpr.get() == E->getSubExpr())
3626 return SemaRef.Owned(E->Retain());
3627
3628 // FIXME: Poor source location information here.
3629 SourceLocation FakeLAngleLoc
3630 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3631 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3632 SourceLocation FakeRParenLoc
3633 = SemaRef.PP.getLocForEndOfToken(
3634 E->getSubExpr()->getSourceRange().getEnd());
3635 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
3636 E->getStmtClass(),
3637 FakeLAngleLoc,
3638 ExplicitTy,
3639 FakeRAngleLoc,
3640 FakeRAngleLoc,
3641 move(SubExpr),
3642 FakeRParenLoc);
3643}
3644
3645template<typename Derived>
3646Sema::OwningExprResult
3647TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
3648 return getDerived().TransformCXXNamedCastExpr(E);
3649}
3650
3651template<typename Derived>
3652Sema::OwningExprResult
3653TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
3654 return getDerived().TransformCXXNamedCastExpr(E);
3655}
3656
3657template<typename Derived>
3658Sema::OwningExprResult
3659TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
3660 CXXReinterpretCastExpr *E) {
3661 return getDerived().TransformCXXNamedCastExpr(E);
3662}
3663
3664template<typename Derived>
3665Sema::OwningExprResult
3666TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
3667 return getDerived().TransformCXXNamedCastExpr(E);
3668}
3669
3670template<typename Derived>
3671Sema::OwningExprResult
3672TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
3673 CXXFunctionalCastExpr *E) {
3674 QualType ExplicitTy;
3675 {
3676 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3677
3678 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3679 if (ExplicitTy.isNull())
3680 return SemaRef.ExprError();
3681 }
3682
3683 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3684 if (SubExpr.isInvalid())
3685 return SemaRef.ExprError();
3686
3687 if (!getDerived().AlwaysRebuild() &&
3688 ExplicitTy == E->getTypeAsWritten() &&
3689 SubExpr.get() == E->getSubExpr())
3690 return SemaRef.Owned(E->Retain());
3691
3692 // FIXME: The end of the type's source range is wrong
3693 return getDerived().RebuildCXXFunctionalCastExpr(
3694 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
3695 ExplicitTy,
3696 /*FIXME:*/E->getSubExpr()->getLocStart(),
3697 move(SubExpr),
3698 E->getRParenLoc());
3699}
3700
3701template<typename Derived>
3702Sema::OwningExprResult
3703TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
3704 if (E->isTypeOperand()) {
3705 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3706
3707 QualType T = getDerived().TransformType(E->getTypeOperand());
3708 if (T.isNull())
3709 return SemaRef.ExprError();
3710
3711 if (!getDerived().AlwaysRebuild() &&
3712 T == E->getTypeOperand())
3713 return SemaRef.Owned(E->Retain());
3714
3715 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3716 /*FIXME:*/E->getLocStart(),
3717 T,
3718 E->getLocEnd());
3719 }
3720
3721 // We don't know whether the expression is potentially evaluated until
3722 // after we perform semantic analysis, so the expression is potentially
3723 // potentially evaluated.
3724 EnterExpressionEvaluationContext Unevaluated(SemaRef,
3725 Action::PotentiallyPotentiallyEvaluated);
3726
3727 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
3728 if (SubExpr.isInvalid())
3729 return SemaRef.ExprError();
3730
3731 if (!getDerived().AlwaysRebuild() &&
3732 SubExpr.get() == E->getExprOperand())
3733 return SemaRef.Owned(E->Retain());
3734
3735 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3736 /*FIXME:*/E->getLocStart(),
3737 move(SubExpr),
3738 E->getLocEnd());
3739}
3740
3741template<typename Derived>
3742Sema::OwningExprResult
3743TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
3744 return SemaRef.Owned(E->Retain());
3745}
3746
3747template<typename Derived>
3748Sema::OwningExprResult
3749TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
3750 CXXNullPtrLiteralExpr *E) {
3751 return SemaRef.Owned(E->Retain());
3752}
3753
3754template<typename Derived>
3755Sema::OwningExprResult
3756TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
3757 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3758
3759 QualType T = getDerived().TransformType(E->getType());
3760 if (T.isNull())
3761 return SemaRef.ExprError();
3762
3763 if (!getDerived().AlwaysRebuild() &&
3764 T == E->getType())
3765 return SemaRef.Owned(E->Retain());
3766
3767 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
3768}
3769
3770template<typename Derived>
3771Sema::OwningExprResult
3772TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
3773 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3774 if (SubExpr.isInvalid())
3775 return SemaRef.ExprError();
3776
3777 if (!getDerived().AlwaysRebuild() &&
3778 SubExpr.get() == E->getSubExpr())
3779 return SemaRef.Owned(E->Retain());
3780
3781 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
3782}
3783
3784template<typename Derived>
3785Sema::OwningExprResult
3786TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
3787 ParmVarDecl *Param
3788 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
3789 if (!Param)
3790 return SemaRef.ExprError();
3791
3792 if (getDerived().AlwaysRebuild() &&
3793 Param == E->getParam())
3794 return SemaRef.Owned(E->Retain());
3795
3796 return getDerived().RebuildCXXDefaultArgExpr(Param);
3797}
3798
3799template<typename Derived>
3800Sema::OwningExprResult
3801TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
3802 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3803
3804 QualType T = getDerived().TransformType(E->getType());
3805 if (T.isNull())
3806 return SemaRef.ExprError();
3807
3808 if (!getDerived().AlwaysRebuild() &&
3809 T == E->getType())
3810 return SemaRef.Owned(E->Retain());
3811
3812 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
3813 /*FIXME:*/E->getTypeBeginLoc(),
3814 T,
3815 E->getRParenLoc());
3816}
3817
3818template<typename Derived>
3819Sema::OwningExprResult
3820TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
3821 VarDecl *Var
Douglas Gregor43959a92009-08-20 07:17:43 +00003822 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregorb98b1992009-08-11 05:31:07 +00003823 if (!Var)
3824 return SemaRef.ExprError();
3825
3826 if (!getDerived().AlwaysRebuild() &&
3827 Var == E->getVarDecl())
3828 return SemaRef.Owned(E->Retain());
3829
3830 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
3831 /*FIXME:*/E->getStartLoc(),
3832 Var);
3833}
3834
3835template<typename Derived>
3836Sema::OwningExprResult
3837TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
3838 // Transform the type that we're allocating
3839 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3840 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
3841 if (AllocType.isNull())
3842 return SemaRef.ExprError();
3843
3844 // Transform the size of the array we're allocating (if any).
3845 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
3846 if (ArraySize.isInvalid())
3847 return SemaRef.ExprError();
3848
3849 // Transform the placement arguments (if any).
3850 bool ArgumentChanged = false;
3851 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
3852 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
3853 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
3854 if (Arg.isInvalid())
3855 return SemaRef.ExprError();
3856
3857 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
3858 PlacementArgs.push_back(Arg.take());
3859 }
3860
Douglas Gregor43959a92009-08-20 07:17:43 +00003861 // transform the constructor arguments (if any).
Douglas Gregorb98b1992009-08-11 05:31:07 +00003862 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
3863 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
3864 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
3865 if (Arg.isInvalid())
3866 return SemaRef.ExprError();
3867
3868 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
3869 ConstructorArgs.push_back(Arg.take());
3870 }
3871
3872 if (!getDerived().AlwaysRebuild() &&
3873 AllocType == E->getAllocatedType() &&
3874 ArraySize.get() == E->getArraySize() &&
3875 !ArgumentChanged)
3876 return SemaRef.Owned(E->Retain());
3877
3878 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
3879 E->isGlobalNew(),
3880 /*FIXME:*/E->getLocStart(),
3881 move_arg(PlacementArgs),
3882 /*FIXME:*/E->getLocStart(),
3883 E->isParenTypeId(),
3884 AllocType,
3885 /*FIXME:*/E->getLocStart(),
3886 /*FIXME:*/SourceRange(),
3887 move(ArraySize),
3888 /*FIXME:*/E->getLocStart(),
3889 move_arg(ConstructorArgs),
3890 E->getLocEnd());
3891}
3892
3893template<typename Derived>
3894Sema::OwningExprResult
3895TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
3896 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
3897 if (Operand.isInvalid())
3898 return SemaRef.ExprError();
3899
3900 if (!getDerived().AlwaysRebuild() &&
3901 Operand.get() == E->getArgument())
3902 return SemaRef.Owned(E->Retain());
3903
3904 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
3905 E->isGlobalDelete(),
3906 E->isArrayForm(),
3907 move(Operand));
3908}
3909
3910template<typename Derived>
3911Sema::OwningExprResult
Douglas Gregora71d8192009-09-04 17:36:40 +00003912TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
3913 CXXPseudoDestructorExpr *E) {
3914 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3915 if (Base.isInvalid())
3916 return SemaRef.ExprError();
3917
3918 NestedNameSpecifier *Qualifier
3919 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3920 E->getQualifierRange());
3921 if (E->getQualifier() && !Qualifier)
3922 return SemaRef.ExprError();
3923
3924 QualType DestroyedType;
3925 {
3926 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
3927 DestroyedType = getDerived().TransformType(E->getDestroyedType());
3928 if (DestroyedType.isNull())
3929 return SemaRef.ExprError();
3930 }
3931
3932 if (!getDerived().AlwaysRebuild() &&
3933 Base.get() == E->getBase() &&
3934 Qualifier == E->getQualifier() &&
3935 DestroyedType == E->getDestroyedType())
3936 return SemaRef.Owned(E->Retain());
3937
3938 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
3939 E->getOperatorLoc(),
3940 E->isArrow(),
3941 E->getDestroyedTypeLoc(),
3942 DestroyedType,
3943 Qualifier,
3944 E->getQualifierRange());
3945}
3946
3947template<typename Derived>
3948Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00003949TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
3950 UnresolvedFunctionNameExpr *E) {
3951 // There is no transformation we can apply to an unresolved function name.
3952 return SemaRef.Owned(E->Retain());
3953}
3954
3955template<typename Derived>
3956Sema::OwningExprResult
3957TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
3958 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3959
3960 QualType T = getDerived().TransformType(E->getQueriedType());
3961 if (T.isNull())
3962 return SemaRef.ExprError();
3963
3964 if (!getDerived().AlwaysRebuild() &&
3965 T == E->getQueriedType())
3966 return SemaRef.Owned(E->Retain());
3967
3968 // FIXME: Bad location information
3969 SourceLocation FakeLParenLoc
3970 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
3971
3972 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
3973 E->getLocStart(),
3974 /*FIXME:*/FakeLParenLoc,
3975 T,
3976 E->getLocEnd());
3977}
3978
3979template<typename Derived>
3980Sema::OwningExprResult
3981TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
3982 NestedNameSpecifier *NNS
3983 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3984 E->getQualifierRange());
3985 if (!NNS)
3986 return SemaRef.ExprError();
3987
3988 NamedDecl *ND
3989 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3990 if (!ND)
3991 return SemaRef.ExprError();
3992
3993 if (!getDerived().AlwaysRebuild() &&
3994 NNS == E->getQualifier() &&
3995 ND == E->getDecl())
3996 return SemaRef.Owned(E->Retain());
3997
3998 return getDerived().RebuildQualifiedDeclRefExpr(NNS,
3999 E->getQualifierRange(),
4000 ND,
4001 E->getLocation(),
4002 /*FIXME:*/false);
4003}
4004
4005template<typename Derived>
4006Sema::OwningExprResult
4007TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
4008 UnresolvedDeclRefExpr *E) {
4009 NestedNameSpecifier *NNS
4010 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4011 E->getQualifierRange());
4012 if (!NNS)
4013 return SemaRef.ExprError();
4014
Douglas Gregor81499bb2009-09-03 22:13:48 +00004015 DeclarationName Name
4016 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4017 if (!Name)
4018 return SemaRef.ExprError();
Douglas Gregorb98b1992009-08-11 05:31:07 +00004019
4020 if (!getDerived().AlwaysRebuild() &&
4021 NNS == E->getQualifier() &&
4022 Name == E->getDeclName())
4023 return SemaRef.Owned(E->Retain());
4024
4025 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
4026 E->getQualifierRange(),
4027 Name,
4028 E->getLocation(),
4029 /*FIXME:*/false);
4030}
4031
4032template<typename Derived>
4033Sema::OwningExprResult
4034TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
4035 TemplateName Template
4036 = getDerived().TransformTemplateName(E->getTemplateName());
4037 if (Template.isNull())
4038 return SemaRef.ExprError();
4039
4040 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4041 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
4042 TemplateArgument TransArg
4043 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4044 if (TransArg.isNull())
4045 return SemaRef.ExprError();
4046
4047 TransArgs.push_back(TransArg);
4048 }
4049
4050 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4051 // compare template arguments (yet).
4052
4053 // FIXME: It's possible that we'll find out now that the template name
4054 // actually refers to a type, in which case the caller is actually dealing
4055 // with a functional cast. Give a reasonable error message!
4056 return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
4057 E->getLAngleLoc(),
4058 TransArgs.data(),
4059 TransArgs.size(),
4060 E->getRAngleLoc());
4061}
4062
4063template<typename Derived>
4064Sema::OwningExprResult
4065TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
4066 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4067
4068 QualType T = getDerived().TransformType(E->getType());
4069 if (T.isNull())
4070 return SemaRef.ExprError();
4071
4072 CXXConstructorDecl *Constructor
4073 = cast_or_null<CXXConstructorDecl>(
4074 getDerived().TransformDecl(E->getConstructor()));
4075 if (!Constructor)
4076 return SemaRef.ExprError();
4077
4078 bool ArgumentChanged = false;
4079 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4080 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
4081 ArgEnd = E->arg_end();
4082 Arg != ArgEnd; ++Arg) {
4083 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4084 if (TransArg.isInvalid())
4085 return SemaRef.ExprError();
4086
4087 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4088 Args.push_back(TransArg.takeAs<Expr>());
4089 }
4090
4091 if (!getDerived().AlwaysRebuild() &&
4092 T == E->getType() &&
4093 Constructor == E->getConstructor() &&
4094 !ArgumentChanged)
4095 return SemaRef.Owned(E->Retain());
4096
4097 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4098 move_arg(Args));
4099}
4100
4101/// \brief Transform a C++ temporary-binding expression.
4102///
4103/// The transformation of a temporary-binding expression always attempts to
4104/// bind a new temporary variable to its subexpression, even if the
4105/// subexpression itself did not change, because the temporary variable itself
4106/// must be unique.
4107template<typename Derived>
4108Sema::OwningExprResult
4109TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4110 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4111 if (SubExpr.isInvalid())
4112 return SemaRef.ExprError();
4113
4114 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4115}
4116
4117/// \brief Transform a C++ expression that contains temporaries that should
4118/// be destroyed after the expression is evaluated.
4119///
4120/// The transformation of a full expression always attempts to build a new
4121/// CXXExprWithTemporaries expression, even if the
4122/// subexpression itself did not change, because it will need to capture the
4123/// the new temporary variables introduced in the subexpression.
4124template<typename Derived>
4125Sema::OwningExprResult
4126TreeTransform<Derived>::TransformCXXExprWithTemporaries(
4127 CXXExprWithTemporaries *E) {
4128 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4129 if (SubExpr.isInvalid())
4130 return SemaRef.ExprError();
4131
4132 return SemaRef.Owned(
4133 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4134 E->shouldDestroyTemporaries()));
4135}
4136
4137template<typename Derived>
4138Sema::OwningExprResult
4139TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
4140 CXXTemporaryObjectExpr *E) {
4141 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4142 QualType T = getDerived().TransformType(E->getType());
4143 if (T.isNull())
4144 return SemaRef.ExprError();
4145
4146 CXXConstructorDecl *Constructor
4147 = cast_or_null<CXXConstructorDecl>(
4148 getDerived().TransformDecl(E->getConstructor()));
4149 if (!Constructor)
4150 return SemaRef.ExprError();
4151
4152 bool ArgumentChanged = false;
4153 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4154 Args.reserve(E->getNumArgs());
4155 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
4156 ArgEnd = E->arg_end();
4157 Arg != ArgEnd; ++Arg) {
4158 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4159 if (TransArg.isInvalid())
4160 return SemaRef.ExprError();
4161
4162 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4163 Args.push_back((Expr *)TransArg.release());
4164 }
4165
4166 if (!getDerived().AlwaysRebuild() &&
4167 T == E->getType() &&
4168 Constructor == E->getConstructor() &&
4169 !ArgumentChanged)
4170 return SemaRef.Owned(E->Retain());
4171
4172 // FIXME: Bogus location information
4173 SourceLocation CommaLoc;
4174 if (Args.size() > 1) {
4175 Expr *First = (Expr *)Args[0];
4176 CommaLoc
4177 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4178 }
4179 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4180 T,
4181 /*FIXME:*/E->getTypeBeginLoc(),
4182 move_arg(Args),
4183 &CommaLoc,
4184 E->getLocEnd());
4185}
4186
4187template<typename Derived>
4188Sema::OwningExprResult
4189TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
4190 CXXUnresolvedConstructExpr *E) {
4191 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4192 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4193 if (T.isNull())
4194 return SemaRef.ExprError();
4195
4196 bool ArgumentChanged = false;
4197 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4198 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4199 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4200 ArgEnd = E->arg_end();
4201 Arg != ArgEnd; ++Arg) {
4202 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4203 if (TransArg.isInvalid())
4204 return SemaRef.ExprError();
4205
4206 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4207 FakeCommaLocs.push_back(
4208 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4209 Args.push_back(TransArg.takeAs<Expr>());
4210 }
4211
4212 if (!getDerived().AlwaysRebuild() &&
4213 T == E->getTypeAsWritten() &&
4214 !ArgumentChanged)
4215 return SemaRef.Owned(E->Retain());
4216
4217 // FIXME: we're faking the locations of the commas
4218 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4219 T,
4220 E->getLParenLoc(),
4221 move_arg(Args),
4222 FakeCommaLocs.data(),
4223 E->getRParenLoc());
4224}
Douglas Gregorbd4c4ae2009-08-26 22:36:53 +00004225
Douglas Gregorb98b1992009-08-11 05:31:07 +00004226template<typename Derived>
4227Sema::OwningExprResult
4228TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
4229 CXXUnresolvedMemberExpr *E) {
4230 // Transform the base of the expression.
4231 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4232 if (Base.isInvalid())
4233 return SemaRef.ExprError();
4234
Douglas Gregora38c6872009-09-03 16:14:30 +00004235 Sema::TypeTy *ObjectType = 0;
4236 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
4237 E->getOperatorLoc(),
4238 E->isArrow()? tok::arrow : tok::period,
4239 ObjectType);
4240 if (Base.isInvalid())
4241 return SemaRef.ExprError();
4242
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004243 // FIXME: The first qualifier found might be a template type parameter,
4244 // in which case there is no transformed declaration to refer to (it might
4245 // refer to a built-in type!).
Douglas Gregorc68afe22009-09-03 21:38:09 +00004246 NamedDecl *FirstQualifierInScope
4247 = cast_or_null<NamedDecl>(
4248 getDerived().TransformDecl(E->getFirstQualifierFoundInScope()));
4249
Douglas Gregora38c6872009-09-03 16:14:30 +00004250 NestedNameSpecifier *Qualifier = 0;
4251 if (E->getQualifier()) {
4252 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4253 E->getQualifierRange(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00004254 QualType::getFromOpaquePtr(ObjectType),
4255 FirstQualifierInScope);
Douglas Gregora38c6872009-09-03 16:14:30 +00004256 if (!Qualifier)
4257 return SemaRef.ExprError();
4258 }
4259
Douglas Gregor81499bb2009-09-03 22:13:48 +00004260 DeclarationName Name
4261 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc());
4262 if (!Name)
4263 return SemaRef.ExprError();
4264
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004265 if (!E->hasExplicitTemplateArgumentList()) {
4266 // This is a reference to a member without an explicitly-specified
4267 // template argument list. Optimize for this common case.
4268 if (!getDerived().AlwaysRebuild() &&
4269 Base.get() == E->getBase() &&
4270 Qualifier == E->getQualifier() &&
4271 Name == E->getMember() &&
4272 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
4273 return SemaRef.Owned(E->Retain());
4274
4275 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4276 E->isArrow(),
4277 E->getOperatorLoc(),
4278 Qualifier,
4279 E->getQualifierRange(),
4280 Name,
4281 E->getMemberLoc(),
4282 FirstQualifierInScope);
4283 }
4284
4285 // FIXME: This is an ugly hack, which forces the same template name to
4286 // be looked up multiple times. Yuck!
4287 // FIXME: This also won't work for, e.g., x->template operator+<int>
4288 TemplateName OrigTemplateName
4289 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
4290
4291 TemplateName Template
4292 = getDerived().TransformTemplateName(OrigTemplateName,
4293 QualType::getFromOpaquePtr(ObjectType));
4294 if (Template.isNull())
4295 return SemaRef.ExprError();
4296
4297 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4298 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
4299 TemplateArgument TransArg
4300 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4301 if (TransArg.isNull())
4302 return SemaRef.ExprError();
4303
4304 TransArgs.push_back(TransArg);
4305 }
Douglas Gregora38c6872009-09-03 16:14:30 +00004306
Douglas Gregorb98b1992009-08-11 05:31:07 +00004307 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4308 E->isArrow(),
4309 E->getOperatorLoc(),
Douglas Gregora38c6872009-09-03 16:14:30 +00004310 Qualifier,
4311 E->getQualifierRange(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004312 Template,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004313 E->getMemberLoc(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004314 FirstQualifierInScope,
4315 E->getLAngleLoc(),
4316 TransArgs.data(),
4317 TransArgs.size(),
4318 E->getRAngleLoc());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004319}
4320
4321template<typename Derived>
4322Sema::OwningExprResult
4323TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4324 return SemaRef.Owned(E->Retain());
4325}
4326
4327template<typename Derived>
4328Sema::OwningExprResult
4329TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
4330 // FIXME: poor source location
4331 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4332 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4333 if (EncodedType.isNull())
4334 return SemaRef.ExprError();
4335
4336 if (!getDerived().AlwaysRebuild() &&
4337 EncodedType == E->getEncodedType())
4338 return SemaRef.Owned(E->Retain());
4339
4340 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4341 EncodedType,
4342 E->getRParenLoc());
4343}
4344
4345template<typename Derived>
4346Sema::OwningExprResult
4347TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
4348 // FIXME: Implement this!
4349 assert(false && "Cannot transform Objective-C expressions yet");
4350 return SemaRef.Owned(E->Retain());
4351}
4352
4353template<typename Derived>
4354Sema::OwningExprResult
4355TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4356 return SemaRef.Owned(E->Retain());
4357}
4358
4359template<typename Derived>
4360Sema::OwningExprResult
4361TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4362 ObjCProtocolDecl *Protocol
4363 = cast_or_null<ObjCProtocolDecl>(
4364 getDerived().TransformDecl(E->getProtocol()));
4365 if (!Protocol)
4366 return SemaRef.ExprError();
4367
4368 if (!getDerived().AlwaysRebuild() &&
4369 Protocol == E->getProtocol())
4370 return SemaRef.Owned(E->Retain());
4371
4372 return getDerived().RebuildObjCProtocolExpr(Protocol,
4373 E->getAtLoc(),
4374 /*FIXME:*/E->getAtLoc(),
4375 /*FIXME:*/E->getAtLoc(),
4376 E->getRParenLoc());
4377
4378}
4379
4380template<typename Derived>
4381Sema::OwningExprResult
4382TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
4383 // FIXME: Implement this!
4384 assert(false && "Cannot transform Objective-C expressions yet");
4385 return SemaRef.Owned(E->Retain());
4386}
4387
4388template<typename Derived>
4389Sema::OwningExprResult
4390TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4391 // FIXME: Implement this!
4392 assert(false && "Cannot transform Objective-C expressions yet");
4393 return SemaRef.Owned(E->Retain());
4394}
4395
4396template<typename Derived>
4397Sema::OwningExprResult
Fariborz Jahanian09105f52009-08-20 17:02:02 +00004398TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
4399 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004400 // FIXME: Implement this!
4401 assert(false && "Cannot transform Objective-C expressions yet");
4402 return SemaRef.Owned(E->Retain());
4403}
4404
4405template<typename Derived>
4406Sema::OwningExprResult
4407TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
4408 // FIXME: Implement this!
4409 assert(false && "Cannot transform Objective-C expressions yet");
4410 return SemaRef.Owned(E->Retain());
4411}
4412
4413template<typename Derived>
4414Sema::OwningExprResult
4415TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
4416 // FIXME: Implement this!
4417 assert(false && "Cannot transform Objective-C expressions yet");
4418 return SemaRef.Owned(E->Retain());
4419}
4420
4421template<typename Derived>
4422Sema::OwningExprResult
4423TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
4424 bool ArgumentChanged = false;
4425 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4426 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4427 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4428 if (SubExpr.isInvalid())
4429 return SemaRef.ExprError();
4430
4431 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4432 SubExprs.push_back(SubExpr.takeAs<Expr>());
4433 }
4434
4435 if (!getDerived().AlwaysRebuild() &&
4436 !ArgumentChanged)
4437 return SemaRef.Owned(E->Retain());
4438
4439 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4440 move_arg(SubExprs),
4441 E->getRParenLoc());
4442}
4443
4444template<typename Derived>
4445Sema::OwningExprResult
4446TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
4447 // FIXME: Implement this!
4448 assert(false && "Cannot transform block expressions yet");
4449 return SemaRef.Owned(E->Retain());
4450}
4451
4452template<typename Derived>
4453Sema::OwningExprResult
4454TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
4455 // FIXME: Implement this!
4456 assert(false && "Cannot transform block-related expressions yet");
4457 return SemaRef.Owned(E->Retain());
4458}
4459
4460//===----------------------------------------------------------------------===//
Douglas Gregor577f75a2009-08-04 16:50:30 +00004461// Type reconstruction
4462//===----------------------------------------------------------------------===//
4463
4464template<typename Derived>
4465QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
4466 return SemaRef.BuildPointerType(PointeeType, 0,
4467 getDerived().getBaseLocation(),
4468 getDerived().getBaseEntity());
4469}
4470
4471template<typename Derived>
4472QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
4473 return SemaRef.BuildBlockPointerType(PointeeType, 0,
4474 getDerived().getBaseLocation(),
4475 getDerived().getBaseEntity());
4476}
4477
4478template<typename Derived>
4479QualType
4480TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
4481 return SemaRef.BuildReferenceType(ReferentType, true, 0,
4482 getDerived().getBaseLocation(),
4483 getDerived().getBaseEntity());
4484}
4485
4486template<typename Derived>
4487QualType
4488TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
4489 return SemaRef.BuildReferenceType(ReferentType, false, 0,
4490 getDerived().getBaseLocation(),
4491 getDerived().getBaseEntity());
4492}
4493
4494template<typename Derived>
4495QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
4496 QualType ClassType) {
4497 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
4498 getDerived().getBaseLocation(),
4499 getDerived().getBaseEntity());
4500}
4501
4502template<typename Derived>
4503QualType
4504TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4505 ArrayType::ArraySizeModifier SizeMod,
4506 const llvm::APInt *Size,
4507 Expr *SizeExpr,
4508 unsigned IndexTypeQuals,
4509 SourceRange BracketsRange) {
4510 if (SizeExpr || !Size)
4511 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4512 IndexTypeQuals, BracketsRange,
4513 getDerived().getBaseEntity());
4514
4515 QualType Types[] = {
4516 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4517 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4518 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
4519 };
4520 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4521 QualType SizeType;
4522 for (unsigned I = 0; I != NumTypes; ++I)
4523 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4524 SizeType = Types[I];
4525 break;
4526 }
4527
4528 if (SizeType.isNull())
4529 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
4530
4531 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
4532 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
4533 IndexTypeQuals, BracketsRange,
4534 getDerived().getBaseEntity());
4535}
4536
4537template<typename Derived>
4538QualType
4539TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
4540 ArrayType::ArraySizeModifier SizeMod,
4541 const llvm::APInt &Size,
4542 unsigned IndexTypeQuals) {
4543 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
4544 IndexTypeQuals, SourceRange());
4545}
4546
4547template<typename Derived>
4548QualType
4549TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
4550 ArrayType::ArraySizeModifier SizeMod,
4551 const llvm::APInt &Size,
4552 Expr *SizeExpr,
4553 unsigned IndexTypeQuals,
4554 SourceRange BracketsRange) {
4555 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
4556 IndexTypeQuals, BracketsRange);
4557}
4558
4559template<typename Derived>
4560QualType
4561TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
4562 QualType ElementType,
4563 ArrayType::ArraySizeModifier SizeMod,
4564 const llvm::APInt &Size,
4565 unsigned IndexTypeQuals) {
4566 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
4567 IndexTypeQuals, SourceRange());
4568}
4569
4570template<typename Derived>
4571QualType
4572TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
4573 ArrayType::ArraySizeModifier SizeMod,
4574 unsigned IndexTypeQuals) {
4575 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
4576 IndexTypeQuals, SourceRange());
4577}
4578
4579template<typename Derived>
4580QualType
4581TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
4582 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004583 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004584 unsigned IndexTypeQuals,
4585 SourceRange BracketsRange) {
4586 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
4587 SizeExpr.takeAs<Expr>(),
4588 IndexTypeQuals, BracketsRange);
4589}
4590
4591template<typename Derived>
4592QualType
4593TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
4594 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004595 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004596 unsigned IndexTypeQuals,
4597 SourceRange BracketsRange) {
4598 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
4599 SizeExpr.takeAs<Expr>(),
4600 IndexTypeQuals, BracketsRange);
4601}
4602
4603template<typename Derived>
4604QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4605 unsigned NumElements) {
4606 // FIXME: semantic checking!
4607 return SemaRef.Context.getVectorType(ElementType, NumElements);
4608}
4609
4610template<typename Derived>
4611QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4612 unsigned NumElements,
4613 SourceLocation AttributeLoc) {
4614 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4615 NumElements, true);
4616 IntegerLiteral *VectorSize
4617 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
4618 AttributeLoc);
4619 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4620 AttributeLoc);
4621}
4622
4623template<typename Derived>
4624QualType
4625TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004626 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00004627 SourceLocation AttributeLoc) {
4628 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4629}
4630
4631template<typename Derived>
4632QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
4633 QualType *ParamTypes,
4634 unsigned NumParamTypes,
4635 bool Variadic,
4636 unsigned Quals) {
4637 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
4638 Quals,
4639 getDerived().getBaseLocation(),
4640 getDerived().getBaseEntity());
4641}
4642
4643template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00004644QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00004645 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4646}
4647
4648template<typename Derived>
4649QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4650 return SemaRef.Context.getTypeOfType(Underlying);
4651}
4652
4653template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00004654QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00004655 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4656}
4657
4658template<typename Derived>
4659QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4660 TemplateName Template,
4661 const TemplateArgument *Args,
4662 unsigned NumArgs) {
4663 // FIXME: Missing source locations for the template name, <, >.
4664 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
4665 SourceLocation(), Args, NumArgs,
4666 SourceLocation());
4667}
4668
Douglas Gregordcee1a12009-08-06 05:28:30 +00004669template<typename Derived>
4670NestedNameSpecifier *
4671TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4672 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00004673 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004674 QualType ObjectType,
4675 NamedDecl *FirstQualifierInScope) {
Douglas Gregordcee1a12009-08-06 05:28:30 +00004676 CXXScopeSpec SS;
4677 // FIXME: The source location information is all wrong.
4678 SS.setRange(Range);
4679 SS.setScopeRep(Prefix);
4680 return static_cast<NestedNameSpecifier *>(
Douglas Gregorc68afe22009-09-03 21:38:09 +00004681 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregor495c35d2009-08-25 22:51:20 +00004682 Range.getEnd(), II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004683 ObjectType,
4684 FirstQualifierInScope,
Douglas Gregor495c35d2009-08-25 22:51:20 +00004685 false));
Douglas Gregordcee1a12009-08-06 05:28:30 +00004686}
4687
4688template<typename Derived>
4689NestedNameSpecifier *
4690TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4691 SourceRange Range,
4692 NamespaceDecl *NS) {
4693 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
4694}
4695
4696template<typename Derived>
4697NestedNameSpecifier *
4698TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4699 SourceRange Range,
4700 bool TemplateKW,
4701 QualType T) {
4702 if (T->isDependentType() || T->isRecordType() ||
4703 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
4704 assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
4705 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
4706 T.getTypePtr());
4707 }
4708
4709 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
4710 return 0;
4711}
4712
Douglas Gregord1067e52009-08-06 06:41:21 +00004713template<typename Derived>
4714TemplateName
4715TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4716 bool TemplateKW,
4717 TemplateDecl *Template) {
4718 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
4719 Template);
4720}
4721
4722template<typename Derived>
4723TemplateName
4724TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4725 bool TemplateKW,
4726 OverloadedFunctionDecl *Ovl) {
4727 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
4728}
4729
4730template<typename Derived>
4731TemplateName
4732TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004733 const IdentifierInfo &II,
4734 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00004735 CXXScopeSpec SS;
4736 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004737 SS.setScopeRep(Qualifier);
4738 return getSema().ActOnDependentTemplateName(
4739 /*FIXME:*/getDerived().getBaseLocation(),
4740 II,
4741 /*FIXME:*/getDerived().getBaseLocation(),
4742 SS,
4743 ObjectType.getAsOpaquePtr())
4744 .template getAsVal<TemplateName>();
Douglas Gregord1067e52009-08-06 06:41:21 +00004745}
Douglas Gregorb98b1992009-08-11 05:31:07 +00004746
4747template<typename Derived>
4748Sema::OwningExprResult
4749TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
4750 SourceLocation OpLoc,
4751 ExprArg Callee,
4752 ExprArg First,
4753 ExprArg Second) {
4754 Expr *FirstExpr = (Expr *)First.get();
4755 Expr *SecondExpr = (Expr *)Second.get();
4756 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
4757
4758 // Determine whether this should be a builtin operation.
4759 if (SecondExpr == 0 || isPostIncDec) {
4760 if (!FirstExpr->getType()->isOverloadableType()) {
4761 // The argument is not of overloadable type, so try to create a
4762 // built-in unary operation.
4763 UnaryOperator::Opcode Opc
4764 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4765
4766 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
4767 }
4768 } else {
4769 if (!FirstExpr->getType()->isOverloadableType() &&
4770 !SecondExpr->getType()->isOverloadableType()) {
4771 // Neither of the arguments is an overloadable type, so try to
4772 // create a built-in binary operation.
4773 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
4774 OwningExprResult Result
4775 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
4776 if (Result.isInvalid())
4777 return SemaRef.ExprError();
4778
4779 First.release();
4780 Second.release();
4781 return move(Result);
4782 }
4783 }
4784
4785 // Compute the transformed set of functions (and function templates) to be
4786 // used during overload resolution.
4787 Sema::FunctionSet Functions;
4788
Douglas Gregor8f1d89e2009-09-01 16:58:52 +00004789 DeclRefExpr *DRE
4790 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004791
4792 // FIXME: Do we have to check
4793 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor8f1d89e2009-09-01 16:58:52 +00004794 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregorb98b1992009-08-11 05:31:07 +00004795 Functions.insert(*F);
4796
4797 // Add any functions found via argument-dependent lookup.
4798 Expr *Args[2] = { FirstExpr, SecondExpr };
4799 unsigned NumArgs = 1 + (SecondExpr != 0);
4800 DeclarationName OpName
4801 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
4802 SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
4803
4804 // Create the overloaded operator invocation for unary operators.
4805 if (NumArgs == 1 || isPostIncDec) {
4806 UnaryOperator::Opcode Opc
4807 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4808 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
4809 }
4810
4811 // Create the overloaded operator invocation for binary operators.
4812 BinaryOperator::Opcode Opc =
4813 BinaryOperator::getOverloadedOpcode(Op);
4814 OwningExprResult Result
4815 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
4816 if (Result.isInvalid())
4817 return SemaRef.ExprError();
4818
4819 First.release();
4820 Second.release();
4821 return move(Result);
4822}
Douglas Gregord1067e52009-08-06 06:41:21 +00004823
Douglas Gregor577f75a2009-08-04 16:50:30 +00004824} // end namespace clang
4825
4826#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H