blob: 22e01ab581411711abf44c596256a77ccacd8846 [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
Douglas Gregor3e368512009-09-04 17:36:40 +0000786 /// \brief Build a new pseudo-destructor 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 RebuildCXXPseudoDestructorExpr(ExprArg Base,
791 SourceLocation OperatorLoc,
792 bool isArrow,
793 SourceLocation DestroyedTypeLoc,
794 QualType DestroyedType,
795 NestedNameSpecifier *Qualifier,
796 SourceRange QualifierRange) {
797 CXXScopeSpec SS;
798 if (Qualifier) {
799 SS.setRange(QualifierRange);
800 SS.setScopeRep(Qualifier);
801 }
802
803 DeclarationName Name
804 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
805 SemaRef.Context.getCanonicalType(DestroyedType));
806
807 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
808 OperatorLoc,
809 isArrow? tok::arrow : tok::period,
810 DestroyedTypeLoc,
811 Name,
812 Sema::DeclPtrTy::make((Decl *)0),
813 &SS);
814 }
815
Douglas Gregor9d879762009-08-11 05:31:07 +0000816 /// \brief Build a new unary operator expression.
817 ///
818 /// By default, performs semantic analysis to build the new expression.
819 /// Subclasses may override this routine to provide different behavior.
820 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
821 UnaryOperator::Opcode Opc,
822 ExprArg SubExpr) {
823 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
824 }
825
826 /// \brief Build a new sizeof or alignof expression with a type argument.
827 ///
828 /// By default, performs semantic analysis to build the new expression.
829 /// Subclasses may override this routine to provide different behavior.
830 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
831 bool isSizeOf, SourceRange R) {
832 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
833 }
834
835 /// \brief Build a new sizeof or alignof expression with an expression
836 /// argument.
837 ///
838 /// By default, performs semantic analysis to build the new expression.
839 /// Subclasses may override this routine to provide different behavior.
840 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
841 bool isSizeOf, SourceRange R) {
842 OwningExprResult Result
843 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
844 OpLoc, isSizeOf, R);
845 if (Result.isInvalid())
846 return getSema().ExprError();
847
848 SubExpr.release();
849 return move(Result);
850 }
851
852 /// \brief Build a new array subscript expression.
853 ///
854 /// By default, performs semantic analysis to build the new expression.
855 /// Subclasses may override this routine to provide different behavior.
856 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
857 SourceLocation LBracketLoc,
858 ExprArg RHS,
859 SourceLocation RBracketLoc) {
860 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
861 LBracketLoc, move(RHS),
862 RBracketLoc);
863 }
864
865 /// \brief Build a new call expression.
866 ///
867 /// By default, performs semantic analysis to build the new expression.
868 /// Subclasses may override this routine to provide different behavior.
869 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
870 MultiExprArg Args,
871 SourceLocation *CommaLocs,
872 SourceLocation RParenLoc) {
873 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
874 move(Args), CommaLocs, RParenLoc);
875 }
876
877 /// \brief Build a new member access expression.
878 ///
879 /// By default, performs semantic analysis to build the new expression.
880 /// Subclasses may override this routine to provide different behavior.
881 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Douglas Gregorc1991bf2009-08-31 23:41:50 +0000882 bool isArrow,
883 NestedNameSpecifier *Qualifier,
884 SourceRange QualifierRange,
885 SourceLocation MemberLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +0000886 NamedDecl *Member) {
Anders Carlsson20c55142009-09-01 04:26:58 +0000887 if (!Member->getDeclName()) {
888 // We have a reference to an unnamed field.
889 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
890
891 MemberExpr *ME =
892 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
893 Member, MemberLoc,
894 cast<FieldDecl>(Member)->getType());
895 return getSema().Owned(ME);
896 }
897
Douglas Gregorc1991bf2009-08-31 23:41:50 +0000898 CXXScopeSpec SS;
899 if (Qualifier) {
900 SS.setRange(QualifierRange);
901 SS.setScopeRep(Qualifier);
902 }
903
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +0000904 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +0000905 isArrow? tok::arrow : tok::period,
906 MemberLoc,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +0000907 Member->getDeclName(),
Douglas Gregorc1991bf2009-08-31 23:41:50 +0000908 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
909 &SS);
Douglas Gregor9d879762009-08-11 05:31:07 +0000910 }
911
912 /// \brief Build a new binary operator expression.
913 ///
914 /// By default, performs semantic analysis to build the new expression.
915 /// Subclasses may override this routine to provide different behavior.
916 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
917 BinaryOperator::Opcode Opc,
918 ExprArg LHS, ExprArg RHS) {
919 OwningExprResult Result
920 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
921 (Expr *)RHS.get());
922 if (Result.isInvalid())
923 return SemaRef.ExprError();
924
925 LHS.release();
926 RHS.release();
927 return move(Result);
928 }
929
930 /// \brief Build a new conditional operator expression.
931 ///
932 /// By default, performs semantic analysis to build the new expression.
933 /// Subclasses may override this routine to provide different behavior.
934 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
935 SourceLocation QuestionLoc,
936 ExprArg LHS,
937 SourceLocation ColonLoc,
938 ExprArg RHS) {
939 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
940 move(LHS), move(RHS));
941 }
942
943 /// \brief Build a new implicit cast expression.
944 ///
945 /// By default, builds a new implicit cast without any semantic analysis.
946 /// Subclasses may override this routine to provide different behavior.
947 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
948 ExprArg SubExpr, bool isLvalue) {
949 ImplicitCastExpr *ICE
950 = new (getSema().Context) ImplicitCastExpr(T, Kind,
951 (Expr *)SubExpr.release(),
952 isLvalue);
953 return getSema().Owned(ICE);
954 }
955
956 /// \brief Build a new C-style cast expression.
957 ///
958 /// By default, performs semantic analysis to build the new expression.
959 /// Subclasses may override this routine to provide different behavior.
960 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
961 QualType ExplicitTy,
962 SourceLocation RParenLoc,
963 ExprArg SubExpr) {
964 return getSema().ActOnCastExpr(/*Scope=*/0,
965 LParenLoc,
966 ExplicitTy.getAsOpaquePtr(),
967 RParenLoc,
968 move(SubExpr));
969 }
970
971 /// \brief Build a new compound literal expression.
972 ///
973 /// By default, performs semantic analysis to build the new expression.
974 /// Subclasses may override this routine to provide different behavior.
975 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
976 QualType T,
977 SourceLocation RParenLoc,
978 ExprArg Init) {
979 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
980 RParenLoc, move(Init));
981 }
982
983 /// \brief Build a new extended vector element access expression.
984 ///
985 /// By default, performs semantic analysis to build the new expression.
986 /// Subclasses may override this routine to provide different behavior.
987 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
988 SourceLocation OpLoc,
989 SourceLocation AccessorLoc,
990 IdentifierInfo &Accessor) {
991 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
992 tok::period, AccessorLoc,
993 Accessor,
994 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
995 }
996
997 /// \brief Build a new initializer list expression.
998 ///
999 /// By default, performs semantic analysis to build the new expression.
1000 /// Subclasses may override this routine to provide different behavior.
1001 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1002 MultiExprArg Inits,
1003 SourceLocation RBraceLoc) {
1004 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1005 }
1006
1007 /// \brief Build a new designated initializer expression.
1008 ///
1009 /// By default, performs semantic analysis to build the new expression.
1010 /// Subclasses may override this routine to provide different behavior.
1011 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1012 MultiExprArg ArrayExprs,
1013 SourceLocation EqualOrColonLoc,
1014 bool GNUSyntax,
1015 ExprArg Init) {
1016 OwningExprResult Result
1017 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1018 move(Init));
1019 if (Result.isInvalid())
1020 return SemaRef.ExprError();
1021
1022 ArrayExprs.release();
1023 return move(Result);
1024 }
1025
1026 /// \brief Build a new value-initialized expression.
1027 ///
1028 /// By default, builds the implicit value initialization without performing
1029 /// any semantic analysis. Subclasses may override this routine to provide
1030 /// different behavior.
1031 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1032 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1033 }
1034
1035 /// \brief Build a new \c va_arg expression.
1036 ///
1037 /// By default, performs semantic analysis to build the new expression.
1038 /// Subclasses may override this routine to provide different behavior.
1039 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1040 QualType T, SourceLocation RParenLoc) {
1041 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
1042 RParenLoc);
1043 }
1044
1045 /// \brief Build a new expression list in parentheses.
1046 ///
1047 /// By default, performs semantic analysis to build the new expression.
1048 /// Subclasses may override this routine to provide different behavior.
1049 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1050 MultiExprArg SubExprs,
1051 SourceLocation RParenLoc) {
1052 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1053 }
1054
1055 /// \brief Build a new address-of-label expression.
1056 ///
1057 /// By default, performs semantic analysis, using the name of the label
1058 /// rather than attempting to map the label statement itself.
1059 /// Subclasses may override this routine to provide different behavior.
1060 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1061 SourceLocation LabelLoc,
1062 LabelStmt *Label) {
1063 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1064 }
1065
1066 /// \brief Build a new GNU statement expression.
1067 ///
1068 /// By default, performs semantic analysis to build the new expression.
1069 /// Subclasses may override this routine to provide different behavior.
1070 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1071 StmtArg SubStmt,
1072 SourceLocation RParenLoc) {
1073 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1074 }
1075
1076 /// \brief Build a new __builtin_types_compatible_p expression.
1077 ///
1078 /// By default, performs semantic analysis to build the new expression.
1079 /// Subclasses may override this routine to provide different behavior.
1080 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1081 QualType T1, QualType T2,
1082 SourceLocation RParenLoc) {
1083 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1084 T1.getAsOpaquePtr(),
1085 T2.getAsOpaquePtr(),
1086 RParenLoc);
1087 }
1088
1089 /// \brief Build a new __builtin_choose_expr expression.
1090 ///
1091 /// By default, performs semantic analysis to build the new expression.
1092 /// Subclasses may override this routine to provide different behavior.
1093 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1094 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1095 SourceLocation RParenLoc) {
1096 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1097 move(Cond), move(LHS), move(RHS),
1098 RParenLoc);
1099 }
1100
1101 /// \brief Build a new overloaded operator call expression.
1102 ///
1103 /// By default, performs semantic analysis to build the new expression.
1104 /// The semantic analysis provides the behavior of template instantiation,
1105 /// copying with transformations that turn what looks like an overloaded
1106 /// operator call into a use of a builtin operator, performing
1107 /// argument-dependent lookup, etc. Subclasses may override this routine to
1108 /// provide different behavior.
1109 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1110 SourceLocation OpLoc,
1111 ExprArg Callee,
1112 ExprArg First,
1113 ExprArg Second);
1114
1115 /// \brief Build a new C++ "named" cast expression, such as static_cast or
1116 /// reinterpret_cast.
1117 ///
1118 /// By default, this routine dispatches to one of the more-specific routines
1119 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
1120 /// Subclasses may override this routine to provide different behavior.
1121 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1122 Stmt::StmtClass Class,
1123 SourceLocation LAngleLoc,
1124 QualType T,
1125 SourceLocation RAngleLoc,
1126 SourceLocation LParenLoc,
1127 ExprArg SubExpr,
1128 SourceLocation RParenLoc) {
1129 switch (Class) {
1130 case Stmt::CXXStaticCastExprClass:
1131 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1132 RAngleLoc, LParenLoc,
1133 move(SubExpr), RParenLoc);
1134
1135 case Stmt::CXXDynamicCastExprClass:
1136 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1137 RAngleLoc, LParenLoc,
1138 move(SubExpr), RParenLoc);
1139
1140 case Stmt::CXXReinterpretCastExprClass:
1141 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1142 RAngleLoc, LParenLoc,
1143 move(SubExpr),
1144 RParenLoc);
1145
1146 case Stmt::CXXConstCastExprClass:
1147 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1148 RAngleLoc, LParenLoc,
1149 move(SubExpr), RParenLoc);
1150
1151 default:
1152 assert(false && "Invalid C++ named cast");
1153 break;
1154 }
1155
1156 return getSema().ExprError();
1157 }
1158
1159 /// \brief Build a new C++ static_cast expression.
1160 ///
1161 /// By default, performs semantic analysis to build the new expression.
1162 /// Subclasses may override this routine to provide different behavior.
1163 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1164 SourceLocation LAngleLoc,
1165 QualType T,
1166 SourceLocation RAngleLoc,
1167 SourceLocation LParenLoc,
1168 ExprArg SubExpr,
1169 SourceLocation RParenLoc) {
1170 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
1171 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1172 LParenLoc, move(SubExpr), RParenLoc);
1173 }
1174
1175 /// \brief Build a new C++ dynamic_cast expression.
1176 ///
1177 /// By default, performs semantic analysis to build the new expression.
1178 /// Subclasses may override this routine to provide different behavior.
1179 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1180 SourceLocation LAngleLoc,
1181 QualType T,
1182 SourceLocation RAngleLoc,
1183 SourceLocation LParenLoc,
1184 ExprArg SubExpr,
1185 SourceLocation RParenLoc) {
1186 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
1187 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1188 LParenLoc, move(SubExpr), RParenLoc);
1189 }
1190
1191 /// \brief Build a new C++ reinterpret_cast expression.
1192 ///
1193 /// By default, performs semantic analysis to build the new expression.
1194 /// Subclasses may override this routine to provide different behavior.
1195 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1196 SourceLocation LAngleLoc,
1197 QualType T,
1198 SourceLocation RAngleLoc,
1199 SourceLocation LParenLoc,
1200 ExprArg SubExpr,
1201 SourceLocation RParenLoc) {
1202 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1203 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1204 LParenLoc, move(SubExpr), RParenLoc);
1205 }
1206
1207 /// \brief Build a new C++ const_cast expression.
1208 ///
1209 /// By default, performs semantic analysis to build the new expression.
1210 /// Subclasses may override this routine to provide different behavior.
1211 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1212 SourceLocation LAngleLoc,
1213 QualType T,
1214 SourceLocation RAngleLoc,
1215 SourceLocation LParenLoc,
1216 ExprArg SubExpr,
1217 SourceLocation RParenLoc) {
1218 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
1219 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1220 LParenLoc, move(SubExpr), RParenLoc);
1221 }
1222
1223 /// \brief Build a new C++ functional-style cast 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 RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1228 QualType T,
1229 SourceLocation LParenLoc,
1230 ExprArg SubExpr,
1231 SourceLocation RParenLoc) {
Chris Lattnercf9d6a02009-08-24 05:19:01 +00001232 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregor9d879762009-08-11 05:31:07 +00001233 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1234 T.getAsOpaquePtr(),
1235 LParenLoc,
Chris Lattnercf9d6a02009-08-24 05:19:01 +00001236 Sema::MultiExprArg(getSema(), &Sub, 1),
Douglas Gregor9d879762009-08-11 05:31:07 +00001237 /*CommaLocs=*/0,
1238 RParenLoc);
1239 }
1240
1241 /// \brief Build a new C++ typeid(type) expression.
1242 ///
1243 /// By default, performs semantic analysis to build the new expression.
1244 /// Subclasses may override this routine to provide different behavior.
1245 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1246 SourceLocation LParenLoc,
1247 QualType T,
1248 SourceLocation RParenLoc) {
1249 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
1250 T.getAsOpaquePtr(), RParenLoc);
1251 }
1252
1253 /// \brief Build a new C++ typeid(expr) expression.
1254 ///
1255 /// By default, performs semantic analysis to build the new expression.
1256 /// Subclasses may override this routine to provide different behavior.
1257 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1258 SourceLocation LParenLoc,
1259 ExprArg Operand,
1260 SourceLocation RParenLoc) {
1261 OwningExprResult Result
1262 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1263 RParenLoc);
1264 if (Result.isInvalid())
1265 return getSema().ExprError();
1266
1267 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1268 return move(Result);
1269 }
1270
1271 /// \brief Build a new C++ "this" expression.
1272 ///
1273 /// By default, builds a new "this" expression without performing any
1274 /// semantic analysis. Subclasses may override this routine to provide
1275 /// different behavior.
1276 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
1277 QualType ThisType) {
1278 return getSema().Owned(
1279 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1280 }
1281
1282 /// \brief Build a new C++ throw expression.
1283 ///
1284 /// By default, performs semantic analysis to build the new expression.
1285 /// Subclasses may override this routine to provide different behavior.
1286 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1287 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1288 }
1289
1290 /// \brief Build a new C++ default-argument expression.
1291 ///
1292 /// By default, builds a new default-argument expression, which does not
1293 /// require any semantic analysis. Subclasses may override this routine to
1294 /// provide different behavior.
1295 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlsson3d752db2009-08-14 18:30:22 +00001296 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregor9d879762009-08-11 05:31:07 +00001297 }
1298
1299 /// \brief Build a new C++ zero-initialization expression.
1300 ///
1301 /// By default, performs semantic analysis to build the new expression.
1302 /// Subclasses may override this routine to provide different behavior.
1303 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
1304 SourceLocation LParenLoc,
1305 QualType T,
1306 SourceLocation RParenLoc) {
1307 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1308 T.getAsOpaquePtr(), LParenLoc,
1309 MultiExprArg(getSema(), 0, 0),
1310 0, RParenLoc);
1311 }
1312
1313 /// \brief Build a new C++ conditional declaration expression.
1314 ///
1315 /// By default, performs semantic analysis to build the new expression.
1316 /// Subclasses may override this routine to provide different behavior.
1317 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
1318 SourceLocation EqLoc,
1319 VarDecl *Var) {
1320 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1321 EqLoc,
1322 Var));
1323 }
1324
1325 /// \brief Build a new C++ "new" expression.
1326 ///
1327 /// By default, performs semantic analysis to build the new expression.
1328 /// Subclasses may override this routine to provide different behavior.
1329 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
1330 bool UseGlobal,
1331 SourceLocation PlacementLParen,
1332 MultiExprArg PlacementArgs,
1333 SourceLocation PlacementRParen,
1334 bool ParenTypeId,
1335 QualType AllocType,
1336 SourceLocation TypeLoc,
1337 SourceRange TypeRange,
1338 ExprArg ArraySize,
1339 SourceLocation ConstructorLParen,
1340 MultiExprArg ConstructorArgs,
1341 SourceLocation ConstructorRParen) {
1342 return getSema().BuildCXXNew(StartLoc, UseGlobal,
1343 PlacementLParen,
1344 move(PlacementArgs),
1345 PlacementRParen,
1346 ParenTypeId,
1347 AllocType,
1348 TypeLoc,
1349 TypeRange,
1350 move(ArraySize),
1351 ConstructorLParen,
1352 move(ConstructorArgs),
1353 ConstructorRParen);
1354 }
1355
1356 /// \brief Build a new C++ "delete" expression.
1357 ///
1358 /// By default, performs semantic analysis to build the new expression.
1359 /// Subclasses may override this routine to provide different behavior.
1360 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1361 bool IsGlobalDelete,
1362 bool IsArrayForm,
1363 ExprArg Operand) {
1364 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1365 move(Operand));
1366 }
1367
1368 /// \brief Build a new unary type trait expression.
1369 ///
1370 /// By default, performs semantic analysis to build the new expression.
1371 /// Subclasses may override this routine to provide different behavior.
1372 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1373 SourceLocation StartLoc,
1374 SourceLocation LParenLoc,
1375 QualType T,
1376 SourceLocation RParenLoc) {
1377 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
1378 T.getAsOpaquePtr(), RParenLoc);
1379 }
1380
1381 /// \brief Build a new qualified declaration reference expression.
1382 ///
1383 /// By default, performs semantic analysis to build the new expression.
1384 /// Subclasses may override this routine to provide different behavior.
1385 OwningExprResult RebuildQualifiedDeclRefExpr(NestedNameSpecifier *NNS,
1386 SourceRange QualifierRange,
1387 NamedDecl *ND,
1388 SourceLocation Location,
1389 bool IsAddressOfOperand) {
1390 CXXScopeSpec SS;
1391 SS.setRange(QualifierRange);
1392 SS.setScopeRep(NNS);
1393 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
1394 Location,
1395 ND->getDeclName(),
1396 /*Trailing lparen=*/false,
1397 &SS,
1398 IsAddressOfOperand);
1399 }
1400
1401 /// \brief Build a new (previously unresolved) declaration reference
1402 /// expression.
1403 ///
1404 /// By default, performs semantic analysis to build the new expression.
1405 /// Subclasses may override this routine to provide different behavior.
1406 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1407 SourceRange QualifierRange,
1408 DeclarationName Name,
1409 SourceLocation Location,
1410 bool IsAddressOfOperand) {
1411 CXXScopeSpec SS;
1412 SS.setRange(QualifierRange);
1413 SS.setScopeRep(NNS);
1414 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
1415 Location,
1416 Name,
1417 /*Trailing lparen=*/false,
1418 &SS,
1419 IsAddressOfOperand);
1420 }
1421
1422 /// \brief Build a new template-id 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 RebuildTemplateIdExpr(TemplateName Template,
1427 SourceLocation TemplateLoc,
1428 SourceLocation LAngleLoc,
1429 TemplateArgument *TemplateArgs,
1430 unsigned NumTemplateArgs,
1431 SourceLocation RAngleLoc) {
1432 return getSema().BuildTemplateIdExpr(Template, TemplateLoc,
1433 LAngleLoc,
1434 TemplateArgs, NumTemplateArgs,
1435 RAngleLoc);
1436 }
1437
1438 /// \brief Build a new object-construction expression.
1439 ///
1440 /// By default, performs semantic analysis to build the new expression.
1441 /// Subclasses may override this routine to provide different behavior.
1442 OwningExprResult RebuildCXXConstructExpr(QualType T,
1443 CXXConstructorDecl *Constructor,
1444 bool IsElidable,
1445 MultiExprArg Args) {
1446 unsigned NumArgs = Args.size();
1447 Expr **ArgsExprs = (Expr **)Args.release();
Anders Carlsson665e4692009-08-25 05:12:04 +00001448 return getSema().BuildCXXConstructExpr(T, Constructor, IsElidable,
1449 ArgsExprs, NumArgs);
Douglas Gregor9d879762009-08-11 05:31:07 +00001450 }
1451
1452 /// \brief Build a new object-construction expression.
1453 ///
1454 /// By default, performs semantic analysis to build the new expression.
1455 /// Subclasses may override this routine to provide different behavior.
1456 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1457 QualType T,
1458 SourceLocation LParenLoc,
1459 MultiExprArg Args,
1460 SourceLocation *Commas,
1461 SourceLocation RParenLoc) {
1462 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1463 T.getAsOpaquePtr(),
1464 LParenLoc,
1465 move(Args),
1466 Commas,
1467 RParenLoc);
1468 }
1469
1470 /// \brief Build a new object-construction expression.
1471 ///
1472 /// By default, performs semantic analysis to build the new expression.
1473 /// Subclasses may override this routine to provide different behavior.
1474 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1475 QualType T,
1476 SourceLocation LParenLoc,
1477 MultiExprArg Args,
1478 SourceLocation *Commas,
1479 SourceLocation RParenLoc) {
1480 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1481 /*FIXME*/LParenLoc),
1482 T.getAsOpaquePtr(),
1483 LParenLoc,
1484 move(Args),
1485 Commas,
1486 RParenLoc);
1487 }
1488
1489 /// \brief Build a new member reference expression.
1490 ///
1491 /// By default, performs semantic analysis to build the new expression.
1492 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor6ffe7b42009-08-11 15:56:57 +00001493 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregor9d879762009-08-11 05:31:07 +00001494 bool IsArrow,
1495 SourceLocation OperatorLoc,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001496 NestedNameSpecifier *Qualifier,
1497 SourceRange QualifierRange,
Douglas Gregor9d879762009-08-11 05:31:07 +00001498 DeclarationName Name,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001499 SourceLocation MemberLoc,
1500 NamedDecl *FirstQualifierInScope) {
Douglas Gregor6ffe7b42009-08-11 15:56:57 +00001501 OwningExprResult Base = move(BaseE);
Douglas Gregor9d879762009-08-11 05:31:07 +00001502 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001503
Douglas Gregor9d879762009-08-11 05:31:07 +00001504 CXXScopeSpec SS;
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001505 SS.setRange(QualifierRange);
1506 SS.setScopeRep(Qualifier);
1507
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001508 Base = SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregor9d879762009-08-11 05:31:07 +00001509 move(Base), OperatorLoc, OpKind,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001510 MemberLoc,
1511 Name,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001512 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001513 &SS,
1514 FirstQualifierInScope);
Douglas Gregor9d879762009-08-11 05:31:07 +00001515 return move(Base);
1516 }
1517
1518 /// \brief Build a new Objective-C @encode expression.
1519 ///
1520 /// By default, performs semantic analysis to build the new expression.
1521 /// Subclasses may override this routine to provide different behavior.
1522 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1523 QualType T,
1524 SourceLocation RParenLoc) {
1525 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1526 RParenLoc));
1527 }
1528
1529 /// \brief Build a new Objective-C protocol expression.
1530 ///
1531 /// By default, performs semantic analysis to build the new expression.
1532 /// Subclasses may override this routine to provide different behavior.
1533 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1534 SourceLocation AtLoc,
1535 SourceLocation ProtoLoc,
1536 SourceLocation LParenLoc,
1537 SourceLocation RParenLoc) {
1538 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1539 Protocol->getIdentifier(),
1540 AtLoc,
1541 ProtoLoc,
1542 LParenLoc,
1543 RParenLoc));
1544 }
1545
1546 /// \brief Build a new shuffle vector expression.
1547 ///
1548 /// By default, performs semantic analysis to build the new expression.
1549 /// Subclasses may override this routine to provide different behavior.
1550 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1551 MultiExprArg SubExprs,
1552 SourceLocation RParenLoc) {
1553 // Find the declaration for __builtin_shufflevector
1554 const IdentifierInfo &Name
1555 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1556 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1557 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1558 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
1559
1560 // Build a reference to the __builtin_shufflevector builtin
1561 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
1562 Expr *Callee
1563 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1564 BuiltinLoc, false, false);
1565 SemaRef.UsualUnaryConversions(Callee);
1566
1567 // Build the CallExpr
1568 unsigned NumSubExprs = SubExprs.size();
1569 Expr **Subs = (Expr **)SubExprs.release();
1570 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1571 Subs, NumSubExprs,
1572 Builtin->getResultType(),
1573 RParenLoc);
1574 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
1575
1576 // Type-check the __builtin_shufflevector expression.
1577 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1578 if (Result.isInvalid())
1579 return SemaRef.ExprError();
1580
1581 OwnedCall.release();
1582 return move(Result);
1583 }
Douglas Gregor841324a2009-08-04 16:50:30 +00001584};
Douglas Gregor9d879762009-08-11 05:31:07 +00001585
Douglas Gregor23a44be2009-08-20 07:17:43 +00001586template<typename Derived>
1587Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1588 if (!S)
1589 return SemaRef.Owned(S);
1590
1591 switch (S->getStmtClass()) {
1592 case Stmt::NoStmtClass: break;
1593
1594 // Transform individual statement nodes
1595#define STMT(Node, Parent) \
1596 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1597#define EXPR(Node, Parent)
1598#include "clang/AST/StmtNodes.def"
1599
1600 // Transform expressions by calling TransformExpr.
1601#define STMT(Node, Parent)
1602#define EXPR(Node, Parent) case Stmt::Node##Class:
1603#include "clang/AST/StmtNodes.def"
1604 {
1605 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1606 if (E.isInvalid())
1607 return getSema().StmtError();
1608
1609 return getSema().Owned(E.takeAs<Stmt>());
1610 }
1611 }
1612
1613 return SemaRef.Owned(S->Retain());
1614}
1615
Douglas Gregor841324a2009-08-04 16:50:30 +00001616
Douglas Gregor2999faa2009-08-04 22:27:00 +00001617template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00001618Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1619 bool isAddressOfOperand) {
1620 if (!E)
1621 return SemaRef.Owned(E);
1622
1623 switch (E->getStmtClass()) {
1624 case Stmt::NoStmtClass: break;
1625#define STMT(Node, Parent) case Stmt::Node##Class: break;
1626#define EXPR(Node, Parent) \
1627 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1628#include "clang/AST/StmtNodes.def"
1629 }
1630
1631 return SemaRef.Owned(E->Retain());
Douglas Gregor72f34bb2009-08-06 22:17:10 +00001632}
1633
1634template<typename Derived>
Douglas Gregor12431cb2009-08-06 05:28:30 +00001635NestedNameSpecifier *
1636TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001637 SourceRange Range,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001638 QualType ObjectType,
1639 NamedDecl *FirstQualifierInScope) {
Douglas Gregorefccbec2009-08-31 21:41:48 +00001640 if (!NNS)
1641 return 0;
1642
Douglas Gregor23a44be2009-08-20 07:17:43 +00001643 // Transform the prefix of this nested name specifier.
Douglas Gregor12431cb2009-08-06 05:28:30 +00001644 NestedNameSpecifier *Prefix = NNS->getPrefix();
1645 if (Prefix) {
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001646 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001647 ObjectType,
1648 FirstQualifierInScope);
Douglas Gregor12431cb2009-08-06 05:28:30 +00001649 if (!Prefix)
1650 return 0;
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001651
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001652 // Clear out the object type and the first qualifier in scope; they only
1653 // apply to the first element in the nested-name-specifier.
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001654 ObjectType = QualType();
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001655 FirstQualifierInScope = 0;
Douglas Gregor12431cb2009-08-06 05:28:30 +00001656 }
1657
1658 switch (NNS->getKind()) {
1659 case NestedNameSpecifier::Identifier:
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001660 assert((Prefix || !ObjectType.isNull()) &&
1661 "Identifier nested-name-specifier with no prefix or object type");
1662 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1663 ObjectType.isNull())
Douglas Gregor12431cb2009-08-06 05:28:30 +00001664 return NNS;
1665
1666 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00001667 *NNS->getAsIdentifier(),
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00001668 ObjectType,
1669 FirstQualifierInScope);
Douglas Gregor12431cb2009-08-06 05:28:30 +00001670
1671 case NestedNameSpecifier::Namespace: {
1672 NamespaceDecl *NS
1673 = cast_or_null<NamespaceDecl>(
1674 getDerived().TransformDecl(NNS->getAsNamespace()));
1675 if (!getDerived().AlwaysRebuild() &&
1676 Prefix == NNS->getPrefix() &&
1677 NS == NNS->getAsNamespace())
1678 return NNS;
1679
1680 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1681 }
1682
1683 case NestedNameSpecifier::Global:
1684 // There is no meaningful transformation that one could perform on the
1685 // global scope.
1686 return NNS;
1687
1688 case NestedNameSpecifier::TypeSpecWithTemplate:
1689 case NestedNameSpecifier::TypeSpec: {
1690 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor214d0462009-08-06 06:41:21 +00001691 if (T.isNull())
1692 return 0;
1693
Douglas Gregor12431cb2009-08-06 05:28:30 +00001694 if (!getDerived().AlwaysRebuild() &&
1695 Prefix == NNS->getPrefix() &&
1696 T == QualType(NNS->getAsType(), 0))
1697 return NNS;
1698
1699 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1700 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
1701 T);
1702 }
1703 }
1704
1705 // Required to silence a GCC warning
1706 return 0;
1707}
1708
1709template<typename Derived>
Douglas Gregora0651052009-09-03 22:13:48 +00001710DeclarationName
1711TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
1712 SourceLocation Loc) {
1713 if (!Name)
1714 return Name;
1715
1716 switch (Name.getNameKind()) {
1717 case DeclarationName::Identifier:
1718 case DeclarationName::ObjCZeroArgSelector:
1719 case DeclarationName::ObjCOneArgSelector:
1720 case DeclarationName::ObjCMultiArgSelector:
1721 case DeclarationName::CXXOperatorName:
1722 case DeclarationName::CXXUsingDirective:
1723 return Name;
1724
1725 case DeclarationName::CXXConstructorName:
1726 case DeclarationName::CXXDestructorName:
1727 case DeclarationName::CXXConversionFunctionName: {
1728 TemporaryBase Rebase(*this, Loc, Name);
1729 QualType T = getDerived().TransformType(Name.getCXXNameType());
1730 if (T.isNull())
1731 return DeclarationName();
1732
1733 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
1734 Name.getNameKind(),
1735 SemaRef.Context.getCanonicalType(T));
1736 }
1737 }
1738
1739 return DeclarationName();
1740}
1741
1742template<typename Derived>
Douglas Gregor214d0462009-08-06 06:41:21 +00001743TemplateName
1744TreeTransform<Derived>::TransformTemplateName(TemplateName Name) {
1745 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
1746 NestedNameSpecifier *NNS
1747 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1748 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1749 if (!NNS)
1750 return TemplateName();
1751
1752 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
1753 TemplateDecl *TransTemplate
1754 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1755 if (!TransTemplate)
1756 return TemplateName();
1757
1758 if (!getDerived().AlwaysRebuild() &&
1759 NNS == QTN->getQualifier() &&
1760 TransTemplate == Template)
1761 return Name;
1762
1763 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1764 TransTemplate);
1765 }
1766
1767 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1768 assert(Ovl && "Not a template name or an overload set?");
1769 OverloadedFunctionDecl *TransOvl
1770 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1771 if (!TransOvl)
1772 return TemplateName();
1773
1774 if (!getDerived().AlwaysRebuild() &&
1775 NNS == QTN->getQualifier() &&
1776 TransOvl == Ovl)
1777 return Name;
1778
1779 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1780 TransOvl);
1781 }
1782
1783 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
1784 NestedNameSpecifier *NNS
1785 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1786 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1787 if (!NNS)
1788 return TemplateName();
1789
1790 if (!getDerived().AlwaysRebuild() &&
1791 NNS == DTN->getQualifier())
1792 return Name;
1793
1794 return getDerived().RebuildTemplateName(NNS, *DTN->getName());
1795 }
1796
1797 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1798 TemplateDecl *TransTemplate
1799 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1800 if (!TransTemplate)
1801 return TemplateName();
1802
1803 if (!getDerived().AlwaysRebuild() &&
1804 TransTemplate == Template)
1805 return Name;
1806
1807 return TemplateName(TransTemplate);
1808 }
1809
1810 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1811 assert(Ovl && "Not a template name or an overload set?");
1812 OverloadedFunctionDecl *TransOvl
1813 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1814 if (!TransOvl)
1815 return TemplateName();
1816
1817 if (!getDerived().AlwaysRebuild() &&
1818 TransOvl == Ovl)
1819 return Name;
1820
1821 return TemplateName(TransOvl);
1822}
1823
1824template<typename Derived>
Douglas Gregor2999faa2009-08-04 22:27:00 +00001825TemplateArgument
1826TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
1827 switch (Arg.getKind()) {
1828 case TemplateArgument::Null:
1829 case TemplateArgument::Integral:
1830 return Arg;
1831
1832 case TemplateArgument::Type: {
1833 QualType T = getDerived().TransformType(Arg.getAsType());
1834 if (T.isNull())
1835 return TemplateArgument();
1836 return TemplateArgument(Arg.getLocation(), T);
1837 }
1838
1839 case TemplateArgument::Declaration: {
1840 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
1841 if (!D)
1842 return TemplateArgument();
1843 return TemplateArgument(Arg.getLocation(), D);
1844 }
1845
1846 case TemplateArgument::Expression: {
1847 // Template argument expressions are not potentially evaluated.
1848 EnterExpressionEvaluationContext Unevaluated(getSema(),
1849 Action::Unevaluated);
1850
1851 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
1852 if (E.isInvalid())
1853 return TemplateArgument();
1854 return TemplateArgument(E.takeAs<Expr>());
1855 }
1856
1857 case TemplateArgument::Pack: {
1858 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1859 TransformedArgs.reserve(Arg.pack_size());
1860 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
1861 AEnd = Arg.pack_end();
1862 A != AEnd; ++A) {
1863 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
1864 if (TA.isNull())
1865 return TA;
1866
1867 TransformedArgs.push_back(TA);
1868 }
1869 TemplateArgument Result;
1870 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
1871 true);
1872 return Result;
1873 }
1874 }
1875
1876 // Work around bogus GCC warning
1877 return TemplateArgument();
1878}
1879
Douglas Gregor841324a2009-08-04 16:50:30 +00001880//===----------------------------------------------------------------------===//
1881// Type transformation
1882//===----------------------------------------------------------------------===//
1883
1884template<typename Derived>
1885QualType TreeTransform<Derived>::TransformType(QualType T) {
1886 if (getDerived().AlreadyTransformed(T))
1887 return T;
1888
1889 QualType Result;
1890 switch (T->getTypeClass()) {
1891#define ABSTRACT_TYPE(CLASS, PARENT)
1892#define TYPE(CLASS, PARENT) \
1893 case Type::CLASS: \
1894 Result = getDerived().Transform##CLASS##Type( \
1895 static_cast<CLASS##Type*>(T.getTypePtr())); \
1896 break;
1897#include "clang/AST/TypeNodes.def"
1898 }
1899
1900 if (Result.isNull() || T == Result)
1901 return Result;
1902
1903 return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
1904}
1905
1906template<typename Derived>
1907QualType
1908TreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
1909 if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
1910 return T.getWithAdditionalQualifiers(CVRQualifiers);
1911
1912 return T;
1913}
Argiris Kirtzidisfd3d5fd2009-08-19 01:28:17 +00001914
Douglas Gregor841324a2009-08-04 16:50:30 +00001915template<typename Derived>
1916QualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
1917 // FIXME: Implement
1918 return QualType(T, 0);
1919}
1920
1921template<typename Derived>
1922QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
1923 // Nothing to do
1924 return QualType(T, 0);
1925}
1926
1927template<typename Derived>
1928QualType TreeTransform<Derived>::TransformFixedWidthIntType(
1929 const FixedWidthIntType *T) {
1930 // FIXME: Implement
1931 return QualType(T, 0);
1932}
1933
1934template<typename Derived>
1935QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
1936 // FIXME: Implement
1937 return QualType(T, 0);
1938}
1939
1940template<typename Derived>
1941QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
1942 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1943 if (PointeeType.isNull())
1944 return QualType();
1945
1946 if (!getDerived().AlwaysRebuild() &&
1947 PointeeType == T->getPointeeType())
1948 return QualType(T, 0);
1949
1950 return getDerived().RebuildPointerType(PointeeType);
1951}
1952
1953template<typename Derived>
1954QualType
1955TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *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().RebuildBlockPointerType(PointeeType);
1965}
1966
1967template<typename Derived>
1968QualType
1969TreeTransform<Derived>::TransformLValueReferenceType(
1970 const LValueReferenceType *T) {
1971 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1972 if (PointeeType.isNull())
1973 return QualType();
1974
1975 if (!getDerived().AlwaysRebuild() &&
1976 PointeeType == T->getPointeeType())
1977 return QualType(T, 0);
1978
1979 return getDerived().RebuildLValueReferenceType(PointeeType);
1980}
1981
1982template<typename Derived>
1983QualType
1984TreeTransform<Derived>::TransformRValueReferenceType(
1985 const RValueReferenceType *T) {
1986 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1987 if (PointeeType.isNull())
1988 return QualType();
1989
1990 if (!getDerived().AlwaysRebuild() &&
1991 PointeeType == T->getPointeeType())
1992 return QualType(T, 0);
1993
1994 return getDerived().RebuildRValueReferenceType(PointeeType);
1995}
1996
1997template<typename Derived>
1998QualType
1999TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
2000 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
2001 if (PointeeType.isNull())
2002 return QualType();
2003
2004 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
2005 if (ClassType.isNull())
2006 return QualType();
2007
2008 if (!getDerived().AlwaysRebuild() &&
2009 PointeeType == T->getPointeeType() &&
2010 ClassType == QualType(T->getClass(), 0))
2011 return QualType(T, 0);
2012
2013 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2014}
2015
2016template<typename Derived>
2017QualType
2018TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
2019 QualType ElementType = getDerived().TransformType(T->getElementType());
2020 if (ElementType.isNull())
2021 return QualType();
2022
2023 if (!getDerived().AlwaysRebuild() &&
2024 ElementType == T->getElementType())
2025 return QualType(T, 0);
2026
2027 return getDerived().RebuildConstantArrayType(ElementType,
2028 T->getSizeModifier(),
2029 T->getSize(),
2030 T->getIndexTypeQualifier());
2031}
2032
2033template<typename Derived>
2034QualType
2035TreeTransform<Derived>::TransformConstantArrayWithExprType(
2036 const ConstantArrayWithExprType *T) {
2037 QualType ElementType = getDerived().TransformType(T->getElementType());
2038 if (ElementType.isNull())
2039 return QualType();
2040
Douglas Gregor2999faa2009-08-04 22:27:00 +00002041 // Array bounds are not potentially evaluated contexts
2042 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2043
2044 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2045 if (Size.isInvalid())
2046 return QualType();
2047
Douglas Gregor841324a2009-08-04 16:50:30 +00002048 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor2999faa2009-08-04 22:27:00 +00002049 ElementType == T->getElementType() &&
2050 Size.get() == T->getSizeExpr())
Douglas Gregor841324a2009-08-04 16:50:30 +00002051 return QualType(T, 0);
2052
2053 return getDerived().RebuildConstantArrayWithExprType(ElementType,
2054 T->getSizeModifier(),
2055 T->getSize(),
Douglas Gregor2999faa2009-08-04 22:27:00 +00002056 Size.takeAs<Expr>(),
Douglas Gregor841324a2009-08-04 16:50:30 +00002057 T->getIndexTypeQualifier(),
2058 T->getBracketsRange());
2059}
2060
2061template<typename Derived>
2062QualType
2063TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
2064 const ConstantArrayWithoutExprType *T) {
2065 QualType ElementType = getDerived().TransformType(T->getElementType());
2066 if (ElementType.isNull())
2067 return QualType();
2068
2069 if (!getDerived().AlwaysRebuild() &&
2070 ElementType == T->getElementType())
2071 return QualType(T, 0);
2072
2073 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
2074 T->getSizeModifier(),
2075 T->getSize(),
2076 T->getIndexTypeQualifier());
2077}
2078
2079template<typename Derived>
2080QualType TreeTransform<Derived>::TransformIncompleteArrayType(
2081 const IncompleteArrayType *T) {
2082 QualType ElementType = getDerived().TransformType(T->getElementType());
2083 if (ElementType.isNull())
2084 return QualType();
2085
2086 if (!getDerived().AlwaysRebuild() &&
2087 ElementType == T->getElementType())
2088 return QualType(T, 0);
2089
2090 return getDerived().RebuildIncompleteArrayType(ElementType,
2091 T->getSizeModifier(),
2092 T->getIndexTypeQualifier());
2093}
2094
2095template<typename Derived>
2096QualType TreeTransform<Derived>::TransformVariableArrayType(
2097 const VariableArrayType *T) {
2098 QualType ElementType = getDerived().TransformType(T->getElementType());
2099 if (ElementType.isNull())
2100 return QualType();
2101
Douglas Gregor2999faa2009-08-04 22:27:00 +00002102 // Array bounds are not potentially evaluated contexts
2103 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2104
Douglas Gregor841324a2009-08-04 16:50:30 +00002105 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2106 if (Size.isInvalid())
2107 return QualType();
2108
2109 if (!getDerived().AlwaysRebuild() &&
2110 ElementType == T->getElementType() &&
2111 Size.get() == T->getSizeExpr()) {
2112 Size.take();
2113 return QualType(T, 0);
2114 }
2115
2116 return getDerived().RebuildVariableArrayType(ElementType,
2117 T->getSizeModifier(),
2118 move(Size),
2119 T->getIndexTypeQualifier(),
2120 T->getBracketsRange());
2121}
2122
2123template<typename Derived>
2124QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
2125 const DependentSizedArrayType *T) {
2126 QualType ElementType = getDerived().TransformType(T->getElementType());
2127 if (ElementType.isNull())
2128 return QualType();
2129
Douglas Gregor2999faa2009-08-04 22:27:00 +00002130 // Array bounds are not potentially evaluated contexts
2131 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2132
Douglas Gregor841324a2009-08-04 16:50:30 +00002133 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2134 if (Size.isInvalid())
2135 return QualType();
2136
2137 if (!getDerived().AlwaysRebuild() &&
2138 ElementType == T->getElementType() &&
2139 Size.get() == T->getSizeExpr()) {
2140 Size.take();
2141 return QualType(T, 0);
2142 }
2143
2144 return getDerived().RebuildDependentSizedArrayType(ElementType,
2145 T->getSizeModifier(),
2146 move(Size),
2147 T->getIndexTypeQualifier(),
2148 T->getBracketsRange());
2149}
2150
2151template<typename Derived>
2152QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
2153 const DependentSizedExtVectorType *T) {
2154 QualType ElementType = getDerived().TransformType(T->getElementType());
2155 if (ElementType.isNull())
2156 return QualType();
2157
Douglas Gregor2999faa2009-08-04 22:27:00 +00002158 // Vector sizes are not potentially evaluated contexts
2159 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2160
Douglas Gregor841324a2009-08-04 16:50:30 +00002161 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2162 if (Size.isInvalid())
2163 return QualType();
2164
2165 if (!getDerived().AlwaysRebuild() &&
2166 ElementType == T->getElementType() &&
2167 Size.get() == T->getSizeExpr()) {
2168 Size.take();
2169 return QualType(T, 0);
2170 }
2171
2172 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
2173 move(Size),
2174 T->getAttributeLoc());
2175}
2176
2177template<typename Derived>
2178QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
2179 QualType ElementType = getDerived().TransformType(T->getElementType());
2180 if (ElementType.isNull())
2181 return QualType();
2182
2183 if (!getDerived().AlwaysRebuild() &&
2184 ElementType == T->getElementType())
2185 return QualType(T, 0);
2186
2187 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
2188}
2189
2190template<typename Derived>
2191QualType
2192TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
2193 QualType ElementType = getDerived().TransformType(T->getElementType());
2194 if (ElementType.isNull())
2195 return QualType();
2196
2197 if (!getDerived().AlwaysRebuild() &&
2198 ElementType == T->getElementType())
2199 return QualType(T, 0);
2200
2201 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
2202 /*FIXME*/SourceLocation());
2203}
2204
2205template<typename Derived>
2206QualType TreeTransform<Derived>::TransformFunctionProtoType(
2207 const FunctionProtoType *T) {
2208 QualType ResultType = getDerived().TransformType(T->getResultType());
2209 if (ResultType.isNull())
2210 return QualType();
2211
2212 llvm::SmallVector<QualType, 4> ParamTypes;
2213 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
2214 ParamEnd = T->arg_type_end();
2215 Param != ParamEnd; ++Param) {
2216 QualType P = getDerived().TransformType(*Param);
2217 if (P.isNull())
2218 return QualType();
2219
2220 ParamTypes.push_back(P);
2221 }
2222
2223 if (!getDerived().AlwaysRebuild() &&
2224 ResultType == T->getResultType() &&
2225 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
2226 return QualType(T, 0);
2227
2228 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
2229 ParamTypes.size(), T->isVariadic(),
2230 T->getTypeQuals());
2231}
2232
2233template<typename Derived>
2234QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
2235 const FunctionNoProtoType *T) {
2236 // FIXME: Implement
2237 return QualType(T, 0);
2238}
2239
2240template<typename Derived>
2241QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
2242 TypedefDecl *Typedef
2243 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2244 if (!Typedef)
2245 return QualType();
2246
2247 if (!getDerived().AlwaysRebuild() &&
2248 Typedef == T->getDecl())
2249 return QualType(T, 0);
2250
2251 return getDerived().RebuildTypedefType(Typedef);
2252}
2253
2254template<typename Derived>
2255QualType TreeTransform<Derived>::TransformTypeOfExprType(
2256 const TypeOfExprType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00002257 // typeof expressions are not potentially evaluated contexts
2258 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2259
Douglas Gregor841324a2009-08-04 16:50:30 +00002260 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2261 if (E.isInvalid())
2262 return QualType();
2263
2264 if (!getDerived().AlwaysRebuild() &&
2265 E.get() == T->getUnderlyingExpr()) {
2266 E.take();
2267 return QualType(T, 0);
2268 }
2269
2270 return getDerived().RebuildTypeOfExprType(move(E));
2271}
2272
2273template<typename Derived>
2274QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
2275 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2276 if (Underlying.isNull())
2277 return QualType();
2278
2279 if (!getDerived().AlwaysRebuild() &&
2280 Underlying == T->getUnderlyingType())
2281 return QualType(T, 0);
2282
2283 return getDerived().RebuildTypeOfType(Underlying);
2284}
2285
2286template<typename Derived>
2287QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00002288 // decltype expressions are not potentially evaluated contexts
2289 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2290
Douglas Gregor841324a2009-08-04 16:50:30 +00002291 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2292 if (E.isInvalid())
2293 return QualType();
2294
2295 if (!getDerived().AlwaysRebuild() &&
2296 E.get() == T->getUnderlyingExpr()) {
2297 E.take();
2298 return QualType(T, 0);
2299 }
2300
2301 return getDerived().RebuildDecltypeType(move(E));
2302}
2303
2304template<typename Derived>
2305QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
2306 RecordDecl *Record
2307 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
2308 if (!Record)
2309 return QualType();
2310
2311 if (!getDerived().AlwaysRebuild() &&
2312 Record == T->getDecl())
2313 return QualType(T, 0);
2314
2315 return getDerived().RebuildRecordType(Record);
2316}
2317
2318template<typename Derived>
2319QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
2320 EnumDecl *Enum
2321 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
2322 if (!Enum)
2323 return QualType();
2324
2325 if (!getDerived().AlwaysRebuild() &&
2326 Enum == T->getDecl())
2327 return QualType(T, 0);
2328
2329 return getDerived().RebuildEnumType(Enum);
2330}
2331
2332template<typename Derived>
2333QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
2334 const TemplateTypeParmType *T) {
2335 // Nothing to do
2336 return QualType(T, 0);
2337}
2338
2339template<typename Derived>
2340QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2341 const TemplateSpecializationType *T) {
2342 TemplateName Template
2343 = getDerived().TransformTemplateName(T->getTemplateName());
2344 if (Template.isNull())
2345 return QualType();
2346
2347 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2348 NewTemplateArgs.reserve(T->getNumArgs());
2349 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2350 Arg != ArgEnd; ++Arg) {
2351 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2352 if (NewArg.isNull())
2353 return QualType();
2354
2355 NewTemplateArgs.push_back(NewArg);
2356 }
2357
2358 // FIXME: early abort if all of the template arguments and such are the
2359 // same.
2360
2361 // FIXME: We're missing the locations of the template name, '<', and '>'.
2362 return getDerived().RebuildTemplateSpecializationType(Template,
2363 NewTemplateArgs.data(),
2364 NewTemplateArgs.size());
2365}
2366
2367template<typename Derived>
2368QualType TreeTransform<Derived>::TransformQualifiedNameType(
2369 const QualifiedNameType *T) {
2370 NestedNameSpecifier *NNS
2371 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2372 SourceRange());
2373 if (!NNS)
2374 return QualType();
2375
2376 QualType Named = getDerived().TransformType(T->getNamedType());
2377 if (Named.isNull())
2378 return QualType();
2379
2380 if (!getDerived().AlwaysRebuild() &&
2381 NNS == T->getQualifier() &&
2382 Named == T->getNamedType())
2383 return QualType(T, 0);
2384
2385 return getDerived().RebuildQualifiedNameType(NNS, Named);
2386}
2387
2388template<typename Derived>
2389QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
2390 NestedNameSpecifier *NNS
2391 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor3f220e82009-08-06 16:20:37 +00002392 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregor841324a2009-08-04 16:50:30 +00002393 if (!NNS)
2394 return QualType();
2395
2396 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
2397 QualType NewTemplateId
2398 = getDerived().TransformType(QualType(TemplateId, 0));
2399 if (NewTemplateId.isNull())
2400 return QualType();
2401
2402 if (!getDerived().AlwaysRebuild() &&
2403 NNS == T->getQualifier() &&
2404 NewTemplateId == QualType(TemplateId, 0))
2405 return QualType(T, 0);
2406
2407 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
2408 }
2409
2410 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
2411}
2412
2413template<typename Derived>
2414QualType TreeTransform<Derived>::TransformObjCInterfaceType(
2415 const ObjCInterfaceType *T) {
2416 // FIXME: Implement
2417 return QualType(T, 0);
2418}
2419
2420template<typename Derived>
2421QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
2422 const ObjCObjectPointerType *T) {
2423 // FIXME: Implement
2424 return QualType(T, 0);
2425}
2426
2427//===----------------------------------------------------------------------===//
Douglas Gregor23a44be2009-08-20 07:17:43 +00002428// Statement transformation
2429//===----------------------------------------------------------------------===//
2430template<typename Derived>
2431Sema::OwningStmtResult
2432TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2433 return SemaRef.Owned(S->Retain());
2434}
2435
2436template<typename Derived>
2437Sema::OwningStmtResult
2438TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2439 return getDerived().TransformCompoundStmt(S, false);
2440}
2441
2442template<typename Derived>
2443Sema::OwningStmtResult
2444TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
2445 bool IsStmtExpr) {
2446 bool SubStmtChanged = false;
2447 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2448 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2449 B != BEnd; ++B) {
2450 OwningStmtResult Result = getDerived().TransformStmt(*B);
2451 if (Result.isInvalid())
2452 return getSema().StmtError();
2453
2454 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2455 Statements.push_back(Result.takeAs<Stmt>());
2456 }
2457
2458 if (!getDerived().AlwaysRebuild() &&
2459 !SubStmtChanged)
2460 return SemaRef.Owned(S->Retain());
2461
2462 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2463 move_arg(Statements),
2464 S->getRBracLoc(),
2465 IsStmtExpr);
2466}
2467
2468template<typename Derived>
2469Sema::OwningStmtResult
2470TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
2471 // The case value expressions are not potentially evaluated.
2472 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2473
2474 // Transform the left-hand case value.
2475 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2476 if (LHS.isInvalid())
2477 return SemaRef.StmtError();
2478
2479 // Transform the right-hand case value (for the GNU case-range extension).
2480 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2481 if (RHS.isInvalid())
2482 return SemaRef.StmtError();
2483
2484 // Build the case statement.
2485 // Case statements are always rebuilt so that they will attached to their
2486 // transformed switch statement.
2487 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2488 move(LHS),
2489 S->getEllipsisLoc(),
2490 move(RHS),
2491 S->getColonLoc());
2492 if (Case.isInvalid())
2493 return SemaRef.StmtError();
2494
2495 // Transform the statement following the case
2496 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2497 if (SubStmt.isInvalid())
2498 return SemaRef.StmtError();
2499
2500 // Attach the body to the case statement
2501 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2502}
2503
2504template<typename Derived>
2505Sema::OwningStmtResult
2506TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
2507 // Transform the statement following the default case
2508 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2509 if (SubStmt.isInvalid())
2510 return SemaRef.StmtError();
2511
2512 // Default statements are always rebuilt
2513 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2514 move(SubStmt));
2515}
2516
2517template<typename Derived>
2518Sema::OwningStmtResult
2519TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
2520 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2521 if (SubStmt.isInvalid())
2522 return SemaRef.StmtError();
2523
2524 // FIXME: Pass the real colon location in.
2525 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2526 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2527 move(SubStmt));
2528}
2529
2530template<typename Derived>
2531Sema::OwningStmtResult
2532TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
2533 // Transform the condition
2534 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2535 if (Cond.isInvalid())
2536 return SemaRef.StmtError();
2537
2538 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
2539
2540 // Transform the "then" branch.
2541 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2542 if (Then.isInvalid())
2543 return SemaRef.StmtError();
2544
2545 // Transform the "else" branch.
2546 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2547 if (Else.isInvalid())
2548 return SemaRef.StmtError();
2549
2550 if (!getDerived().AlwaysRebuild() &&
2551 FullCond->get() == S->getCond() &&
2552 Then.get() == S->getThen() &&
2553 Else.get() == S->getElse())
2554 return SemaRef.Owned(S->Retain());
2555
2556 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
2557 S->getElseLoc(), move(Else));
2558}
2559
2560template<typename Derived>
2561Sema::OwningStmtResult
2562TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
2563 // Transform the condition.
2564 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2565 if (Cond.isInvalid())
2566 return SemaRef.StmtError();
2567
2568 // Rebuild the switch statement.
2569 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2570 if (Switch.isInvalid())
2571 return SemaRef.StmtError();
2572
2573 // Transform the body of the switch statement.
2574 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2575 if (Body.isInvalid())
2576 return SemaRef.StmtError();
2577
2578 // Complete the switch statement.
2579 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2580 move(Body));
2581}
2582
2583template<typename Derived>
2584Sema::OwningStmtResult
2585TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
2586 // Transform the condition
2587 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2588 if (Cond.isInvalid())
2589 return SemaRef.StmtError();
2590
2591 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
2592
2593 // Transform the body
2594 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2595 if (Body.isInvalid())
2596 return SemaRef.StmtError();
2597
2598 if (!getDerived().AlwaysRebuild() &&
2599 FullCond->get() == S->getCond() &&
2600 Body.get() == S->getBody())
2601 return SemaRef.Owned(S->Retain());
2602
2603 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2604}
2605
2606template<typename Derived>
2607Sema::OwningStmtResult
2608TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2609 // Transform the condition
2610 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2611 if (Cond.isInvalid())
2612 return SemaRef.StmtError();
2613
2614 // Transform the body
2615 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2616 if (Body.isInvalid())
2617 return SemaRef.StmtError();
2618
2619 if (!getDerived().AlwaysRebuild() &&
2620 Cond.get() == S->getCond() &&
2621 Body.get() == S->getBody())
2622 return SemaRef.Owned(S->Retain());
2623
2624 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
2625 /*FIXME:*/S->getWhileLoc(), move(Cond),
2626 S->getRParenLoc());
2627}
2628
2629template<typename Derived>
2630Sema::OwningStmtResult
2631TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
2632 // Transform the initialization statement
2633 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
2634 if (Init.isInvalid())
2635 return SemaRef.StmtError();
2636
2637 // Transform the condition
2638 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2639 if (Cond.isInvalid())
2640 return SemaRef.StmtError();
2641
2642 // Transform the increment
2643 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
2644 if (Inc.isInvalid())
2645 return SemaRef.StmtError();
2646
2647 // Transform the body
2648 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2649 if (Body.isInvalid())
2650 return SemaRef.StmtError();
2651
2652 if (!getDerived().AlwaysRebuild() &&
2653 Init.get() == S->getInit() &&
2654 Cond.get() == S->getCond() &&
2655 Inc.get() == S->getInc() &&
2656 Body.get() == S->getBody())
2657 return SemaRef.Owned(S->Retain());
2658
2659 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
2660 move(Init), move(Cond), move(Inc),
2661 S->getRParenLoc(), move(Body));
2662}
2663
2664template<typename Derived>
2665Sema::OwningStmtResult
2666TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
2667 // Goto statements must always be rebuilt, to resolve the label.
2668 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
2669 S->getLabel());
2670}
2671
2672template<typename Derived>
2673Sema::OwningStmtResult
2674TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
2675 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
2676 if (Target.isInvalid())
2677 return SemaRef.StmtError();
2678
2679 if (!getDerived().AlwaysRebuild() &&
2680 Target.get() == S->getTarget())
2681 return SemaRef.Owned(S->Retain());
2682
2683 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
2684 move(Target));
2685}
2686
2687template<typename Derived>
2688Sema::OwningStmtResult
2689TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
2690 return SemaRef.Owned(S->Retain());
2691}
2692
2693template<typename Derived>
2694Sema::OwningStmtResult
2695TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
2696 return SemaRef.Owned(S->Retain());
2697}
2698
2699template<typename Derived>
2700Sema::OwningStmtResult
2701TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
2702 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
2703 if (Result.isInvalid())
2704 return SemaRef.StmtError();
2705
2706 // FIXME: We always rebuild the return statement because there is no way
2707 // to tell whether the return type of the function has changed.
2708 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
2709}
2710
2711template<typename Derived>
2712Sema::OwningStmtResult
2713TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
2714 bool DeclChanged = false;
2715 llvm::SmallVector<Decl *, 4> Decls;
2716 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
2717 D != DEnd; ++D) {
2718 Decl *Transformed = getDerived().TransformDefinition(*D);
2719 if (!Transformed)
2720 return SemaRef.StmtError();
2721
2722 if (Transformed != *D)
2723 DeclChanged = true;
2724
2725 Decls.push_back(Transformed);
2726 }
2727
2728 if (!getDerived().AlwaysRebuild() && !DeclChanged)
2729 return SemaRef.Owned(S->Retain());
2730
2731 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
2732 S->getStartLoc(), S->getEndLoc());
2733}
2734
2735template<typename Derived>
2736Sema::OwningStmtResult
2737TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
2738 assert(false && "SwitchCase is abstract and cannot be transformed");
2739 return SemaRef.Owned(S->Retain());
2740}
2741
2742template<typename Derived>
2743Sema::OwningStmtResult
2744TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
2745 // FIXME: Implement!
2746 assert(false && "Inline assembly cannot be transformed");
2747 return SemaRef.Owned(S->Retain());
2748}
2749
2750
2751template<typename Derived>
2752Sema::OwningStmtResult
2753TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
2754 // FIXME: Implement this
2755 assert(false && "Cannot transform an Objective-C @try statement");
2756 return SemaRef.Owned(S->Retain());
2757}
2758
2759template<typename Derived>
2760Sema::OwningStmtResult
2761TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
2762 // FIXME: Implement this
2763 assert(false && "Cannot transform an Objective-C @catch statement");
2764 return SemaRef.Owned(S->Retain());
2765}
2766
2767template<typename Derived>
2768Sema::OwningStmtResult
2769TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
2770 // FIXME: Implement this
2771 assert(false && "Cannot transform an Objective-C @finally statement");
2772 return SemaRef.Owned(S->Retain());
2773}
2774
2775template<typename Derived>
2776Sema::OwningStmtResult
2777TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
2778 // FIXME: Implement this
2779 assert(false && "Cannot transform an Objective-C @throw statement");
2780 return SemaRef.Owned(S->Retain());
2781}
2782
2783template<typename Derived>
2784Sema::OwningStmtResult
2785TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
2786 ObjCAtSynchronizedStmt *S) {
2787 // FIXME: Implement this
2788 assert(false && "Cannot transform an Objective-C @synchronized statement");
2789 return SemaRef.Owned(S->Retain());
2790}
2791
2792template<typename Derived>
2793Sema::OwningStmtResult
2794TreeTransform<Derived>::TransformObjCForCollectionStmt(
2795 ObjCForCollectionStmt *S) {
2796 // FIXME: Implement this
2797 assert(false && "Cannot transform an Objective-C for-each statement");
2798 return SemaRef.Owned(S->Retain());
2799}
2800
2801
2802template<typename Derived>
2803Sema::OwningStmtResult
2804TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
2805 // Transform the exception declaration, if any.
2806 VarDecl *Var = 0;
2807 if (S->getExceptionDecl()) {
2808 VarDecl *ExceptionDecl = S->getExceptionDecl();
2809 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
2810 ExceptionDecl->getDeclName());
2811
2812 QualType T = getDerived().TransformType(ExceptionDecl->getType());
2813 if (T.isNull())
2814 return SemaRef.StmtError();
2815
2816 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
2817 T,
2818 ExceptionDecl->getDeclaratorInfo(),
2819 ExceptionDecl->getIdentifier(),
2820 ExceptionDecl->getLocation(),
2821 /*FIXME: Inaccurate*/
2822 SourceRange(ExceptionDecl->getLocation()));
2823 if (!Var || Var->isInvalidDecl()) {
2824 if (Var)
2825 Var->Destroy(SemaRef.Context);
2826 return SemaRef.StmtError();
2827 }
2828 }
2829
2830 // Transform the actual exception handler.
2831 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
2832 if (Handler.isInvalid()) {
2833 if (Var)
2834 Var->Destroy(SemaRef.Context);
2835 return SemaRef.StmtError();
2836 }
2837
2838 if (!getDerived().AlwaysRebuild() &&
2839 !Var &&
2840 Handler.get() == S->getHandlerBlock())
2841 return SemaRef.Owned(S->Retain());
2842
2843 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
2844 Var,
2845 move(Handler));
2846}
2847
2848template<typename Derived>
2849Sema::OwningStmtResult
2850TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
2851 // Transform the try block itself.
2852 OwningStmtResult TryBlock
2853 = getDerived().TransformCompoundStmt(S->getTryBlock());
2854 if (TryBlock.isInvalid())
2855 return SemaRef.StmtError();
2856
2857 // Transform the handlers.
2858 bool HandlerChanged = false;
2859 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
2860 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
2861 OwningStmtResult Handler
2862 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
2863 if (Handler.isInvalid())
2864 return SemaRef.StmtError();
2865
2866 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
2867 Handlers.push_back(Handler.takeAs<Stmt>());
2868 }
2869
2870 if (!getDerived().AlwaysRebuild() &&
2871 TryBlock.get() == S->getTryBlock() &&
2872 !HandlerChanged)
2873 return SemaRef.Owned(S->Retain());
2874
2875 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
2876 move_arg(Handlers));
2877}
2878
2879//===----------------------------------------------------------------------===//
Douglas Gregor9d879762009-08-11 05:31:07 +00002880// Expression transformation
2881//===----------------------------------------------------------------------===//
2882template<typename Derived>
2883Sema::OwningExprResult
2884TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
2885 return SemaRef.Owned(E->Retain());
2886}
2887
2888template<typename Derived>
2889Sema::OwningExprResult
2890TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
2891 NamedDecl *ND
2892 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
2893 if (!ND)
2894 return SemaRef.ExprError();
2895
2896 if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
2897 return SemaRef.Owned(E->Retain());
2898
2899 return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
2900}
2901
2902template<typename Derived>
2903Sema::OwningExprResult
2904TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
2905 return SemaRef.Owned(E->Retain());
2906}
2907
2908template<typename Derived>
2909Sema::OwningExprResult
2910TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
2911 return SemaRef.Owned(E->Retain());
2912}
2913
2914template<typename Derived>
2915Sema::OwningExprResult
2916TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
2917 return SemaRef.Owned(E->Retain());
2918}
2919
2920template<typename Derived>
2921Sema::OwningExprResult
2922TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
2923 return SemaRef.Owned(E->Retain());
2924}
2925
2926template<typename Derived>
2927Sema::OwningExprResult
2928TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
2929 return SemaRef.Owned(E->Retain());
2930}
2931
2932template<typename Derived>
2933Sema::OwningExprResult
2934TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
2935 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
2936 if (SubExpr.isInvalid())
2937 return SemaRef.ExprError();
2938
2939 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
2940 return SemaRef.Owned(E->Retain());
2941
2942 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
2943 E->getRParen());
2944}
2945
2946template<typename Derived>
2947Sema::OwningExprResult
2948TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
2949 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
2950 if (SubExpr.isInvalid())
2951 return SemaRef.ExprError();
2952
2953 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
2954 return SemaRef.Owned(E->Retain());
2955
2956 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
2957 E->getOpcode(),
2958 move(SubExpr));
2959}
2960
2961template<typename Derived>
2962Sema::OwningExprResult
2963TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2964 if (E->isArgumentType()) {
2965 QualType T = getDerived().TransformType(E->getArgumentType());
2966 if (T.isNull())
2967 return SemaRef.ExprError();
2968
2969 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
2970 return SemaRef.Owned(E->Retain());
2971
2972 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
2973 E->isSizeOf(),
2974 E->getSourceRange());
2975 }
2976
2977 Sema::OwningExprResult SubExpr(SemaRef);
2978 {
2979 // C++0x [expr.sizeof]p1:
2980 // The operand is either an expression, which is an unevaluated operand
2981 // [...]
2982 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2983
2984 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
2985 if (SubExpr.isInvalid())
2986 return SemaRef.ExprError();
2987
2988 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
2989 return SemaRef.Owned(E->Retain());
2990 }
2991
2992 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
2993 E->isSizeOf(),
2994 E->getSourceRange());
2995}
2996
2997template<typename Derived>
2998Sema::OwningExprResult
2999TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3000 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3001 if (LHS.isInvalid())
3002 return SemaRef.ExprError();
3003
3004 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3005 if (RHS.isInvalid())
3006 return SemaRef.ExprError();
3007
3008
3009 if (!getDerived().AlwaysRebuild() &&
3010 LHS.get() == E->getLHS() &&
3011 RHS.get() == E->getRHS())
3012 return SemaRef.Owned(E->Retain());
3013
3014 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3015 /*FIXME:*/E->getLHS()->getLocStart(),
3016 move(RHS),
3017 E->getRBracketLoc());
3018}
3019
3020template<typename Derived>
3021Sema::OwningExprResult
3022TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3023 // Transform the callee.
3024 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3025 if (Callee.isInvalid())
3026 return SemaRef.ExprError();
3027
3028 // Transform arguments.
3029 bool ArgChanged = false;
3030 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3031 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3032 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3033 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3034 if (Arg.isInvalid())
3035 return SemaRef.ExprError();
3036
3037 // FIXME: Wrong source location information for the ','.
3038 FakeCommaLocs.push_back(
3039 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
3040
3041 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
3042 Args.push_back(Arg.takeAs<Expr>());
3043 }
3044
3045 if (!getDerived().AlwaysRebuild() &&
3046 Callee.get() == E->getCallee() &&
3047 !ArgChanged)
3048 return SemaRef.Owned(E->Retain());
3049
3050 // FIXME: Wrong source location information for the '('.
3051 SourceLocation FakeLParenLoc
3052 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3053 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3054 move_arg(Args),
3055 FakeCommaLocs.data(),
3056 E->getRParenLoc());
3057}
3058
3059template<typename Derived>
3060Sema::OwningExprResult
3061TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
3062 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3063 if (Base.isInvalid())
3064 return SemaRef.ExprError();
3065
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003066 NestedNameSpecifier *Qualifier = 0;
3067 if (E->hasQualifier()) {
3068 Qualifier
3069 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3070 E->getQualifierRange());
Douglas Gregord33e3282009-09-01 00:37:14 +00003071 if (Qualifier == 0)
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003072 return SemaRef.ExprError();
3073 }
3074
Douglas Gregor9d879762009-08-11 05:31:07 +00003075 NamedDecl *Member
3076 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3077 if (!Member)
3078 return SemaRef.ExprError();
3079
3080 if (!getDerived().AlwaysRebuild() &&
3081 Base.get() == E->getBase() &&
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003082 Qualifier == E->getQualifier() &&
Douglas Gregor9d879762009-08-11 05:31:07 +00003083 Member == E->getMemberDecl())
3084 return SemaRef.Owned(E->Retain());
3085
3086 // FIXME: Bogus source location for the operator
3087 SourceLocation FakeOperatorLoc
3088 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3089
3090 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3091 E->isArrow(),
Douglas Gregorc1991bf2009-08-31 23:41:50 +00003092 Qualifier,
3093 E->getQualifierRange(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003094 E->getMemberLoc(),
3095 Member);
3096}
3097
3098template<typename Derived>
3099Sema::OwningExprResult
3100TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3101 assert(false && "Cannot transform abstract class");
3102 return SemaRef.Owned(E->Retain());
3103}
3104
3105template<typename Derived>
3106Sema::OwningExprResult
3107TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
3108 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3109 if (LHS.isInvalid())
3110 return SemaRef.ExprError();
3111
3112 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3113 if (RHS.isInvalid())
3114 return SemaRef.ExprError();
3115
3116 if (!getDerived().AlwaysRebuild() &&
3117 LHS.get() == E->getLHS() &&
3118 RHS.get() == E->getRHS())
3119 return SemaRef.Owned(E->Retain());
3120
3121 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3122 move(LHS), move(RHS));
3123}
3124
3125template<typename Derived>
3126Sema::OwningExprResult
3127TreeTransform<Derived>::TransformCompoundAssignOperator(
3128 CompoundAssignOperator *E) {
3129 return getDerived().TransformBinaryOperator(E);
3130}
3131
3132template<typename Derived>
3133Sema::OwningExprResult
3134TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
3135 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3136 if (Cond.isInvalid())
3137 return SemaRef.ExprError();
3138
3139 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3140 if (LHS.isInvalid())
3141 return SemaRef.ExprError();
3142
3143 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3144 if (RHS.isInvalid())
3145 return SemaRef.ExprError();
3146
3147 if (!getDerived().AlwaysRebuild() &&
3148 Cond.get() == E->getCond() &&
3149 LHS.get() == E->getLHS() &&
3150 RHS.get() == E->getRHS())
3151 return SemaRef.Owned(E->Retain());
3152
Douglas Gregor9d879762009-08-11 05:31:07 +00003153 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor34619872009-08-26 14:37:04 +00003154 E->getQuestionLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003155 move(LHS),
Douglas Gregor34619872009-08-26 14:37:04 +00003156 E->getColonLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003157 move(RHS));
3158}
3159
3160template<typename Derived>
3161Sema::OwningExprResult
3162TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
3163 QualType T = getDerived().TransformType(E->getType());
3164 if (T.isNull())
3165 return SemaRef.ExprError();
3166
3167 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3168 if (SubExpr.isInvalid())
3169 return SemaRef.ExprError();
3170
3171 if (!getDerived().AlwaysRebuild() &&
3172 T == E->getType() &&
3173 SubExpr.get() == E->getSubExpr())
3174 return SemaRef.Owned(E->Retain());
3175
3176 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
3177 move(SubExpr),
3178 E->isLvalueCast());
3179}
3180
3181template<typename Derived>
3182Sema::OwningExprResult
3183TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3184 assert(false && "Cannot transform abstract class");
3185 return SemaRef.Owned(E->Retain());
3186}
3187
3188template<typename Derived>
3189Sema::OwningExprResult
3190TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
3191 QualType T;
3192 {
3193 // FIXME: Source location isn't quite accurate.
3194 SourceLocation TypeStartLoc
3195 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3196 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
3197
3198 T = getDerived().TransformType(E->getTypeAsWritten());
3199 if (T.isNull())
3200 return SemaRef.ExprError();
3201 }
3202
3203 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3204 if (SubExpr.isInvalid())
3205 return SemaRef.ExprError();
3206
3207 if (!getDerived().AlwaysRebuild() &&
3208 T == E->getTypeAsWritten() &&
3209 SubExpr.get() == E->getSubExpr())
3210 return SemaRef.Owned(E->Retain());
3211
3212 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3213 E->getRParenLoc(),
3214 move(SubExpr));
3215}
3216
3217template<typename Derived>
3218Sema::OwningExprResult
3219TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3220 QualType T;
3221 {
3222 // FIXME: Source location isn't quite accurate.
3223 SourceLocation FakeTypeLoc
3224 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3225 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
3226
3227 T = getDerived().TransformType(E->getType());
3228 if (T.isNull())
3229 return SemaRef.ExprError();
3230 }
3231
3232 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3233 if (Init.isInvalid())
3234 return SemaRef.ExprError();
3235
3236 if (!getDerived().AlwaysRebuild() &&
3237 T == E->getType() &&
3238 Init.get() == E->getInitializer())
3239 return SemaRef.Owned(E->Retain());
3240
3241 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3242 /*FIXME:*/E->getInitializer()->getLocEnd(),
3243 move(Init));
3244}
3245
3246template<typename Derived>
3247Sema::OwningExprResult
3248TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
3249 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3250 if (Base.isInvalid())
3251 return SemaRef.ExprError();
3252
3253 if (!getDerived().AlwaysRebuild() &&
3254 Base.get() == E->getBase())
3255 return SemaRef.Owned(E->Retain());
3256
3257 // FIXME: Bad source location
3258 SourceLocation FakeOperatorLoc
3259 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3260 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3261 E->getAccessorLoc(),
3262 E->getAccessor());
3263}
3264
3265template<typename Derived>
3266Sema::OwningExprResult
3267TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
3268 bool InitChanged = false;
3269
3270 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3271 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3272 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3273 if (Init.isInvalid())
3274 return SemaRef.ExprError();
3275
3276 InitChanged = InitChanged || Init.get() != E->getInit(I);
3277 Inits.push_back(Init.takeAs<Expr>());
3278 }
3279
3280 if (!getDerived().AlwaysRebuild() && !InitChanged)
3281 return SemaRef.Owned(E->Retain());
3282
3283 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3284 E->getRBraceLoc());
3285}
3286
3287template<typename Derived>
3288Sema::OwningExprResult
3289TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
3290 Designation Desig;
3291
Douglas Gregor23a44be2009-08-20 07:17:43 +00003292 // transform the initializer value
Douglas Gregor9d879762009-08-11 05:31:07 +00003293 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3294 if (Init.isInvalid())
3295 return SemaRef.ExprError();
3296
Douglas Gregor23a44be2009-08-20 07:17:43 +00003297 // transform the designators.
Douglas Gregor9d879762009-08-11 05:31:07 +00003298 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3299 bool ExprChanged = false;
3300 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3301 DEnd = E->designators_end();
3302 D != DEnd; ++D) {
3303 if (D->isFieldDesignator()) {
3304 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3305 D->getDotLoc(),
3306 D->getFieldLoc()));
3307 continue;
3308 }
3309
3310 if (D->isArrayDesignator()) {
3311 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3312 if (Index.isInvalid())
3313 return SemaRef.ExprError();
3314
3315 Desig.AddDesignator(Designator::getArray(Index.get(),
3316 D->getLBracketLoc()));
3317
3318 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3319 ArrayExprs.push_back(Index.release());
3320 continue;
3321 }
3322
3323 assert(D->isArrayRangeDesignator() && "New kind of designator?");
3324 OwningExprResult Start
3325 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3326 if (Start.isInvalid())
3327 return SemaRef.ExprError();
3328
3329 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3330 if (End.isInvalid())
3331 return SemaRef.ExprError();
3332
3333 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
3334 End.get(),
3335 D->getLBracketLoc(),
3336 D->getEllipsisLoc()));
3337
3338 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3339 End.get() != E->getArrayRangeEnd(*D);
3340
3341 ArrayExprs.push_back(Start.release());
3342 ArrayExprs.push_back(End.release());
3343 }
3344
3345 if (!getDerived().AlwaysRebuild() &&
3346 Init.get() == E->getInit() &&
3347 !ExprChanged)
3348 return SemaRef.Owned(E->Retain());
3349
3350 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3351 E->getEqualOrColonLoc(),
3352 E->usesGNUSyntax(), move(Init));
3353}
3354
3355template<typename Derived>
3356Sema::OwningExprResult
3357TreeTransform<Derived>::TransformImplicitValueInitExpr(
3358 ImplicitValueInitExpr *E) {
3359 QualType T = getDerived().TransformType(E->getType());
3360 if (T.isNull())
3361 return SemaRef.ExprError();
3362
3363 if (!getDerived().AlwaysRebuild() &&
3364 T == E->getType())
3365 return SemaRef.Owned(E->Retain());
3366
3367 return getDerived().RebuildImplicitValueInitExpr(T);
3368}
3369
3370template<typename Derived>
3371Sema::OwningExprResult
3372TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3373 // FIXME: Do we want the type as written?
3374 QualType T;
3375
3376 {
3377 // FIXME: Source location isn't quite accurate.
3378 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3379 T = getDerived().TransformType(E->getType());
3380 if (T.isNull())
3381 return SemaRef.ExprError();
3382 }
3383
3384 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3385 if (SubExpr.isInvalid())
3386 return SemaRef.ExprError();
3387
3388 if (!getDerived().AlwaysRebuild() &&
3389 T == E->getType() &&
3390 SubExpr.get() == E->getSubExpr())
3391 return SemaRef.Owned(E->Retain());
3392
3393 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3394 T, E->getRParenLoc());
3395}
3396
3397template<typename Derived>
3398Sema::OwningExprResult
3399TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3400 bool ArgumentChanged = false;
3401 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3402 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3403 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3404 if (Init.isInvalid())
3405 return SemaRef.ExprError();
3406
3407 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3408 Inits.push_back(Init.takeAs<Expr>());
3409 }
3410
3411 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3412 move_arg(Inits),
3413 E->getRParenLoc());
3414}
3415
3416/// \brief Transform an address-of-label expression.
3417///
3418/// By default, the transformation of an address-of-label expression always
3419/// rebuilds the expression, so that the label identifier can be resolved to
3420/// the corresponding label statement by semantic analysis.
3421template<typename Derived>
3422Sema::OwningExprResult
3423TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
3424 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3425 E->getLabel());
3426}
3427
3428template<typename Derived>
3429Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
3430 OwningStmtResult SubStmt
3431 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3432 if (SubStmt.isInvalid())
3433 return SemaRef.ExprError();
3434
3435 if (!getDerived().AlwaysRebuild() &&
3436 SubStmt.get() == E->getSubStmt())
3437 return SemaRef.Owned(E->Retain());
3438
3439 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
3440 move(SubStmt),
3441 E->getRParenLoc());
3442}
3443
3444template<typename Derived>
3445Sema::OwningExprResult
3446TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
3447 QualType T1, T2;
3448 {
3449 // FIXME: Source location isn't quite accurate.
3450 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3451
3452 T1 = getDerived().TransformType(E->getArgType1());
3453 if (T1.isNull())
3454 return SemaRef.ExprError();
3455
3456 T2 = getDerived().TransformType(E->getArgType2());
3457 if (T2.isNull())
3458 return SemaRef.ExprError();
3459 }
3460
3461 if (!getDerived().AlwaysRebuild() &&
3462 T1 == E->getArgType1() &&
3463 T2 == E->getArgType2())
3464 return SemaRef.Owned(E->Retain());
3465
3466 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3467 T1, T2, E->getRParenLoc());
3468}
3469
3470template<typename Derived>
3471Sema::OwningExprResult
3472TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
3473 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3474 if (Cond.isInvalid())
3475 return SemaRef.ExprError();
3476
3477 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3478 if (LHS.isInvalid())
3479 return SemaRef.ExprError();
3480
3481 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3482 if (RHS.isInvalid())
3483 return SemaRef.ExprError();
3484
3485 if (!getDerived().AlwaysRebuild() &&
3486 Cond.get() == E->getCond() &&
3487 LHS.get() == E->getLHS() &&
3488 RHS.get() == E->getRHS())
3489 return SemaRef.Owned(E->Retain());
3490
3491 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3492 move(Cond), move(LHS), move(RHS),
3493 E->getRParenLoc());
3494}
3495
3496template<typename Derived>
3497Sema::OwningExprResult
3498TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3499 return SemaRef.Owned(E->Retain());
3500}
3501
3502template<typename Derived>
3503Sema::OwningExprResult
3504TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3505 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3506 if (Callee.isInvalid())
3507 return SemaRef.ExprError();
3508
3509 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3510 if (First.isInvalid())
3511 return SemaRef.ExprError();
3512
3513 OwningExprResult Second(SemaRef);
3514 if (E->getNumArgs() == 2) {
3515 Second = getDerived().TransformExpr(E->getArg(1));
3516 if (Second.isInvalid())
3517 return SemaRef.ExprError();
3518 }
3519
3520 if (!getDerived().AlwaysRebuild() &&
3521 Callee.get() == E->getCallee() &&
3522 First.get() == E->getArg(0) &&
3523 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3524 return SemaRef.Owned(E->Retain());
3525
3526 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3527 E->getOperatorLoc(),
3528 move(Callee),
3529 move(First),
3530 move(Second));
3531}
3532
3533template<typename Derived>
3534Sema::OwningExprResult
3535TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
3536 return getDerived().TransformCallExpr(E);
3537}
3538
3539template<typename Derived>
3540Sema::OwningExprResult
3541TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3542 QualType ExplicitTy;
3543 {
3544 // FIXME: Source location isn't quite accurate.
3545 SourceLocation TypeStartLoc
3546 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3547 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
3548
3549 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3550 if (ExplicitTy.isNull())
3551 return SemaRef.ExprError();
3552 }
3553
3554 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3555 if (SubExpr.isInvalid())
3556 return SemaRef.ExprError();
3557
3558 if (!getDerived().AlwaysRebuild() &&
3559 ExplicitTy == E->getTypeAsWritten() &&
3560 SubExpr.get() == E->getSubExpr())
3561 return SemaRef.Owned(E->Retain());
3562
3563 // FIXME: Poor source location information here.
3564 SourceLocation FakeLAngleLoc
3565 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3566 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3567 SourceLocation FakeRParenLoc
3568 = SemaRef.PP.getLocForEndOfToken(
3569 E->getSubExpr()->getSourceRange().getEnd());
3570 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
3571 E->getStmtClass(),
3572 FakeLAngleLoc,
3573 ExplicitTy,
3574 FakeRAngleLoc,
3575 FakeRAngleLoc,
3576 move(SubExpr),
3577 FakeRParenLoc);
3578}
3579
3580template<typename Derived>
3581Sema::OwningExprResult
3582TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
3583 return getDerived().TransformCXXNamedCastExpr(E);
3584}
3585
3586template<typename Derived>
3587Sema::OwningExprResult
3588TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
3589 return getDerived().TransformCXXNamedCastExpr(E);
3590}
3591
3592template<typename Derived>
3593Sema::OwningExprResult
3594TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
3595 CXXReinterpretCastExpr *E) {
3596 return getDerived().TransformCXXNamedCastExpr(E);
3597}
3598
3599template<typename Derived>
3600Sema::OwningExprResult
3601TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
3602 return getDerived().TransformCXXNamedCastExpr(E);
3603}
3604
3605template<typename Derived>
3606Sema::OwningExprResult
3607TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
3608 CXXFunctionalCastExpr *E) {
3609 QualType ExplicitTy;
3610 {
3611 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3612
3613 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3614 if (ExplicitTy.isNull())
3615 return SemaRef.ExprError();
3616 }
3617
3618 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3619 if (SubExpr.isInvalid())
3620 return SemaRef.ExprError();
3621
3622 if (!getDerived().AlwaysRebuild() &&
3623 ExplicitTy == E->getTypeAsWritten() &&
3624 SubExpr.get() == E->getSubExpr())
3625 return SemaRef.Owned(E->Retain());
3626
3627 // FIXME: The end of the type's source range is wrong
3628 return getDerived().RebuildCXXFunctionalCastExpr(
3629 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
3630 ExplicitTy,
3631 /*FIXME:*/E->getSubExpr()->getLocStart(),
3632 move(SubExpr),
3633 E->getRParenLoc());
3634}
3635
3636template<typename Derived>
3637Sema::OwningExprResult
3638TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
3639 if (E->isTypeOperand()) {
3640 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3641
3642 QualType T = getDerived().TransformType(E->getTypeOperand());
3643 if (T.isNull())
3644 return SemaRef.ExprError();
3645
3646 if (!getDerived().AlwaysRebuild() &&
3647 T == E->getTypeOperand())
3648 return SemaRef.Owned(E->Retain());
3649
3650 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3651 /*FIXME:*/E->getLocStart(),
3652 T,
3653 E->getLocEnd());
3654 }
3655
3656 // We don't know whether the expression is potentially evaluated until
3657 // after we perform semantic analysis, so the expression is potentially
3658 // potentially evaluated.
3659 EnterExpressionEvaluationContext Unevaluated(SemaRef,
3660 Action::PotentiallyPotentiallyEvaluated);
3661
3662 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
3663 if (SubExpr.isInvalid())
3664 return SemaRef.ExprError();
3665
3666 if (!getDerived().AlwaysRebuild() &&
3667 SubExpr.get() == E->getExprOperand())
3668 return SemaRef.Owned(E->Retain());
3669
3670 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3671 /*FIXME:*/E->getLocStart(),
3672 move(SubExpr),
3673 E->getLocEnd());
3674}
3675
3676template<typename Derived>
3677Sema::OwningExprResult
3678TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
3679 return SemaRef.Owned(E->Retain());
3680}
3681
3682template<typename Derived>
3683Sema::OwningExprResult
3684TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
3685 CXXNullPtrLiteralExpr *E) {
3686 return SemaRef.Owned(E->Retain());
3687}
3688
3689template<typename Derived>
3690Sema::OwningExprResult
3691TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
3692 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3693
3694 QualType T = getDerived().TransformType(E->getType());
3695 if (T.isNull())
3696 return SemaRef.ExprError();
3697
3698 if (!getDerived().AlwaysRebuild() &&
3699 T == E->getType())
3700 return SemaRef.Owned(E->Retain());
3701
3702 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
3703}
3704
3705template<typename Derived>
3706Sema::OwningExprResult
3707TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
3708 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3709 if (SubExpr.isInvalid())
3710 return SemaRef.ExprError();
3711
3712 if (!getDerived().AlwaysRebuild() &&
3713 SubExpr.get() == E->getSubExpr())
3714 return SemaRef.Owned(E->Retain());
3715
3716 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
3717}
3718
3719template<typename Derived>
3720Sema::OwningExprResult
3721TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
3722 ParmVarDecl *Param
3723 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
3724 if (!Param)
3725 return SemaRef.ExprError();
3726
3727 if (getDerived().AlwaysRebuild() &&
3728 Param == E->getParam())
3729 return SemaRef.Owned(E->Retain());
3730
3731 return getDerived().RebuildCXXDefaultArgExpr(Param);
3732}
3733
3734template<typename Derived>
3735Sema::OwningExprResult
3736TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
3737 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3738
3739 QualType T = getDerived().TransformType(E->getType());
3740 if (T.isNull())
3741 return SemaRef.ExprError();
3742
3743 if (!getDerived().AlwaysRebuild() &&
3744 T == E->getType())
3745 return SemaRef.Owned(E->Retain());
3746
3747 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
3748 /*FIXME:*/E->getTypeBeginLoc(),
3749 T,
3750 E->getRParenLoc());
3751}
3752
3753template<typename Derived>
3754Sema::OwningExprResult
3755TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
3756 VarDecl *Var
Douglas Gregor23a44be2009-08-20 07:17:43 +00003757 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregor9d879762009-08-11 05:31:07 +00003758 if (!Var)
3759 return SemaRef.ExprError();
3760
3761 if (!getDerived().AlwaysRebuild() &&
3762 Var == E->getVarDecl())
3763 return SemaRef.Owned(E->Retain());
3764
3765 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
3766 /*FIXME:*/E->getStartLoc(),
3767 Var);
3768}
3769
3770template<typename Derived>
3771Sema::OwningExprResult
3772TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
3773 // Transform the type that we're allocating
3774 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3775 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
3776 if (AllocType.isNull())
3777 return SemaRef.ExprError();
3778
3779 // Transform the size of the array we're allocating (if any).
3780 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
3781 if (ArraySize.isInvalid())
3782 return SemaRef.ExprError();
3783
3784 // Transform the placement arguments (if any).
3785 bool ArgumentChanged = false;
3786 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
3787 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
3788 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
3789 if (Arg.isInvalid())
3790 return SemaRef.ExprError();
3791
3792 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
3793 PlacementArgs.push_back(Arg.take());
3794 }
3795
Douglas Gregor23a44be2009-08-20 07:17:43 +00003796 // transform the constructor arguments (if any).
Douglas Gregor9d879762009-08-11 05:31:07 +00003797 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
3798 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
3799 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
3800 if (Arg.isInvalid())
3801 return SemaRef.ExprError();
3802
3803 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
3804 ConstructorArgs.push_back(Arg.take());
3805 }
3806
3807 if (!getDerived().AlwaysRebuild() &&
3808 AllocType == E->getAllocatedType() &&
3809 ArraySize.get() == E->getArraySize() &&
3810 !ArgumentChanged)
3811 return SemaRef.Owned(E->Retain());
3812
3813 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
3814 E->isGlobalNew(),
3815 /*FIXME:*/E->getLocStart(),
3816 move_arg(PlacementArgs),
3817 /*FIXME:*/E->getLocStart(),
3818 E->isParenTypeId(),
3819 AllocType,
3820 /*FIXME:*/E->getLocStart(),
3821 /*FIXME:*/SourceRange(),
3822 move(ArraySize),
3823 /*FIXME:*/E->getLocStart(),
3824 move_arg(ConstructorArgs),
3825 E->getLocEnd());
3826}
3827
3828template<typename Derived>
3829Sema::OwningExprResult
3830TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
3831 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
3832 if (Operand.isInvalid())
3833 return SemaRef.ExprError();
3834
3835 if (!getDerived().AlwaysRebuild() &&
3836 Operand.get() == E->getArgument())
3837 return SemaRef.Owned(E->Retain());
3838
3839 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
3840 E->isGlobalDelete(),
3841 E->isArrayForm(),
3842 move(Operand));
3843}
3844
3845template<typename Derived>
3846Sema::OwningExprResult
Douglas Gregor3e368512009-09-04 17:36:40 +00003847TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
3848 CXXPseudoDestructorExpr *E) {
3849 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3850 if (Base.isInvalid())
3851 return SemaRef.ExprError();
3852
3853 NestedNameSpecifier *Qualifier
3854 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3855 E->getQualifierRange());
3856 if (E->getQualifier() && !Qualifier)
3857 return SemaRef.ExprError();
3858
3859 QualType DestroyedType;
3860 {
3861 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
3862 DestroyedType = getDerived().TransformType(E->getDestroyedType());
3863 if (DestroyedType.isNull())
3864 return SemaRef.ExprError();
3865 }
3866
3867 if (!getDerived().AlwaysRebuild() &&
3868 Base.get() == E->getBase() &&
3869 Qualifier == E->getQualifier() &&
3870 DestroyedType == E->getDestroyedType())
3871 return SemaRef.Owned(E->Retain());
3872
3873 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
3874 E->getOperatorLoc(),
3875 E->isArrow(),
3876 E->getDestroyedTypeLoc(),
3877 DestroyedType,
3878 Qualifier,
3879 E->getQualifierRange());
3880}
3881
3882template<typename Derived>
3883Sema::OwningExprResult
Douglas Gregor9d879762009-08-11 05:31:07 +00003884TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
3885 UnresolvedFunctionNameExpr *E) {
3886 // There is no transformation we can apply to an unresolved function name.
3887 return SemaRef.Owned(E->Retain());
3888}
3889
3890template<typename Derived>
3891Sema::OwningExprResult
3892TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
3893 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3894
3895 QualType T = getDerived().TransformType(E->getQueriedType());
3896 if (T.isNull())
3897 return SemaRef.ExprError();
3898
3899 if (!getDerived().AlwaysRebuild() &&
3900 T == E->getQueriedType())
3901 return SemaRef.Owned(E->Retain());
3902
3903 // FIXME: Bad location information
3904 SourceLocation FakeLParenLoc
3905 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
3906
3907 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
3908 E->getLocStart(),
3909 /*FIXME:*/FakeLParenLoc,
3910 T,
3911 E->getLocEnd());
3912}
3913
3914template<typename Derived>
3915Sema::OwningExprResult
3916TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
3917 NestedNameSpecifier *NNS
3918 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3919 E->getQualifierRange());
3920 if (!NNS)
3921 return SemaRef.ExprError();
3922
3923 NamedDecl *ND
3924 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3925 if (!ND)
3926 return SemaRef.ExprError();
3927
3928 if (!getDerived().AlwaysRebuild() &&
3929 NNS == E->getQualifier() &&
3930 ND == E->getDecl())
3931 return SemaRef.Owned(E->Retain());
3932
3933 return getDerived().RebuildQualifiedDeclRefExpr(NNS,
3934 E->getQualifierRange(),
3935 ND,
3936 E->getLocation(),
3937 /*FIXME:*/false);
3938}
3939
3940template<typename Derived>
3941Sema::OwningExprResult
3942TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
3943 UnresolvedDeclRefExpr *E) {
3944 NestedNameSpecifier *NNS
3945 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3946 E->getQualifierRange());
3947 if (!NNS)
3948 return SemaRef.ExprError();
3949
Douglas Gregora0651052009-09-03 22:13:48 +00003950 DeclarationName Name
3951 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
3952 if (!Name)
3953 return SemaRef.ExprError();
Douglas Gregor9d879762009-08-11 05:31:07 +00003954
3955 if (!getDerived().AlwaysRebuild() &&
3956 NNS == E->getQualifier() &&
3957 Name == E->getDeclName())
3958 return SemaRef.Owned(E->Retain());
3959
3960 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
3961 E->getQualifierRange(),
3962 Name,
3963 E->getLocation(),
3964 /*FIXME:*/false);
3965}
3966
3967template<typename Derived>
3968Sema::OwningExprResult
3969TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
3970 TemplateName Template
3971 = getDerived().TransformTemplateName(E->getTemplateName());
3972 if (Template.isNull())
3973 return SemaRef.ExprError();
3974
3975 llvm::SmallVector<TemplateArgument, 4> TransArgs;
3976 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
3977 TemplateArgument TransArg
3978 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
3979 if (TransArg.isNull())
3980 return SemaRef.ExprError();
3981
3982 TransArgs.push_back(TransArg);
3983 }
3984
3985 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
3986 // compare template arguments (yet).
3987
3988 // FIXME: It's possible that we'll find out now that the template name
3989 // actually refers to a type, in which case the caller is actually dealing
3990 // with a functional cast. Give a reasonable error message!
3991 return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
3992 E->getLAngleLoc(),
3993 TransArgs.data(),
3994 TransArgs.size(),
3995 E->getRAngleLoc());
3996}
3997
3998template<typename Derived>
3999Sema::OwningExprResult
4000TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
4001 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4002
4003 QualType T = getDerived().TransformType(E->getType());
4004 if (T.isNull())
4005 return SemaRef.ExprError();
4006
4007 CXXConstructorDecl *Constructor
4008 = cast_or_null<CXXConstructorDecl>(
4009 getDerived().TransformDecl(E->getConstructor()));
4010 if (!Constructor)
4011 return SemaRef.ExprError();
4012
4013 bool ArgumentChanged = false;
4014 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4015 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
4016 ArgEnd = E->arg_end();
4017 Arg != ArgEnd; ++Arg) {
4018 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4019 if (TransArg.isInvalid())
4020 return SemaRef.ExprError();
4021
4022 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4023 Args.push_back(TransArg.takeAs<Expr>());
4024 }
4025
4026 if (!getDerived().AlwaysRebuild() &&
4027 T == E->getType() &&
4028 Constructor == E->getConstructor() &&
4029 !ArgumentChanged)
4030 return SemaRef.Owned(E->Retain());
4031
4032 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4033 move_arg(Args));
4034}
4035
4036/// \brief Transform a C++ temporary-binding expression.
4037///
4038/// The transformation of a temporary-binding expression always attempts to
4039/// bind a new temporary variable to its subexpression, even if the
4040/// subexpression itself did not change, because the temporary variable itself
4041/// must be unique.
4042template<typename Derived>
4043Sema::OwningExprResult
4044TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4045 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4046 if (SubExpr.isInvalid())
4047 return SemaRef.ExprError();
4048
4049 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4050}
4051
4052/// \brief Transform a C++ expression that contains temporaries that should
4053/// be destroyed after the expression is evaluated.
4054///
4055/// The transformation of a full expression always attempts to build a new
4056/// CXXExprWithTemporaries expression, even if the
4057/// subexpression itself did not change, because it will need to capture the
4058/// the new temporary variables introduced in the subexpression.
4059template<typename Derived>
4060Sema::OwningExprResult
4061TreeTransform<Derived>::TransformCXXExprWithTemporaries(
4062 CXXExprWithTemporaries *E) {
4063 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4064 if (SubExpr.isInvalid())
4065 return SemaRef.ExprError();
4066
4067 return SemaRef.Owned(
4068 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4069 E->shouldDestroyTemporaries()));
4070}
4071
4072template<typename Derived>
4073Sema::OwningExprResult
4074TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
4075 CXXTemporaryObjectExpr *E) {
4076 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4077 QualType T = getDerived().TransformType(E->getType());
4078 if (T.isNull())
4079 return SemaRef.ExprError();
4080
4081 CXXConstructorDecl *Constructor
4082 = cast_or_null<CXXConstructorDecl>(
4083 getDerived().TransformDecl(E->getConstructor()));
4084 if (!Constructor)
4085 return SemaRef.ExprError();
4086
4087 bool ArgumentChanged = false;
4088 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4089 Args.reserve(E->getNumArgs());
4090 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
4091 ArgEnd = E->arg_end();
4092 Arg != ArgEnd; ++Arg) {
4093 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4094 if (TransArg.isInvalid())
4095 return SemaRef.ExprError();
4096
4097 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4098 Args.push_back((Expr *)TransArg.release());
4099 }
4100
4101 if (!getDerived().AlwaysRebuild() &&
4102 T == E->getType() &&
4103 Constructor == E->getConstructor() &&
4104 !ArgumentChanged)
4105 return SemaRef.Owned(E->Retain());
4106
4107 // FIXME: Bogus location information
4108 SourceLocation CommaLoc;
4109 if (Args.size() > 1) {
4110 Expr *First = (Expr *)Args[0];
4111 CommaLoc
4112 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4113 }
4114 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4115 T,
4116 /*FIXME:*/E->getTypeBeginLoc(),
4117 move_arg(Args),
4118 &CommaLoc,
4119 E->getLocEnd());
4120}
4121
4122template<typename Derived>
4123Sema::OwningExprResult
4124TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
4125 CXXUnresolvedConstructExpr *E) {
4126 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4127 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4128 if (T.isNull())
4129 return SemaRef.ExprError();
4130
4131 bool ArgumentChanged = false;
4132 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4133 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4134 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4135 ArgEnd = E->arg_end();
4136 Arg != ArgEnd; ++Arg) {
4137 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4138 if (TransArg.isInvalid())
4139 return SemaRef.ExprError();
4140
4141 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4142 FakeCommaLocs.push_back(
4143 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4144 Args.push_back(TransArg.takeAs<Expr>());
4145 }
4146
4147 if (!getDerived().AlwaysRebuild() &&
4148 T == E->getTypeAsWritten() &&
4149 !ArgumentChanged)
4150 return SemaRef.Owned(E->Retain());
4151
4152 // FIXME: we're faking the locations of the commas
4153 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4154 T,
4155 E->getLParenLoc(),
4156 move_arg(Args),
4157 FakeCommaLocs.data(),
4158 E->getRParenLoc());
4159}
Douglas Gregore399ad42009-08-26 22:36:53 +00004160
Douglas Gregor9d879762009-08-11 05:31:07 +00004161template<typename Derived>
4162Sema::OwningExprResult
4163TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
4164 CXXUnresolvedMemberExpr *E) {
4165 // Transform the base of the expression.
4166 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4167 if (Base.isInvalid())
4168 return SemaRef.ExprError();
4169
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004170 Sema::TypeTy *ObjectType = 0;
4171 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
4172 E->getOperatorLoc(),
4173 E->isArrow()? tok::arrow : tok::period,
4174 ObjectType);
4175 if (Base.isInvalid())
4176 return SemaRef.ExprError();
4177
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004178 NamedDecl *FirstQualifierInScope
4179 = cast_or_null<NamedDecl>(
4180 getDerived().TransformDecl(E->getFirstQualifierFoundInScope()));
4181
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004182 NestedNameSpecifier *Qualifier = 0;
4183 if (E->getQualifier()) {
4184 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4185 E->getQualifierRange(),
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004186 QualType::getFromOpaquePtr(ObjectType),
4187 FirstQualifierInScope);
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004188 if (!Qualifier)
4189 return SemaRef.ExprError();
4190 }
4191
Douglas Gregora0651052009-09-03 22:13:48 +00004192 DeclarationName Name
4193 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc());
4194 if (!Name)
4195 return SemaRef.ExprError();
4196
Douglas Gregor9d879762009-08-11 05:31:07 +00004197 if (!getDerived().AlwaysRebuild() &&
4198 Base.get() == E->getBase() &&
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004199 Qualifier == E->getQualifier() &&
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004200 Name == E->getMember() &&
4201 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Douglas Gregor9d879762009-08-11 05:31:07 +00004202 return SemaRef.Owned(E->Retain());
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004203
Douglas Gregor9d879762009-08-11 05:31:07 +00004204 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4205 E->isArrow(),
4206 E->getOperatorLoc(),
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004207 Qualifier,
4208 E->getQualifierRange(),
4209 Name,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004210 E->getMemberLoc(),
4211 FirstQualifierInScope);
Douglas Gregor9d879762009-08-11 05:31:07 +00004212}
4213
4214template<typename Derived>
4215Sema::OwningExprResult
4216TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4217 return SemaRef.Owned(E->Retain());
4218}
4219
4220template<typename Derived>
4221Sema::OwningExprResult
4222TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
4223 // FIXME: poor source location
4224 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4225 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4226 if (EncodedType.isNull())
4227 return SemaRef.ExprError();
4228
4229 if (!getDerived().AlwaysRebuild() &&
4230 EncodedType == E->getEncodedType())
4231 return SemaRef.Owned(E->Retain());
4232
4233 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4234 EncodedType,
4235 E->getRParenLoc());
4236}
4237
4238template<typename Derived>
4239Sema::OwningExprResult
4240TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
4241 // FIXME: Implement this!
4242 assert(false && "Cannot transform Objective-C expressions yet");
4243 return SemaRef.Owned(E->Retain());
4244}
4245
4246template<typename Derived>
4247Sema::OwningExprResult
4248TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4249 return SemaRef.Owned(E->Retain());
4250}
4251
4252template<typename Derived>
4253Sema::OwningExprResult
4254TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4255 ObjCProtocolDecl *Protocol
4256 = cast_or_null<ObjCProtocolDecl>(
4257 getDerived().TransformDecl(E->getProtocol()));
4258 if (!Protocol)
4259 return SemaRef.ExprError();
4260
4261 if (!getDerived().AlwaysRebuild() &&
4262 Protocol == E->getProtocol())
4263 return SemaRef.Owned(E->Retain());
4264
4265 return getDerived().RebuildObjCProtocolExpr(Protocol,
4266 E->getAtLoc(),
4267 /*FIXME:*/E->getAtLoc(),
4268 /*FIXME:*/E->getAtLoc(),
4269 E->getRParenLoc());
4270
4271}
4272
4273template<typename Derived>
4274Sema::OwningExprResult
4275TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
4276 // FIXME: Implement this!
4277 assert(false && "Cannot transform Objective-C expressions yet");
4278 return SemaRef.Owned(E->Retain());
4279}
4280
4281template<typename Derived>
4282Sema::OwningExprResult
4283TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4284 // FIXME: Implement this!
4285 assert(false && "Cannot transform Objective-C expressions yet");
4286 return SemaRef.Owned(E->Retain());
4287}
4288
4289template<typename Derived>
4290Sema::OwningExprResult
Fariborz Jahanian128cdc52009-08-20 17:02:02 +00004291TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
4292 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004293 // FIXME: Implement this!
4294 assert(false && "Cannot transform Objective-C expressions yet");
4295 return SemaRef.Owned(E->Retain());
4296}
4297
4298template<typename Derived>
4299Sema::OwningExprResult
4300TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
4301 // FIXME: Implement this!
4302 assert(false && "Cannot transform Objective-C expressions yet");
4303 return SemaRef.Owned(E->Retain());
4304}
4305
4306template<typename Derived>
4307Sema::OwningExprResult
4308TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
4309 // FIXME: Implement this!
4310 assert(false && "Cannot transform Objective-C expressions yet");
4311 return SemaRef.Owned(E->Retain());
4312}
4313
4314template<typename Derived>
4315Sema::OwningExprResult
4316TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
4317 bool ArgumentChanged = false;
4318 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4319 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4320 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4321 if (SubExpr.isInvalid())
4322 return SemaRef.ExprError();
4323
4324 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4325 SubExprs.push_back(SubExpr.takeAs<Expr>());
4326 }
4327
4328 if (!getDerived().AlwaysRebuild() &&
4329 !ArgumentChanged)
4330 return SemaRef.Owned(E->Retain());
4331
4332 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4333 move_arg(SubExprs),
4334 E->getRParenLoc());
4335}
4336
4337template<typename Derived>
4338Sema::OwningExprResult
4339TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
4340 // FIXME: Implement this!
4341 assert(false && "Cannot transform block expressions yet");
4342 return SemaRef.Owned(E->Retain());
4343}
4344
4345template<typename Derived>
4346Sema::OwningExprResult
4347TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
4348 // FIXME: Implement this!
4349 assert(false && "Cannot transform block-related expressions yet");
4350 return SemaRef.Owned(E->Retain());
4351}
4352
4353//===----------------------------------------------------------------------===//
Douglas Gregor841324a2009-08-04 16:50:30 +00004354// Type reconstruction
4355//===----------------------------------------------------------------------===//
4356
4357template<typename Derived>
4358QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
4359 return SemaRef.BuildPointerType(PointeeType, 0,
4360 getDerived().getBaseLocation(),
4361 getDerived().getBaseEntity());
4362}
4363
4364template<typename Derived>
4365QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
4366 return SemaRef.BuildBlockPointerType(PointeeType, 0,
4367 getDerived().getBaseLocation(),
4368 getDerived().getBaseEntity());
4369}
4370
4371template<typename Derived>
4372QualType
4373TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
4374 return SemaRef.BuildReferenceType(ReferentType, true, 0,
4375 getDerived().getBaseLocation(),
4376 getDerived().getBaseEntity());
4377}
4378
4379template<typename Derived>
4380QualType
4381TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
4382 return SemaRef.BuildReferenceType(ReferentType, false, 0,
4383 getDerived().getBaseLocation(),
4384 getDerived().getBaseEntity());
4385}
4386
4387template<typename Derived>
4388QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
4389 QualType ClassType) {
4390 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
4391 getDerived().getBaseLocation(),
4392 getDerived().getBaseEntity());
4393}
4394
4395template<typename Derived>
4396QualType
4397TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4398 ArrayType::ArraySizeModifier SizeMod,
4399 const llvm::APInt *Size,
4400 Expr *SizeExpr,
4401 unsigned IndexTypeQuals,
4402 SourceRange BracketsRange) {
4403 if (SizeExpr || !Size)
4404 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4405 IndexTypeQuals, BracketsRange,
4406 getDerived().getBaseEntity());
4407
4408 QualType Types[] = {
4409 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4410 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4411 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
4412 };
4413 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4414 QualType SizeType;
4415 for (unsigned I = 0; I != NumTypes; ++I)
4416 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4417 SizeType = Types[I];
4418 break;
4419 }
4420
4421 if (SizeType.isNull())
4422 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
4423
4424 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
4425 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
4426 IndexTypeQuals, BracketsRange,
4427 getDerived().getBaseEntity());
4428}
4429
4430template<typename Derived>
4431QualType
4432TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
4433 ArrayType::ArraySizeModifier SizeMod,
4434 const llvm::APInt &Size,
4435 unsigned IndexTypeQuals) {
4436 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
4437 IndexTypeQuals, SourceRange());
4438}
4439
4440template<typename Derived>
4441QualType
4442TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
4443 ArrayType::ArraySizeModifier SizeMod,
4444 const llvm::APInt &Size,
4445 Expr *SizeExpr,
4446 unsigned IndexTypeQuals,
4447 SourceRange BracketsRange) {
4448 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
4449 IndexTypeQuals, BracketsRange);
4450}
4451
4452template<typename Derived>
4453QualType
4454TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
4455 QualType ElementType,
4456 ArrayType::ArraySizeModifier SizeMod,
4457 const llvm::APInt &Size,
4458 unsigned IndexTypeQuals) {
4459 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
4460 IndexTypeQuals, SourceRange());
4461}
4462
4463template<typename Derived>
4464QualType
4465TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
4466 ArrayType::ArraySizeModifier SizeMod,
4467 unsigned IndexTypeQuals) {
4468 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
4469 IndexTypeQuals, SourceRange());
4470}
4471
4472template<typename Derived>
4473QualType
4474TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
4475 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +00004476 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004477 unsigned IndexTypeQuals,
4478 SourceRange BracketsRange) {
4479 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
4480 SizeExpr.takeAs<Expr>(),
4481 IndexTypeQuals, BracketsRange);
4482}
4483
4484template<typename Derived>
4485QualType
4486TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
4487 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +00004488 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004489 unsigned IndexTypeQuals,
4490 SourceRange BracketsRange) {
4491 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
4492 SizeExpr.takeAs<Expr>(),
4493 IndexTypeQuals, BracketsRange);
4494}
4495
4496template<typename Derived>
4497QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4498 unsigned NumElements) {
4499 // FIXME: semantic checking!
4500 return SemaRef.Context.getVectorType(ElementType, NumElements);
4501}
4502
4503template<typename Derived>
4504QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4505 unsigned NumElements,
4506 SourceLocation AttributeLoc) {
4507 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4508 NumElements, true);
4509 IntegerLiteral *VectorSize
4510 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
4511 AttributeLoc);
4512 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4513 AttributeLoc);
4514}
4515
4516template<typename Derived>
4517QualType
4518TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregor9d879762009-08-11 05:31:07 +00004519 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004520 SourceLocation AttributeLoc) {
4521 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4522}
4523
4524template<typename Derived>
4525QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
4526 QualType *ParamTypes,
4527 unsigned NumParamTypes,
4528 bool Variadic,
4529 unsigned Quals) {
4530 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
4531 Quals,
4532 getDerived().getBaseLocation(),
4533 getDerived().getBaseEntity());
4534}
4535
4536template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00004537QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor841324a2009-08-04 16:50:30 +00004538 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4539}
4540
4541template<typename Derived>
4542QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4543 return SemaRef.Context.getTypeOfType(Underlying);
4544}
4545
4546template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00004547QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor841324a2009-08-04 16:50:30 +00004548 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4549}
4550
4551template<typename Derived>
4552QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4553 TemplateName Template,
4554 const TemplateArgument *Args,
4555 unsigned NumArgs) {
4556 // FIXME: Missing source locations for the template name, <, >.
4557 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
4558 SourceLocation(), Args, NumArgs,
4559 SourceLocation());
4560}
4561
Douglas Gregor12431cb2009-08-06 05:28:30 +00004562template<typename Derived>
4563NestedNameSpecifier *
4564TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4565 SourceRange Range,
Douglas Gregor0f927cf2009-09-03 16:14:30 +00004566 IdentifierInfo &II,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004567 QualType ObjectType,
4568 NamedDecl *FirstQualifierInScope) {
Douglas Gregor12431cb2009-08-06 05:28:30 +00004569 CXXScopeSpec SS;
4570 // FIXME: The source location information is all wrong.
4571 SS.setRange(Range);
4572 SS.setScopeRep(Prefix);
4573 return static_cast<NestedNameSpecifier *>(
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004574 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregorc03d3302009-08-25 22:51:20 +00004575 Range.getEnd(), II,
Douglas Gregorbc2fb7f2009-09-03 21:38:09 +00004576 ObjectType,
4577 FirstQualifierInScope,
Douglas Gregorc03d3302009-08-25 22:51:20 +00004578 false));
Douglas Gregor12431cb2009-08-06 05:28:30 +00004579}
4580
4581template<typename Derived>
4582NestedNameSpecifier *
4583TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4584 SourceRange Range,
4585 NamespaceDecl *NS) {
4586 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
4587}
4588
4589template<typename Derived>
4590NestedNameSpecifier *
4591TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4592 SourceRange Range,
4593 bool TemplateKW,
4594 QualType T) {
4595 if (T->isDependentType() || T->isRecordType() ||
4596 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
4597 assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
4598 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
4599 T.getTypePtr());
4600 }
4601
4602 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
4603 return 0;
4604}
4605
Douglas Gregor214d0462009-08-06 06:41:21 +00004606template<typename Derived>
4607TemplateName
4608TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4609 bool TemplateKW,
4610 TemplateDecl *Template) {
4611 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
4612 Template);
4613}
4614
4615template<typename Derived>
4616TemplateName
4617TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4618 bool TemplateKW,
4619 OverloadedFunctionDecl *Ovl) {
4620 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
4621}
4622
4623template<typename Derived>
4624TemplateName
4625TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4626 const IdentifierInfo &II) {
4627 if (Qualifier->isDependent())
4628 return SemaRef.Context.getDependentTemplateName(Qualifier, &II);
4629
4630 // Somewhat redundant with ActOnDependentTemplateName.
4631 CXXScopeSpec SS;
4632 SS.setRange(SourceRange(getDerived().getBaseLocation()));
4633 SS.setScopeRep(Qualifier);
4634 Sema::TemplateTy Template;
Douglas Gregor681d31d2009-09-02 22:59:36 +00004635 TemplateNameKind TNK = SemaRef.isTemplateName(0, II,
4636 /*FIXME:*/getDerived().getBaseLocation(),
4637 &SS,
4638 /*FIXME:ObjectType=*/0, false,
4639 Template);
Douglas Gregor214d0462009-08-06 06:41:21 +00004640 if (TNK == TNK_Non_template) {
4641 SemaRef.Diag(getDerived().getBaseLocation(),
4642 diag::err_template_kw_refers_to_non_template)
4643 << &II;
4644 return TemplateName();
4645 } else if (TNK == TNK_Function_template) {
4646 SemaRef.Diag(getDerived().getBaseLocation(),
4647 diag::err_template_kw_refers_to_non_template)
4648 << &II;
4649 return TemplateName();
4650 }
4651
4652 return Template.getAsVal<TemplateName>();
4653}
Douglas Gregor9d879762009-08-11 05:31:07 +00004654
4655template<typename Derived>
4656Sema::OwningExprResult
4657TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
4658 SourceLocation OpLoc,
4659 ExprArg Callee,
4660 ExprArg First,
4661 ExprArg Second) {
4662 Expr *FirstExpr = (Expr *)First.get();
4663 Expr *SecondExpr = (Expr *)Second.get();
4664 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
4665
4666 // Determine whether this should be a builtin operation.
4667 if (SecondExpr == 0 || isPostIncDec) {
4668 if (!FirstExpr->getType()->isOverloadableType()) {
4669 // The argument is not of overloadable type, so try to create a
4670 // built-in unary operation.
4671 UnaryOperator::Opcode Opc
4672 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4673
4674 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
4675 }
4676 } else {
4677 if (!FirstExpr->getType()->isOverloadableType() &&
4678 !SecondExpr->getType()->isOverloadableType()) {
4679 // Neither of the arguments is an overloadable type, so try to
4680 // create a built-in binary operation.
4681 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
4682 OwningExprResult Result
4683 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
4684 if (Result.isInvalid())
4685 return SemaRef.ExprError();
4686
4687 First.release();
4688 Second.release();
4689 return move(Result);
4690 }
4691 }
4692
4693 // Compute the transformed set of functions (and function templates) to be
4694 // used during overload resolution.
4695 Sema::FunctionSet Functions;
4696
Douglas Gregor23026c82009-09-01 16:58:52 +00004697 DeclRefExpr *DRE
4698 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregor9d879762009-08-11 05:31:07 +00004699
4700 // FIXME: Do we have to check
4701 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor23026c82009-09-01 16:58:52 +00004702 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregor9d879762009-08-11 05:31:07 +00004703 Functions.insert(*F);
4704
4705 // Add any functions found via argument-dependent lookup.
4706 Expr *Args[2] = { FirstExpr, SecondExpr };
4707 unsigned NumArgs = 1 + (SecondExpr != 0);
4708 DeclarationName OpName
4709 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
4710 SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
4711
4712 // Create the overloaded operator invocation for unary operators.
4713 if (NumArgs == 1 || isPostIncDec) {
4714 UnaryOperator::Opcode Opc
4715 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4716 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
4717 }
4718
4719 // Create the overloaded operator invocation for binary operators.
4720 BinaryOperator::Opcode Opc =
4721 BinaryOperator::getOverloadedOpcode(Op);
4722 OwningExprResult Result
4723 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
4724 if (Result.isInvalid())
4725 return SemaRef.ExprError();
4726
4727 First.release();
4728 Second.release();
4729 return move(Result);
4730}
Douglas Gregor214d0462009-08-06 06:41:21 +00004731
Douglas Gregor841324a2009-08-04 16:50:30 +00004732} // end namespace clang
4733
4734#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H