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