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