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