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