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