blob: deb54115a5830abc3e71c35af5e2e9ef7de05053 [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) {
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +0000840 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregor9d879762009-08-11 05:31:07 +0000841 isArrow? tok::arrow : tok::period,
842 MemberLoc,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +0000843 Member->getDeclName(),
Douglas Gregor9d879762009-08-11 05:31:07 +0000844 /*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);
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001438 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregore399ad42009-08-26 22:36:53 +00001439 isArrow? tok::arrow : tok::period,
1440 MemberLoc,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001441 Member->getDeclName(),
Douglas Gregore399ad42009-08-26 22:36:53 +00001442 /*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
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001462 Base = SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregor9d879762009-08-11 05:31:07 +00001463 move(Base), OperatorLoc, OpKind,
Douglas Gregor3b4dc7c2009-08-31 20:00:26 +00001464 MemberLoc,
1465 Name,
Douglas Gregor9d879762009-08-11 05:31:07 +00001466 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1467 SemaRef.ActOnCXXExitMemberScope(0, SS);
1468 return move(Base);
1469 }
1470
1471 /// \brief Build a new Objective-C @encode expression.
1472 ///
1473 /// By default, performs semantic analysis to build the new expression.
1474 /// Subclasses may override this routine to provide different behavior.
1475 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1476 QualType T,
1477 SourceLocation RParenLoc) {
1478 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1479 RParenLoc));
1480 }
1481
1482 /// \brief Build a new Objective-C protocol expression.
1483 ///
1484 /// By default, performs semantic analysis to build the new expression.
1485 /// Subclasses may override this routine to provide different behavior.
1486 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1487 SourceLocation AtLoc,
1488 SourceLocation ProtoLoc,
1489 SourceLocation LParenLoc,
1490 SourceLocation RParenLoc) {
1491 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1492 Protocol->getIdentifier(),
1493 AtLoc,
1494 ProtoLoc,
1495 LParenLoc,
1496 RParenLoc));
1497 }
1498
1499 /// \brief Build a new shuffle vector expression.
1500 ///
1501 /// By default, performs semantic analysis to build the new expression.
1502 /// Subclasses may override this routine to provide different behavior.
1503 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1504 MultiExprArg SubExprs,
1505 SourceLocation RParenLoc) {
1506 // Find the declaration for __builtin_shufflevector
1507 const IdentifierInfo &Name
1508 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1509 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1510 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1511 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
1512
1513 // Build a reference to the __builtin_shufflevector builtin
1514 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
1515 Expr *Callee
1516 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1517 BuiltinLoc, false, false);
1518 SemaRef.UsualUnaryConversions(Callee);
1519
1520 // Build the CallExpr
1521 unsigned NumSubExprs = SubExprs.size();
1522 Expr **Subs = (Expr **)SubExprs.release();
1523 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1524 Subs, NumSubExprs,
1525 Builtin->getResultType(),
1526 RParenLoc);
1527 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
1528
1529 // Type-check the __builtin_shufflevector expression.
1530 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1531 if (Result.isInvalid())
1532 return SemaRef.ExprError();
1533
1534 OwnedCall.release();
1535 return move(Result);
1536 }
Douglas Gregor841324a2009-08-04 16:50:30 +00001537};
Douglas Gregor9d879762009-08-11 05:31:07 +00001538
Douglas Gregor23a44be2009-08-20 07:17:43 +00001539template<typename Derived>
1540Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1541 if (!S)
1542 return SemaRef.Owned(S);
1543
1544 switch (S->getStmtClass()) {
1545 case Stmt::NoStmtClass: break;
1546
1547 // Transform individual statement nodes
1548#define STMT(Node, Parent) \
1549 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1550#define EXPR(Node, Parent)
1551#include "clang/AST/StmtNodes.def"
1552
1553 // Transform expressions by calling TransformExpr.
1554#define STMT(Node, Parent)
1555#define EXPR(Node, Parent) case Stmt::Node##Class:
1556#include "clang/AST/StmtNodes.def"
1557 {
1558 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1559 if (E.isInvalid())
1560 return getSema().StmtError();
1561
1562 return getSema().Owned(E.takeAs<Stmt>());
1563 }
1564 }
1565
1566 return SemaRef.Owned(S->Retain());
1567}
1568
Douglas Gregor841324a2009-08-04 16:50:30 +00001569
Douglas Gregor2999faa2009-08-04 22:27:00 +00001570template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00001571Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1572 bool isAddressOfOperand) {
1573 if (!E)
1574 return SemaRef.Owned(E);
1575
1576 switch (E->getStmtClass()) {
1577 case Stmt::NoStmtClass: break;
1578#define STMT(Node, Parent) case Stmt::Node##Class: break;
1579#define EXPR(Node, Parent) \
1580 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1581#include "clang/AST/StmtNodes.def"
1582 }
1583
1584 return SemaRef.Owned(E->Retain());
Douglas Gregor72f34bb2009-08-06 22:17:10 +00001585}
1586
1587template<typename Derived>
Douglas Gregor12431cb2009-08-06 05:28:30 +00001588NestedNameSpecifier *
1589TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
1590 SourceRange Range) {
Douglas Gregor23a44be2009-08-20 07:17:43 +00001591 // Transform the prefix of this nested name specifier.
Douglas Gregor12431cb2009-08-06 05:28:30 +00001592 NestedNameSpecifier *Prefix = NNS->getPrefix();
1593 if (Prefix) {
1594 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
1595 if (!Prefix)
1596 return 0;
1597 }
1598
1599 switch (NNS->getKind()) {
1600 case NestedNameSpecifier::Identifier:
1601 assert(Prefix &&
1602 "Can't have an identifier nested-name-specifier with no prefix");
1603 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
1604 return NNS;
1605
1606 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1607 *NNS->getAsIdentifier());
1608
1609 case NestedNameSpecifier::Namespace: {
1610 NamespaceDecl *NS
1611 = cast_or_null<NamespaceDecl>(
1612 getDerived().TransformDecl(NNS->getAsNamespace()));
1613 if (!getDerived().AlwaysRebuild() &&
1614 Prefix == NNS->getPrefix() &&
1615 NS == NNS->getAsNamespace())
1616 return NNS;
1617
1618 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1619 }
1620
1621 case NestedNameSpecifier::Global:
1622 // There is no meaningful transformation that one could perform on the
1623 // global scope.
1624 return NNS;
1625
1626 case NestedNameSpecifier::TypeSpecWithTemplate:
1627 case NestedNameSpecifier::TypeSpec: {
1628 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor214d0462009-08-06 06:41:21 +00001629 if (T.isNull())
1630 return 0;
1631
Douglas Gregor12431cb2009-08-06 05:28:30 +00001632 if (!getDerived().AlwaysRebuild() &&
1633 Prefix == NNS->getPrefix() &&
1634 T == QualType(NNS->getAsType(), 0))
1635 return NNS;
1636
1637 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1638 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
1639 T);
1640 }
1641 }
1642
1643 // Required to silence a GCC warning
1644 return 0;
1645}
1646
1647template<typename Derived>
Douglas Gregor214d0462009-08-06 06:41:21 +00001648TemplateName
1649TreeTransform<Derived>::TransformTemplateName(TemplateName Name) {
1650 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
1651 NestedNameSpecifier *NNS
1652 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1653 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1654 if (!NNS)
1655 return TemplateName();
1656
1657 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
1658 TemplateDecl *TransTemplate
1659 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1660 if (!TransTemplate)
1661 return TemplateName();
1662
1663 if (!getDerived().AlwaysRebuild() &&
1664 NNS == QTN->getQualifier() &&
1665 TransTemplate == Template)
1666 return Name;
1667
1668 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1669 TransTemplate);
1670 }
1671
1672 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1673 assert(Ovl && "Not a template name or an overload set?");
1674 OverloadedFunctionDecl *TransOvl
1675 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1676 if (!TransOvl)
1677 return TemplateName();
1678
1679 if (!getDerived().AlwaysRebuild() &&
1680 NNS == QTN->getQualifier() &&
1681 TransOvl == Ovl)
1682 return Name;
1683
1684 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1685 TransOvl);
1686 }
1687
1688 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
1689 NestedNameSpecifier *NNS
1690 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1691 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1692 if (!NNS)
1693 return TemplateName();
1694
1695 if (!getDerived().AlwaysRebuild() &&
1696 NNS == DTN->getQualifier())
1697 return Name;
1698
1699 return getDerived().RebuildTemplateName(NNS, *DTN->getName());
1700 }
1701
1702 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1703 TemplateDecl *TransTemplate
1704 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1705 if (!TransTemplate)
1706 return TemplateName();
1707
1708 if (!getDerived().AlwaysRebuild() &&
1709 TransTemplate == Template)
1710 return Name;
1711
1712 return TemplateName(TransTemplate);
1713 }
1714
1715 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1716 assert(Ovl && "Not a template name or an overload set?");
1717 OverloadedFunctionDecl *TransOvl
1718 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1719 if (!TransOvl)
1720 return TemplateName();
1721
1722 if (!getDerived().AlwaysRebuild() &&
1723 TransOvl == Ovl)
1724 return Name;
1725
1726 return TemplateName(TransOvl);
1727}
1728
1729template<typename Derived>
Douglas Gregor2999faa2009-08-04 22:27:00 +00001730TemplateArgument
1731TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
1732 switch (Arg.getKind()) {
1733 case TemplateArgument::Null:
1734 case TemplateArgument::Integral:
1735 return Arg;
1736
1737 case TemplateArgument::Type: {
1738 QualType T = getDerived().TransformType(Arg.getAsType());
1739 if (T.isNull())
1740 return TemplateArgument();
1741 return TemplateArgument(Arg.getLocation(), T);
1742 }
1743
1744 case TemplateArgument::Declaration: {
1745 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
1746 if (!D)
1747 return TemplateArgument();
1748 return TemplateArgument(Arg.getLocation(), D);
1749 }
1750
1751 case TemplateArgument::Expression: {
1752 // Template argument expressions are not potentially evaluated.
1753 EnterExpressionEvaluationContext Unevaluated(getSema(),
1754 Action::Unevaluated);
1755
1756 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
1757 if (E.isInvalid())
1758 return TemplateArgument();
1759 return TemplateArgument(E.takeAs<Expr>());
1760 }
1761
1762 case TemplateArgument::Pack: {
1763 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1764 TransformedArgs.reserve(Arg.pack_size());
1765 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
1766 AEnd = Arg.pack_end();
1767 A != AEnd; ++A) {
1768 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
1769 if (TA.isNull())
1770 return TA;
1771
1772 TransformedArgs.push_back(TA);
1773 }
1774 TemplateArgument Result;
1775 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
1776 true);
1777 return Result;
1778 }
1779 }
1780
1781 // Work around bogus GCC warning
1782 return TemplateArgument();
1783}
1784
Douglas Gregor841324a2009-08-04 16:50:30 +00001785//===----------------------------------------------------------------------===//
1786// Type transformation
1787//===----------------------------------------------------------------------===//
1788
1789template<typename Derived>
1790QualType TreeTransform<Derived>::TransformType(QualType T) {
1791 if (getDerived().AlreadyTransformed(T))
1792 return T;
1793
1794 QualType Result;
1795 switch (T->getTypeClass()) {
1796#define ABSTRACT_TYPE(CLASS, PARENT)
1797#define TYPE(CLASS, PARENT) \
1798 case Type::CLASS: \
1799 Result = getDerived().Transform##CLASS##Type( \
1800 static_cast<CLASS##Type*>(T.getTypePtr())); \
1801 break;
1802#include "clang/AST/TypeNodes.def"
1803 }
1804
1805 if (Result.isNull() || T == Result)
1806 return Result;
1807
1808 return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
1809}
1810
1811template<typename Derived>
1812QualType
1813TreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
1814 if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
1815 return T.getWithAdditionalQualifiers(CVRQualifiers);
1816
1817 return T;
1818}
Argiris Kirtzidisfd3d5fd2009-08-19 01:28:17 +00001819
Douglas Gregor841324a2009-08-04 16:50:30 +00001820template<typename Derived>
1821QualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
1822 // FIXME: Implement
1823 return QualType(T, 0);
1824}
1825
1826template<typename Derived>
1827QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
1828 // Nothing to do
1829 return QualType(T, 0);
1830}
1831
1832template<typename Derived>
1833QualType TreeTransform<Derived>::TransformFixedWidthIntType(
1834 const FixedWidthIntType *T) {
1835 // FIXME: Implement
1836 return QualType(T, 0);
1837}
1838
1839template<typename Derived>
1840QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
1841 // FIXME: Implement
1842 return QualType(T, 0);
1843}
1844
1845template<typename Derived>
1846QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
1847 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1848 if (PointeeType.isNull())
1849 return QualType();
1850
1851 if (!getDerived().AlwaysRebuild() &&
1852 PointeeType == T->getPointeeType())
1853 return QualType(T, 0);
1854
1855 return getDerived().RebuildPointerType(PointeeType);
1856}
1857
1858template<typename Derived>
1859QualType
1860TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
1861 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1862 if (PointeeType.isNull())
1863 return QualType();
1864
1865 if (!getDerived().AlwaysRebuild() &&
1866 PointeeType == T->getPointeeType())
1867 return QualType(T, 0);
1868
1869 return getDerived().RebuildBlockPointerType(PointeeType);
1870}
1871
1872template<typename Derived>
1873QualType
1874TreeTransform<Derived>::TransformLValueReferenceType(
1875 const LValueReferenceType *T) {
1876 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1877 if (PointeeType.isNull())
1878 return QualType();
1879
1880 if (!getDerived().AlwaysRebuild() &&
1881 PointeeType == T->getPointeeType())
1882 return QualType(T, 0);
1883
1884 return getDerived().RebuildLValueReferenceType(PointeeType);
1885}
1886
1887template<typename Derived>
1888QualType
1889TreeTransform<Derived>::TransformRValueReferenceType(
1890 const RValueReferenceType *T) {
1891 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1892 if (PointeeType.isNull())
1893 return QualType();
1894
1895 if (!getDerived().AlwaysRebuild() &&
1896 PointeeType == T->getPointeeType())
1897 return QualType(T, 0);
1898
1899 return getDerived().RebuildRValueReferenceType(PointeeType);
1900}
1901
1902template<typename Derived>
1903QualType
1904TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
1905 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
1906 if (PointeeType.isNull())
1907 return QualType();
1908
1909 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
1910 if (ClassType.isNull())
1911 return QualType();
1912
1913 if (!getDerived().AlwaysRebuild() &&
1914 PointeeType == T->getPointeeType() &&
1915 ClassType == QualType(T->getClass(), 0))
1916 return QualType(T, 0);
1917
1918 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
1919}
1920
1921template<typename Derived>
1922QualType
1923TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
1924 QualType ElementType = getDerived().TransformType(T->getElementType());
1925 if (ElementType.isNull())
1926 return QualType();
1927
1928 if (!getDerived().AlwaysRebuild() &&
1929 ElementType == T->getElementType())
1930 return QualType(T, 0);
1931
1932 return getDerived().RebuildConstantArrayType(ElementType,
1933 T->getSizeModifier(),
1934 T->getSize(),
1935 T->getIndexTypeQualifier());
1936}
1937
1938template<typename Derived>
1939QualType
1940TreeTransform<Derived>::TransformConstantArrayWithExprType(
1941 const ConstantArrayWithExprType *T) {
1942 QualType ElementType = getDerived().TransformType(T->getElementType());
1943 if (ElementType.isNull())
1944 return QualType();
1945
Douglas Gregor2999faa2009-08-04 22:27:00 +00001946 // Array bounds are not potentially evaluated contexts
1947 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
1948
1949 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
1950 if (Size.isInvalid())
1951 return QualType();
1952
Douglas Gregor841324a2009-08-04 16:50:30 +00001953 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor2999faa2009-08-04 22:27:00 +00001954 ElementType == T->getElementType() &&
1955 Size.get() == T->getSizeExpr())
Douglas Gregor841324a2009-08-04 16:50:30 +00001956 return QualType(T, 0);
1957
1958 return getDerived().RebuildConstantArrayWithExprType(ElementType,
1959 T->getSizeModifier(),
1960 T->getSize(),
Douglas Gregor2999faa2009-08-04 22:27:00 +00001961 Size.takeAs<Expr>(),
Douglas Gregor841324a2009-08-04 16:50:30 +00001962 T->getIndexTypeQualifier(),
1963 T->getBracketsRange());
1964}
1965
1966template<typename Derived>
1967QualType
1968TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
1969 const ConstantArrayWithoutExprType *T) {
1970 QualType ElementType = getDerived().TransformType(T->getElementType());
1971 if (ElementType.isNull())
1972 return QualType();
1973
1974 if (!getDerived().AlwaysRebuild() &&
1975 ElementType == T->getElementType())
1976 return QualType(T, 0);
1977
1978 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
1979 T->getSizeModifier(),
1980 T->getSize(),
1981 T->getIndexTypeQualifier());
1982}
1983
1984template<typename Derived>
1985QualType TreeTransform<Derived>::TransformIncompleteArrayType(
1986 const IncompleteArrayType *T) {
1987 QualType ElementType = getDerived().TransformType(T->getElementType());
1988 if (ElementType.isNull())
1989 return QualType();
1990
1991 if (!getDerived().AlwaysRebuild() &&
1992 ElementType == T->getElementType())
1993 return QualType(T, 0);
1994
1995 return getDerived().RebuildIncompleteArrayType(ElementType,
1996 T->getSizeModifier(),
1997 T->getIndexTypeQualifier());
1998}
1999
2000template<typename Derived>
2001QualType TreeTransform<Derived>::TransformVariableArrayType(
2002 const VariableArrayType *T) {
2003 QualType ElementType = getDerived().TransformType(T->getElementType());
2004 if (ElementType.isNull())
2005 return QualType();
2006
Douglas Gregor2999faa2009-08-04 22:27:00 +00002007 // Array bounds are not potentially evaluated contexts
2008 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2009
Douglas Gregor841324a2009-08-04 16:50:30 +00002010 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2011 if (Size.isInvalid())
2012 return QualType();
2013
2014 if (!getDerived().AlwaysRebuild() &&
2015 ElementType == T->getElementType() &&
2016 Size.get() == T->getSizeExpr()) {
2017 Size.take();
2018 return QualType(T, 0);
2019 }
2020
2021 return getDerived().RebuildVariableArrayType(ElementType,
2022 T->getSizeModifier(),
2023 move(Size),
2024 T->getIndexTypeQualifier(),
2025 T->getBracketsRange());
2026}
2027
2028template<typename Derived>
2029QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
2030 const DependentSizedArrayType *T) {
2031 QualType ElementType = getDerived().TransformType(T->getElementType());
2032 if (ElementType.isNull())
2033 return QualType();
2034
Douglas Gregor2999faa2009-08-04 22:27:00 +00002035 // Array bounds are not potentially evaluated contexts
2036 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2037
Douglas Gregor841324a2009-08-04 16:50:30 +00002038 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2039 if (Size.isInvalid())
2040 return QualType();
2041
2042 if (!getDerived().AlwaysRebuild() &&
2043 ElementType == T->getElementType() &&
2044 Size.get() == T->getSizeExpr()) {
2045 Size.take();
2046 return QualType(T, 0);
2047 }
2048
2049 return getDerived().RebuildDependentSizedArrayType(ElementType,
2050 T->getSizeModifier(),
2051 move(Size),
2052 T->getIndexTypeQualifier(),
2053 T->getBracketsRange());
2054}
2055
2056template<typename Derived>
2057QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
2058 const DependentSizedExtVectorType *T) {
2059 QualType ElementType = getDerived().TransformType(T->getElementType());
2060 if (ElementType.isNull())
2061 return QualType();
2062
Douglas Gregor2999faa2009-08-04 22:27:00 +00002063 // Vector sizes are not potentially evaluated contexts
2064 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2065
Douglas Gregor841324a2009-08-04 16:50:30 +00002066 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2067 if (Size.isInvalid())
2068 return QualType();
2069
2070 if (!getDerived().AlwaysRebuild() &&
2071 ElementType == T->getElementType() &&
2072 Size.get() == T->getSizeExpr()) {
2073 Size.take();
2074 return QualType(T, 0);
2075 }
2076
2077 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
2078 move(Size),
2079 T->getAttributeLoc());
2080}
2081
2082template<typename Derived>
2083QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
2084 QualType ElementType = getDerived().TransformType(T->getElementType());
2085 if (ElementType.isNull())
2086 return QualType();
2087
2088 if (!getDerived().AlwaysRebuild() &&
2089 ElementType == T->getElementType())
2090 return QualType(T, 0);
2091
2092 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
2093}
2094
2095template<typename Derived>
2096QualType
2097TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
2098 QualType ElementType = getDerived().TransformType(T->getElementType());
2099 if (ElementType.isNull())
2100 return QualType();
2101
2102 if (!getDerived().AlwaysRebuild() &&
2103 ElementType == T->getElementType())
2104 return QualType(T, 0);
2105
2106 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
2107 /*FIXME*/SourceLocation());
2108}
2109
2110template<typename Derived>
2111QualType TreeTransform<Derived>::TransformFunctionProtoType(
2112 const FunctionProtoType *T) {
2113 QualType ResultType = getDerived().TransformType(T->getResultType());
2114 if (ResultType.isNull())
2115 return QualType();
2116
2117 llvm::SmallVector<QualType, 4> ParamTypes;
2118 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
2119 ParamEnd = T->arg_type_end();
2120 Param != ParamEnd; ++Param) {
2121 QualType P = getDerived().TransformType(*Param);
2122 if (P.isNull())
2123 return QualType();
2124
2125 ParamTypes.push_back(P);
2126 }
2127
2128 if (!getDerived().AlwaysRebuild() &&
2129 ResultType == T->getResultType() &&
2130 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
2131 return QualType(T, 0);
2132
2133 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
2134 ParamTypes.size(), T->isVariadic(),
2135 T->getTypeQuals());
2136}
2137
2138template<typename Derived>
2139QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
2140 const FunctionNoProtoType *T) {
2141 // FIXME: Implement
2142 return QualType(T, 0);
2143}
2144
2145template<typename Derived>
2146QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
2147 TypedefDecl *Typedef
2148 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2149 if (!Typedef)
2150 return QualType();
2151
2152 if (!getDerived().AlwaysRebuild() &&
2153 Typedef == T->getDecl())
2154 return QualType(T, 0);
2155
2156 return getDerived().RebuildTypedefType(Typedef);
2157}
2158
2159template<typename Derived>
2160QualType TreeTransform<Derived>::TransformTypeOfExprType(
2161 const TypeOfExprType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00002162 // typeof expressions are not potentially evaluated contexts
2163 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2164
Douglas Gregor841324a2009-08-04 16:50:30 +00002165 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2166 if (E.isInvalid())
2167 return QualType();
2168
2169 if (!getDerived().AlwaysRebuild() &&
2170 E.get() == T->getUnderlyingExpr()) {
2171 E.take();
2172 return QualType(T, 0);
2173 }
2174
2175 return getDerived().RebuildTypeOfExprType(move(E));
2176}
2177
2178template<typename Derived>
2179QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
2180 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2181 if (Underlying.isNull())
2182 return QualType();
2183
2184 if (!getDerived().AlwaysRebuild() &&
2185 Underlying == T->getUnderlyingType())
2186 return QualType(T, 0);
2187
2188 return getDerived().RebuildTypeOfType(Underlying);
2189}
2190
2191template<typename Derived>
2192QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00002193 // decltype expressions are not potentially evaluated contexts
2194 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2195
Douglas Gregor841324a2009-08-04 16:50:30 +00002196 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2197 if (E.isInvalid())
2198 return QualType();
2199
2200 if (!getDerived().AlwaysRebuild() &&
2201 E.get() == T->getUnderlyingExpr()) {
2202 E.take();
2203 return QualType(T, 0);
2204 }
2205
2206 return getDerived().RebuildDecltypeType(move(E));
2207}
2208
2209template<typename Derived>
2210QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
2211 RecordDecl *Record
2212 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
2213 if (!Record)
2214 return QualType();
2215
2216 if (!getDerived().AlwaysRebuild() &&
2217 Record == T->getDecl())
2218 return QualType(T, 0);
2219
2220 return getDerived().RebuildRecordType(Record);
2221}
2222
2223template<typename Derived>
2224QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
2225 EnumDecl *Enum
2226 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
2227 if (!Enum)
2228 return QualType();
2229
2230 if (!getDerived().AlwaysRebuild() &&
2231 Enum == T->getDecl())
2232 return QualType(T, 0);
2233
2234 return getDerived().RebuildEnumType(Enum);
2235}
2236
2237template<typename Derived>
2238QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
2239 const TemplateTypeParmType *T) {
2240 // Nothing to do
2241 return QualType(T, 0);
2242}
2243
2244template<typename Derived>
2245QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2246 const TemplateSpecializationType *T) {
2247 TemplateName Template
2248 = getDerived().TransformTemplateName(T->getTemplateName());
2249 if (Template.isNull())
2250 return QualType();
2251
2252 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2253 NewTemplateArgs.reserve(T->getNumArgs());
2254 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2255 Arg != ArgEnd; ++Arg) {
2256 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2257 if (NewArg.isNull())
2258 return QualType();
2259
2260 NewTemplateArgs.push_back(NewArg);
2261 }
2262
2263 // FIXME: early abort if all of the template arguments and such are the
2264 // same.
2265
2266 // FIXME: We're missing the locations of the template name, '<', and '>'.
2267 return getDerived().RebuildTemplateSpecializationType(Template,
2268 NewTemplateArgs.data(),
2269 NewTemplateArgs.size());
2270}
2271
2272template<typename Derived>
2273QualType TreeTransform<Derived>::TransformQualifiedNameType(
2274 const QualifiedNameType *T) {
2275 NestedNameSpecifier *NNS
2276 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2277 SourceRange());
2278 if (!NNS)
2279 return QualType();
2280
2281 QualType Named = getDerived().TransformType(T->getNamedType());
2282 if (Named.isNull())
2283 return QualType();
2284
2285 if (!getDerived().AlwaysRebuild() &&
2286 NNS == T->getQualifier() &&
2287 Named == T->getNamedType())
2288 return QualType(T, 0);
2289
2290 return getDerived().RebuildQualifiedNameType(NNS, Named);
2291}
2292
2293template<typename Derived>
2294QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
2295 NestedNameSpecifier *NNS
2296 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor3f220e82009-08-06 16:20:37 +00002297 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregor841324a2009-08-04 16:50:30 +00002298 if (!NNS)
2299 return QualType();
2300
2301 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
2302 QualType NewTemplateId
2303 = getDerived().TransformType(QualType(TemplateId, 0));
2304 if (NewTemplateId.isNull())
2305 return QualType();
2306
2307 if (!getDerived().AlwaysRebuild() &&
2308 NNS == T->getQualifier() &&
2309 NewTemplateId == QualType(TemplateId, 0))
2310 return QualType(T, 0);
2311
2312 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
2313 }
2314
2315 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
2316}
2317
2318template<typename Derived>
2319QualType TreeTransform<Derived>::TransformObjCInterfaceType(
2320 const ObjCInterfaceType *T) {
2321 // FIXME: Implement
2322 return QualType(T, 0);
2323}
2324
2325template<typename Derived>
2326QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
2327 const ObjCObjectPointerType *T) {
2328 // FIXME: Implement
2329 return QualType(T, 0);
2330}
2331
2332//===----------------------------------------------------------------------===//
Douglas Gregor23a44be2009-08-20 07:17:43 +00002333// Statement transformation
2334//===----------------------------------------------------------------------===//
2335template<typename Derived>
2336Sema::OwningStmtResult
2337TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2338 return SemaRef.Owned(S->Retain());
2339}
2340
2341template<typename Derived>
2342Sema::OwningStmtResult
2343TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2344 return getDerived().TransformCompoundStmt(S, false);
2345}
2346
2347template<typename Derived>
2348Sema::OwningStmtResult
2349TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
2350 bool IsStmtExpr) {
2351 bool SubStmtChanged = false;
2352 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2353 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2354 B != BEnd; ++B) {
2355 OwningStmtResult Result = getDerived().TransformStmt(*B);
2356 if (Result.isInvalid())
2357 return getSema().StmtError();
2358
2359 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2360 Statements.push_back(Result.takeAs<Stmt>());
2361 }
2362
2363 if (!getDerived().AlwaysRebuild() &&
2364 !SubStmtChanged)
2365 return SemaRef.Owned(S->Retain());
2366
2367 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2368 move_arg(Statements),
2369 S->getRBracLoc(),
2370 IsStmtExpr);
2371}
2372
2373template<typename Derived>
2374Sema::OwningStmtResult
2375TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
2376 // The case value expressions are not potentially evaluated.
2377 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2378
2379 // Transform the left-hand case value.
2380 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2381 if (LHS.isInvalid())
2382 return SemaRef.StmtError();
2383
2384 // Transform the right-hand case value (for the GNU case-range extension).
2385 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2386 if (RHS.isInvalid())
2387 return SemaRef.StmtError();
2388
2389 // Build the case statement.
2390 // Case statements are always rebuilt so that they will attached to their
2391 // transformed switch statement.
2392 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2393 move(LHS),
2394 S->getEllipsisLoc(),
2395 move(RHS),
2396 S->getColonLoc());
2397 if (Case.isInvalid())
2398 return SemaRef.StmtError();
2399
2400 // Transform the statement following the case
2401 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2402 if (SubStmt.isInvalid())
2403 return SemaRef.StmtError();
2404
2405 // Attach the body to the case statement
2406 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2407}
2408
2409template<typename Derived>
2410Sema::OwningStmtResult
2411TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
2412 // Transform the statement following the default case
2413 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2414 if (SubStmt.isInvalid())
2415 return SemaRef.StmtError();
2416
2417 // Default statements are always rebuilt
2418 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2419 move(SubStmt));
2420}
2421
2422template<typename Derived>
2423Sema::OwningStmtResult
2424TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
2425 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2426 if (SubStmt.isInvalid())
2427 return SemaRef.StmtError();
2428
2429 // FIXME: Pass the real colon location in.
2430 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2431 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2432 move(SubStmt));
2433}
2434
2435template<typename Derived>
2436Sema::OwningStmtResult
2437TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
2438 // Transform the condition
2439 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2440 if (Cond.isInvalid())
2441 return SemaRef.StmtError();
2442
2443 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
2444
2445 // Transform the "then" branch.
2446 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2447 if (Then.isInvalid())
2448 return SemaRef.StmtError();
2449
2450 // Transform the "else" branch.
2451 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2452 if (Else.isInvalid())
2453 return SemaRef.StmtError();
2454
2455 if (!getDerived().AlwaysRebuild() &&
2456 FullCond->get() == S->getCond() &&
2457 Then.get() == S->getThen() &&
2458 Else.get() == S->getElse())
2459 return SemaRef.Owned(S->Retain());
2460
2461 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
2462 S->getElseLoc(), move(Else));
2463}
2464
2465template<typename Derived>
2466Sema::OwningStmtResult
2467TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
2468 // Transform the condition.
2469 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2470 if (Cond.isInvalid())
2471 return SemaRef.StmtError();
2472
2473 // Rebuild the switch statement.
2474 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2475 if (Switch.isInvalid())
2476 return SemaRef.StmtError();
2477
2478 // Transform the body of the switch statement.
2479 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2480 if (Body.isInvalid())
2481 return SemaRef.StmtError();
2482
2483 // Complete the switch statement.
2484 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2485 move(Body));
2486}
2487
2488template<typename Derived>
2489Sema::OwningStmtResult
2490TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
2491 // Transform the condition
2492 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2493 if (Cond.isInvalid())
2494 return SemaRef.StmtError();
2495
2496 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
2497
2498 // Transform the body
2499 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2500 if (Body.isInvalid())
2501 return SemaRef.StmtError();
2502
2503 if (!getDerived().AlwaysRebuild() &&
2504 FullCond->get() == S->getCond() &&
2505 Body.get() == S->getBody())
2506 return SemaRef.Owned(S->Retain());
2507
2508 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2509}
2510
2511template<typename Derived>
2512Sema::OwningStmtResult
2513TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2514 // Transform the condition
2515 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2516 if (Cond.isInvalid())
2517 return SemaRef.StmtError();
2518
2519 // Transform the body
2520 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2521 if (Body.isInvalid())
2522 return SemaRef.StmtError();
2523
2524 if (!getDerived().AlwaysRebuild() &&
2525 Cond.get() == S->getCond() &&
2526 Body.get() == S->getBody())
2527 return SemaRef.Owned(S->Retain());
2528
2529 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
2530 /*FIXME:*/S->getWhileLoc(), move(Cond),
2531 S->getRParenLoc());
2532}
2533
2534template<typename Derived>
2535Sema::OwningStmtResult
2536TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
2537 // Transform the initialization statement
2538 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
2539 if (Init.isInvalid())
2540 return SemaRef.StmtError();
2541
2542 // Transform the condition
2543 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2544 if (Cond.isInvalid())
2545 return SemaRef.StmtError();
2546
2547 // Transform the increment
2548 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
2549 if (Inc.isInvalid())
2550 return SemaRef.StmtError();
2551
2552 // Transform the body
2553 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2554 if (Body.isInvalid())
2555 return SemaRef.StmtError();
2556
2557 if (!getDerived().AlwaysRebuild() &&
2558 Init.get() == S->getInit() &&
2559 Cond.get() == S->getCond() &&
2560 Inc.get() == S->getInc() &&
2561 Body.get() == S->getBody())
2562 return SemaRef.Owned(S->Retain());
2563
2564 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
2565 move(Init), move(Cond), move(Inc),
2566 S->getRParenLoc(), move(Body));
2567}
2568
2569template<typename Derived>
2570Sema::OwningStmtResult
2571TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
2572 // Goto statements must always be rebuilt, to resolve the label.
2573 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
2574 S->getLabel());
2575}
2576
2577template<typename Derived>
2578Sema::OwningStmtResult
2579TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
2580 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
2581 if (Target.isInvalid())
2582 return SemaRef.StmtError();
2583
2584 if (!getDerived().AlwaysRebuild() &&
2585 Target.get() == S->getTarget())
2586 return SemaRef.Owned(S->Retain());
2587
2588 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
2589 move(Target));
2590}
2591
2592template<typename Derived>
2593Sema::OwningStmtResult
2594TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
2595 return SemaRef.Owned(S->Retain());
2596}
2597
2598template<typename Derived>
2599Sema::OwningStmtResult
2600TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
2601 return SemaRef.Owned(S->Retain());
2602}
2603
2604template<typename Derived>
2605Sema::OwningStmtResult
2606TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
2607 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
2608 if (Result.isInvalid())
2609 return SemaRef.StmtError();
2610
2611 // FIXME: We always rebuild the return statement because there is no way
2612 // to tell whether the return type of the function has changed.
2613 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
2614}
2615
2616template<typename Derived>
2617Sema::OwningStmtResult
2618TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
2619 bool DeclChanged = false;
2620 llvm::SmallVector<Decl *, 4> Decls;
2621 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
2622 D != DEnd; ++D) {
2623 Decl *Transformed = getDerived().TransformDefinition(*D);
2624 if (!Transformed)
2625 return SemaRef.StmtError();
2626
2627 if (Transformed != *D)
2628 DeclChanged = true;
2629
2630 Decls.push_back(Transformed);
2631 }
2632
2633 if (!getDerived().AlwaysRebuild() && !DeclChanged)
2634 return SemaRef.Owned(S->Retain());
2635
2636 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
2637 S->getStartLoc(), S->getEndLoc());
2638}
2639
2640template<typename Derived>
2641Sema::OwningStmtResult
2642TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
2643 assert(false && "SwitchCase is abstract and cannot be transformed");
2644 return SemaRef.Owned(S->Retain());
2645}
2646
2647template<typename Derived>
2648Sema::OwningStmtResult
2649TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
2650 // FIXME: Implement!
2651 assert(false && "Inline assembly cannot be transformed");
2652 return SemaRef.Owned(S->Retain());
2653}
2654
2655
2656template<typename Derived>
2657Sema::OwningStmtResult
2658TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
2659 // FIXME: Implement this
2660 assert(false && "Cannot transform an Objective-C @try statement");
2661 return SemaRef.Owned(S->Retain());
2662}
2663
2664template<typename Derived>
2665Sema::OwningStmtResult
2666TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
2667 // FIXME: Implement this
2668 assert(false && "Cannot transform an Objective-C @catch statement");
2669 return SemaRef.Owned(S->Retain());
2670}
2671
2672template<typename Derived>
2673Sema::OwningStmtResult
2674TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
2675 // FIXME: Implement this
2676 assert(false && "Cannot transform an Objective-C @finally statement");
2677 return SemaRef.Owned(S->Retain());
2678}
2679
2680template<typename Derived>
2681Sema::OwningStmtResult
2682TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
2683 // FIXME: Implement this
2684 assert(false && "Cannot transform an Objective-C @throw statement");
2685 return SemaRef.Owned(S->Retain());
2686}
2687
2688template<typename Derived>
2689Sema::OwningStmtResult
2690TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
2691 ObjCAtSynchronizedStmt *S) {
2692 // FIXME: Implement this
2693 assert(false && "Cannot transform an Objective-C @synchronized statement");
2694 return SemaRef.Owned(S->Retain());
2695}
2696
2697template<typename Derived>
2698Sema::OwningStmtResult
2699TreeTransform<Derived>::TransformObjCForCollectionStmt(
2700 ObjCForCollectionStmt *S) {
2701 // FIXME: Implement this
2702 assert(false && "Cannot transform an Objective-C for-each statement");
2703 return SemaRef.Owned(S->Retain());
2704}
2705
2706
2707template<typename Derived>
2708Sema::OwningStmtResult
2709TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
2710 // Transform the exception declaration, if any.
2711 VarDecl *Var = 0;
2712 if (S->getExceptionDecl()) {
2713 VarDecl *ExceptionDecl = S->getExceptionDecl();
2714 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
2715 ExceptionDecl->getDeclName());
2716
2717 QualType T = getDerived().TransformType(ExceptionDecl->getType());
2718 if (T.isNull())
2719 return SemaRef.StmtError();
2720
2721 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
2722 T,
2723 ExceptionDecl->getDeclaratorInfo(),
2724 ExceptionDecl->getIdentifier(),
2725 ExceptionDecl->getLocation(),
2726 /*FIXME: Inaccurate*/
2727 SourceRange(ExceptionDecl->getLocation()));
2728 if (!Var || Var->isInvalidDecl()) {
2729 if (Var)
2730 Var->Destroy(SemaRef.Context);
2731 return SemaRef.StmtError();
2732 }
2733 }
2734
2735 // Transform the actual exception handler.
2736 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
2737 if (Handler.isInvalid()) {
2738 if (Var)
2739 Var->Destroy(SemaRef.Context);
2740 return SemaRef.StmtError();
2741 }
2742
2743 if (!getDerived().AlwaysRebuild() &&
2744 !Var &&
2745 Handler.get() == S->getHandlerBlock())
2746 return SemaRef.Owned(S->Retain());
2747
2748 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
2749 Var,
2750 move(Handler));
2751}
2752
2753template<typename Derived>
2754Sema::OwningStmtResult
2755TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
2756 // Transform the try block itself.
2757 OwningStmtResult TryBlock
2758 = getDerived().TransformCompoundStmt(S->getTryBlock());
2759 if (TryBlock.isInvalid())
2760 return SemaRef.StmtError();
2761
2762 // Transform the handlers.
2763 bool HandlerChanged = false;
2764 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
2765 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
2766 OwningStmtResult Handler
2767 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
2768 if (Handler.isInvalid())
2769 return SemaRef.StmtError();
2770
2771 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
2772 Handlers.push_back(Handler.takeAs<Stmt>());
2773 }
2774
2775 if (!getDerived().AlwaysRebuild() &&
2776 TryBlock.get() == S->getTryBlock() &&
2777 !HandlerChanged)
2778 return SemaRef.Owned(S->Retain());
2779
2780 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
2781 move_arg(Handlers));
2782}
2783
2784//===----------------------------------------------------------------------===//
Douglas Gregor9d879762009-08-11 05:31:07 +00002785// Expression transformation
2786//===----------------------------------------------------------------------===//
2787template<typename Derived>
2788Sema::OwningExprResult
2789TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
2790 return SemaRef.Owned(E->Retain());
2791}
2792
2793template<typename Derived>
2794Sema::OwningExprResult
2795TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
2796 NamedDecl *ND
2797 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
2798 if (!ND)
2799 return SemaRef.ExprError();
2800
2801 if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
2802 return SemaRef.Owned(E->Retain());
2803
2804 return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
2805}
2806
2807template<typename Derived>
2808Sema::OwningExprResult
2809TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
2810 return SemaRef.Owned(E->Retain());
2811}
2812
2813template<typename Derived>
2814Sema::OwningExprResult
2815TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
2816 return SemaRef.Owned(E->Retain());
2817}
2818
2819template<typename Derived>
2820Sema::OwningExprResult
2821TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
2822 return SemaRef.Owned(E->Retain());
2823}
2824
2825template<typename Derived>
2826Sema::OwningExprResult
2827TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
2828 return SemaRef.Owned(E->Retain());
2829}
2830
2831template<typename Derived>
2832Sema::OwningExprResult
2833TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
2834 return SemaRef.Owned(E->Retain());
2835}
2836
2837template<typename Derived>
2838Sema::OwningExprResult
2839TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
2840 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
2841 if (SubExpr.isInvalid())
2842 return SemaRef.ExprError();
2843
2844 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
2845 return SemaRef.Owned(E->Retain());
2846
2847 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
2848 E->getRParen());
2849}
2850
2851template<typename Derived>
2852Sema::OwningExprResult
2853TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
2854 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
2855 if (SubExpr.isInvalid())
2856 return SemaRef.ExprError();
2857
2858 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
2859 return SemaRef.Owned(E->Retain());
2860
2861 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
2862 E->getOpcode(),
2863 move(SubExpr));
2864}
2865
2866template<typename Derived>
2867Sema::OwningExprResult
2868TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
2869 if (E->isArgumentType()) {
2870 QualType T = getDerived().TransformType(E->getArgumentType());
2871 if (T.isNull())
2872 return SemaRef.ExprError();
2873
2874 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
2875 return SemaRef.Owned(E->Retain());
2876
2877 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
2878 E->isSizeOf(),
2879 E->getSourceRange());
2880 }
2881
2882 Sema::OwningExprResult SubExpr(SemaRef);
2883 {
2884 // C++0x [expr.sizeof]p1:
2885 // The operand is either an expression, which is an unevaluated operand
2886 // [...]
2887 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2888
2889 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
2890 if (SubExpr.isInvalid())
2891 return SemaRef.ExprError();
2892
2893 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
2894 return SemaRef.Owned(E->Retain());
2895 }
2896
2897 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
2898 E->isSizeOf(),
2899 E->getSourceRange());
2900}
2901
2902template<typename Derived>
2903Sema::OwningExprResult
2904TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
2905 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
2906 if (LHS.isInvalid())
2907 return SemaRef.ExprError();
2908
2909 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
2910 if (RHS.isInvalid())
2911 return SemaRef.ExprError();
2912
2913
2914 if (!getDerived().AlwaysRebuild() &&
2915 LHS.get() == E->getLHS() &&
2916 RHS.get() == E->getRHS())
2917 return SemaRef.Owned(E->Retain());
2918
2919 return getDerived().RebuildArraySubscriptExpr(move(LHS),
2920 /*FIXME:*/E->getLHS()->getLocStart(),
2921 move(RHS),
2922 E->getRBracketLoc());
2923}
2924
2925template<typename Derived>
2926Sema::OwningExprResult
2927TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
2928 // Transform the callee.
2929 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
2930 if (Callee.isInvalid())
2931 return SemaRef.ExprError();
2932
2933 // Transform arguments.
2934 bool ArgChanged = false;
2935 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
2936 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
2937 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2938 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
2939 if (Arg.isInvalid())
2940 return SemaRef.ExprError();
2941
2942 // FIXME: Wrong source location information for the ','.
2943 FakeCommaLocs.push_back(
2944 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
2945
2946 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
2947 Args.push_back(Arg.takeAs<Expr>());
2948 }
2949
2950 if (!getDerived().AlwaysRebuild() &&
2951 Callee.get() == E->getCallee() &&
2952 !ArgChanged)
2953 return SemaRef.Owned(E->Retain());
2954
2955 // FIXME: Wrong source location information for the '('.
2956 SourceLocation FakeLParenLoc
2957 = ((Expr *)Callee.get())->getSourceRange().getBegin();
2958 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
2959 move_arg(Args),
2960 FakeCommaLocs.data(),
2961 E->getRParenLoc());
2962}
2963
2964template<typename Derived>
2965Sema::OwningExprResult
2966TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
2967 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
2968 if (Base.isInvalid())
2969 return SemaRef.ExprError();
2970
2971 NamedDecl *Member
2972 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
2973 if (!Member)
2974 return SemaRef.ExprError();
2975
2976 if (!getDerived().AlwaysRebuild() &&
2977 Base.get() == E->getBase() &&
2978 Member == E->getMemberDecl())
2979 return SemaRef.Owned(E->Retain());
2980
2981 // FIXME: Bogus source location for the operator
2982 SourceLocation FakeOperatorLoc
2983 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
2984
2985 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
2986 E->isArrow(),
2987 E->getMemberLoc(),
2988 Member);
2989}
2990
2991template<typename Derived>
2992Sema::OwningExprResult
2993TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
2994 assert(false && "Cannot transform abstract class");
2995 return SemaRef.Owned(E->Retain());
2996}
2997
2998template<typename Derived>
2999Sema::OwningExprResult
3000TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
3001 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3002 if (LHS.isInvalid())
3003 return SemaRef.ExprError();
3004
3005 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3006 if (RHS.isInvalid())
3007 return SemaRef.ExprError();
3008
3009 if (!getDerived().AlwaysRebuild() &&
3010 LHS.get() == E->getLHS() &&
3011 RHS.get() == E->getRHS())
3012 return SemaRef.Owned(E->Retain());
3013
3014 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3015 move(LHS), move(RHS));
3016}
3017
3018template<typename Derived>
3019Sema::OwningExprResult
3020TreeTransform<Derived>::TransformCompoundAssignOperator(
3021 CompoundAssignOperator *E) {
3022 return getDerived().TransformBinaryOperator(E);
3023}
3024
3025template<typename Derived>
3026Sema::OwningExprResult
3027TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
3028 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3029 if (Cond.isInvalid())
3030 return SemaRef.ExprError();
3031
3032 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3033 if (LHS.isInvalid())
3034 return SemaRef.ExprError();
3035
3036 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3037 if (RHS.isInvalid())
3038 return SemaRef.ExprError();
3039
3040 if (!getDerived().AlwaysRebuild() &&
3041 Cond.get() == E->getCond() &&
3042 LHS.get() == E->getLHS() &&
3043 RHS.get() == E->getRHS())
3044 return SemaRef.Owned(E->Retain());
3045
Douglas Gregor9d879762009-08-11 05:31:07 +00003046 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor34619872009-08-26 14:37:04 +00003047 E->getQuestionLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003048 move(LHS),
Douglas Gregor34619872009-08-26 14:37:04 +00003049 E->getColonLoc(),
Douglas Gregor9d879762009-08-11 05:31:07 +00003050 move(RHS));
3051}
3052
3053template<typename Derived>
3054Sema::OwningExprResult
3055TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
3056 QualType T = getDerived().TransformType(E->getType());
3057 if (T.isNull())
3058 return SemaRef.ExprError();
3059
3060 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3061 if (SubExpr.isInvalid())
3062 return SemaRef.ExprError();
3063
3064 if (!getDerived().AlwaysRebuild() &&
3065 T == E->getType() &&
3066 SubExpr.get() == E->getSubExpr())
3067 return SemaRef.Owned(E->Retain());
3068
3069 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
3070 move(SubExpr),
3071 E->isLvalueCast());
3072}
3073
3074template<typename Derived>
3075Sema::OwningExprResult
3076TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3077 assert(false && "Cannot transform abstract class");
3078 return SemaRef.Owned(E->Retain());
3079}
3080
3081template<typename Derived>
3082Sema::OwningExprResult
3083TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
3084 QualType T;
3085 {
3086 // FIXME: Source location isn't quite accurate.
3087 SourceLocation TypeStartLoc
3088 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3089 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
3090
3091 T = getDerived().TransformType(E->getTypeAsWritten());
3092 if (T.isNull())
3093 return SemaRef.ExprError();
3094 }
3095
3096 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3097 if (SubExpr.isInvalid())
3098 return SemaRef.ExprError();
3099
3100 if (!getDerived().AlwaysRebuild() &&
3101 T == E->getTypeAsWritten() &&
3102 SubExpr.get() == E->getSubExpr())
3103 return SemaRef.Owned(E->Retain());
3104
3105 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3106 E->getRParenLoc(),
3107 move(SubExpr));
3108}
3109
3110template<typename Derived>
3111Sema::OwningExprResult
3112TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3113 QualType T;
3114 {
3115 // FIXME: Source location isn't quite accurate.
3116 SourceLocation FakeTypeLoc
3117 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3118 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
3119
3120 T = getDerived().TransformType(E->getType());
3121 if (T.isNull())
3122 return SemaRef.ExprError();
3123 }
3124
3125 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3126 if (Init.isInvalid())
3127 return SemaRef.ExprError();
3128
3129 if (!getDerived().AlwaysRebuild() &&
3130 T == E->getType() &&
3131 Init.get() == E->getInitializer())
3132 return SemaRef.Owned(E->Retain());
3133
3134 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3135 /*FIXME:*/E->getInitializer()->getLocEnd(),
3136 move(Init));
3137}
3138
3139template<typename Derived>
3140Sema::OwningExprResult
3141TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
3142 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3143 if (Base.isInvalid())
3144 return SemaRef.ExprError();
3145
3146 if (!getDerived().AlwaysRebuild() &&
3147 Base.get() == E->getBase())
3148 return SemaRef.Owned(E->Retain());
3149
3150 // FIXME: Bad source location
3151 SourceLocation FakeOperatorLoc
3152 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3153 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3154 E->getAccessorLoc(),
3155 E->getAccessor());
3156}
3157
3158template<typename Derived>
3159Sema::OwningExprResult
3160TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
3161 bool InitChanged = false;
3162
3163 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3164 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3165 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3166 if (Init.isInvalid())
3167 return SemaRef.ExprError();
3168
3169 InitChanged = InitChanged || Init.get() != E->getInit(I);
3170 Inits.push_back(Init.takeAs<Expr>());
3171 }
3172
3173 if (!getDerived().AlwaysRebuild() && !InitChanged)
3174 return SemaRef.Owned(E->Retain());
3175
3176 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3177 E->getRBraceLoc());
3178}
3179
3180template<typename Derived>
3181Sema::OwningExprResult
3182TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
3183 Designation Desig;
3184
Douglas Gregor23a44be2009-08-20 07:17:43 +00003185 // transform the initializer value
Douglas Gregor9d879762009-08-11 05:31:07 +00003186 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3187 if (Init.isInvalid())
3188 return SemaRef.ExprError();
3189
Douglas Gregor23a44be2009-08-20 07:17:43 +00003190 // transform the designators.
Douglas Gregor9d879762009-08-11 05:31:07 +00003191 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3192 bool ExprChanged = false;
3193 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3194 DEnd = E->designators_end();
3195 D != DEnd; ++D) {
3196 if (D->isFieldDesignator()) {
3197 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3198 D->getDotLoc(),
3199 D->getFieldLoc()));
3200 continue;
3201 }
3202
3203 if (D->isArrayDesignator()) {
3204 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3205 if (Index.isInvalid())
3206 return SemaRef.ExprError();
3207
3208 Desig.AddDesignator(Designator::getArray(Index.get(),
3209 D->getLBracketLoc()));
3210
3211 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3212 ArrayExprs.push_back(Index.release());
3213 continue;
3214 }
3215
3216 assert(D->isArrayRangeDesignator() && "New kind of designator?");
3217 OwningExprResult Start
3218 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3219 if (Start.isInvalid())
3220 return SemaRef.ExprError();
3221
3222 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3223 if (End.isInvalid())
3224 return SemaRef.ExprError();
3225
3226 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
3227 End.get(),
3228 D->getLBracketLoc(),
3229 D->getEllipsisLoc()));
3230
3231 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3232 End.get() != E->getArrayRangeEnd(*D);
3233
3234 ArrayExprs.push_back(Start.release());
3235 ArrayExprs.push_back(End.release());
3236 }
3237
3238 if (!getDerived().AlwaysRebuild() &&
3239 Init.get() == E->getInit() &&
3240 !ExprChanged)
3241 return SemaRef.Owned(E->Retain());
3242
3243 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3244 E->getEqualOrColonLoc(),
3245 E->usesGNUSyntax(), move(Init));
3246}
3247
3248template<typename Derived>
3249Sema::OwningExprResult
3250TreeTransform<Derived>::TransformImplicitValueInitExpr(
3251 ImplicitValueInitExpr *E) {
3252 QualType T = getDerived().TransformType(E->getType());
3253 if (T.isNull())
3254 return SemaRef.ExprError();
3255
3256 if (!getDerived().AlwaysRebuild() &&
3257 T == E->getType())
3258 return SemaRef.Owned(E->Retain());
3259
3260 return getDerived().RebuildImplicitValueInitExpr(T);
3261}
3262
3263template<typename Derived>
3264Sema::OwningExprResult
3265TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3266 // FIXME: Do we want the type as written?
3267 QualType T;
3268
3269 {
3270 // FIXME: Source location isn't quite accurate.
3271 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3272 T = getDerived().TransformType(E->getType());
3273 if (T.isNull())
3274 return SemaRef.ExprError();
3275 }
3276
3277 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3278 if (SubExpr.isInvalid())
3279 return SemaRef.ExprError();
3280
3281 if (!getDerived().AlwaysRebuild() &&
3282 T == E->getType() &&
3283 SubExpr.get() == E->getSubExpr())
3284 return SemaRef.Owned(E->Retain());
3285
3286 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3287 T, E->getRParenLoc());
3288}
3289
3290template<typename Derived>
3291Sema::OwningExprResult
3292TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3293 bool ArgumentChanged = false;
3294 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3295 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3296 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3297 if (Init.isInvalid())
3298 return SemaRef.ExprError();
3299
3300 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3301 Inits.push_back(Init.takeAs<Expr>());
3302 }
3303
3304 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3305 move_arg(Inits),
3306 E->getRParenLoc());
3307}
3308
3309/// \brief Transform an address-of-label expression.
3310///
3311/// By default, the transformation of an address-of-label expression always
3312/// rebuilds the expression, so that the label identifier can be resolved to
3313/// the corresponding label statement by semantic analysis.
3314template<typename Derived>
3315Sema::OwningExprResult
3316TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
3317 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3318 E->getLabel());
3319}
3320
3321template<typename Derived>
3322Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
3323 OwningStmtResult SubStmt
3324 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3325 if (SubStmt.isInvalid())
3326 return SemaRef.ExprError();
3327
3328 if (!getDerived().AlwaysRebuild() &&
3329 SubStmt.get() == E->getSubStmt())
3330 return SemaRef.Owned(E->Retain());
3331
3332 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
3333 move(SubStmt),
3334 E->getRParenLoc());
3335}
3336
3337template<typename Derived>
3338Sema::OwningExprResult
3339TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
3340 QualType T1, T2;
3341 {
3342 // FIXME: Source location isn't quite accurate.
3343 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3344
3345 T1 = getDerived().TransformType(E->getArgType1());
3346 if (T1.isNull())
3347 return SemaRef.ExprError();
3348
3349 T2 = getDerived().TransformType(E->getArgType2());
3350 if (T2.isNull())
3351 return SemaRef.ExprError();
3352 }
3353
3354 if (!getDerived().AlwaysRebuild() &&
3355 T1 == E->getArgType1() &&
3356 T2 == E->getArgType2())
3357 return SemaRef.Owned(E->Retain());
3358
3359 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3360 T1, T2, E->getRParenLoc());
3361}
3362
3363template<typename Derived>
3364Sema::OwningExprResult
3365TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
3366 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3367 if (Cond.isInvalid())
3368 return SemaRef.ExprError();
3369
3370 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3371 if (LHS.isInvalid())
3372 return SemaRef.ExprError();
3373
3374 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3375 if (RHS.isInvalid())
3376 return SemaRef.ExprError();
3377
3378 if (!getDerived().AlwaysRebuild() &&
3379 Cond.get() == E->getCond() &&
3380 LHS.get() == E->getLHS() &&
3381 RHS.get() == E->getRHS())
3382 return SemaRef.Owned(E->Retain());
3383
3384 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3385 move(Cond), move(LHS), move(RHS),
3386 E->getRParenLoc());
3387}
3388
3389template<typename Derived>
3390Sema::OwningExprResult
3391TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3392 return SemaRef.Owned(E->Retain());
3393}
3394
3395template<typename Derived>
3396Sema::OwningExprResult
3397TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3398 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3399 if (Callee.isInvalid())
3400 return SemaRef.ExprError();
3401
3402 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3403 if (First.isInvalid())
3404 return SemaRef.ExprError();
3405
3406 OwningExprResult Second(SemaRef);
3407 if (E->getNumArgs() == 2) {
3408 Second = getDerived().TransformExpr(E->getArg(1));
3409 if (Second.isInvalid())
3410 return SemaRef.ExprError();
3411 }
3412
3413 if (!getDerived().AlwaysRebuild() &&
3414 Callee.get() == E->getCallee() &&
3415 First.get() == E->getArg(0) &&
3416 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3417 return SemaRef.Owned(E->Retain());
3418
3419 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3420 E->getOperatorLoc(),
3421 move(Callee),
3422 move(First),
3423 move(Second));
3424}
3425
3426template<typename Derived>
3427Sema::OwningExprResult
3428TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
3429 return getDerived().TransformCallExpr(E);
3430}
3431
3432template<typename Derived>
3433Sema::OwningExprResult
3434TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3435 QualType ExplicitTy;
3436 {
3437 // FIXME: Source location isn't quite accurate.
3438 SourceLocation TypeStartLoc
3439 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3440 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
3441
3442 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3443 if (ExplicitTy.isNull())
3444 return SemaRef.ExprError();
3445 }
3446
3447 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3448 if (SubExpr.isInvalid())
3449 return SemaRef.ExprError();
3450
3451 if (!getDerived().AlwaysRebuild() &&
3452 ExplicitTy == E->getTypeAsWritten() &&
3453 SubExpr.get() == E->getSubExpr())
3454 return SemaRef.Owned(E->Retain());
3455
3456 // FIXME: Poor source location information here.
3457 SourceLocation FakeLAngleLoc
3458 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3459 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3460 SourceLocation FakeRParenLoc
3461 = SemaRef.PP.getLocForEndOfToken(
3462 E->getSubExpr()->getSourceRange().getEnd());
3463 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
3464 E->getStmtClass(),
3465 FakeLAngleLoc,
3466 ExplicitTy,
3467 FakeRAngleLoc,
3468 FakeRAngleLoc,
3469 move(SubExpr),
3470 FakeRParenLoc);
3471}
3472
3473template<typename Derived>
3474Sema::OwningExprResult
3475TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
3476 return getDerived().TransformCXXNamedCastExpr(E);
3477}
3478
3479template<typename Derived>
3480Sema::OwningExprResult
3481TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
3482 return getDerived().TransformCXXNamedCastExpr(E);
3483}
3484
3485template<typename Derived>
3486Sema::OwningExprResult
3487TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
3488 CXXReinterpretCastExpr *E) {
3489 return getDerived().TransformCXXNamedCastExpr(E);
3490}
3491
3492template<typename Derived>
3493Sema::OwningExprResult
3494TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
3495 return getDerived().TransformCXXNamedCastExpr(E);
3496}
3497
3498template<typename Derived>
3499Sema::OwningExprResult
3500TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
3501 CXXFunctionalCastExpr *E) {
3502 QualType ExplicitTy;
3503 {
3504 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3505
3506 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3507 if (ExplicitTy.isNull())
3508 return SemaRef.ExprError();
3509 }
3510
3511 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3512 if (SubExpr.isInvalid())
3513 return SemaRef.ExprError();
3514
3515 if (!getDerived().AlwaysRebuild() &&
3516 ExplicitTy == E->getTypeAsWritten() &&
3517 SubExpr.get() == E->getSubExpr())
3518 return SemaRef.Owned(E->Retain());
3519
3520 // FIXME: The end of the type's source range is wrong
3521 return getDerived().RebuildCXXFunctionalCastExpr(
3522 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
3523 ExplicitTy,
3524 /*FIXME:*/E->getSubExpr()->getLocStart(),
3525 move(SubExpr),
3526 E->getRParenLoc());
3527}
3528
3529template<typename Derived>
3530Sema::OwningExprResult
3531TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
3532 if (E->isTypeOperand()) {
3533 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3534
3535 QualType T = getDerived().TransformType(E->getTypeOperand());
3536 if (T.isNull())
3537 return SemaRef.ExprError();
3538
3539 if (!getDerived().AlwaysRebuild() &&
3540 T == E->getTypeOperand())
3541 return SemaRef.Owned(E->Retain());
3542
3543 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3544 /*FIXME:*/E->getLocStart(),
3545 T,
3546 E->getLocEnd());
3547 }
3548
3549 // We don't know whether the expression is potentially evaluated until
3550 // after we perform semantic analysis, so the expression is potentially
3551 // potentially evaluated.
3552 EnterExpressionEvaluationContext Unevaluated(SemaRef,
3553 Action::PotentiallyPotentiallyEvaluated);
3554
3555 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
3556 if (SubExpr.isInvalid())
3557 return SemaRef.ExprError();
3558
3559 if (!getDerived().AlwaysRebuild() &&
3560 SubExpr.get() == E->getExprOperand())
3561 return SemaRef.Owned(E->Retain());
3562
3563 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
3564 /*FIXME:*/E->getLocStart(),
3565 move(SubExpr),
3566 E->getLocEnd());
3567}
3568
3569template<typename Derived>
3570Sema::OwningExprResult
3571TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
3572 return SemaRef.Owned(E->Retain());
3573}
3574
3575template<typename Derived>
3576Sema::OwningExprResult
3577TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
3578 CXXNullPtrLiteralExpr *E) {
3579 return SemaRef.Owned(E->Retain());
3580}
3581
3582template<typename Derived>
3583Sema::OwningExprResult
3584TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
3585 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3586
3587 QualType T = getDerived().TransformType(E->getType());
3588 if (T.isNull())
3589 return SemaRef.ExprError();
3590
3591 if (!getDerived().AlwaysRebuild() &&
3592 T == E->getType())
3593 return SemaRef.Owned(E->Retain());
3594
3595 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
3596}
3597
3598template<typename Derived>
3599Sema::OwningExprResult
3600TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
3601 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3602 if (SubExpr.isInvalid())
3603 return SemaRef.ExprError();
3604
3605 if (!getDerived().AlwaysRebuild() &&
3606 SubExpr.get() == E->getSubExpr())
3607 return SemaRef.Owned(E->Retain());
3608
3609 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
3610}
3611
3612template<typename Derived>
3613Sema::OwningExprResult
3614TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
3615 ParmVarDecl *Param
3616 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
3617 if (!Param)
3618 return SemaRef.ExprError();
3619
3620 if (getDerived().AlwaysRebuild() &&
3621 Param == E->getParam())
3622 return SemaRef.Owned(E->Retain());
3623
3624 return getDerived().RebuildCXXDefaultArgExpr(Param);
3625}
3626
3627template<typename Derived>
3628Sema::OwningExprResult
3629TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
3630 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3631
3632 QualType T = getDerived().TransformType(E->getType());
3633 if (T.isNull())
3634 return SemaRef.ExprError();
3635
3636 if (!getDerived().AlwaysRebuild() &&
3637 T == E->getType())
3638 return SemaRef.Owned(E->Retain());
3639
3640 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
3641 /*FIXME:*/E->getTypeBeginLoc(),
3642 T,
3643 E->getRParenLoc());
3644}
3645
3646template<typename Derived>
3647Sema::OwningExprResult
3648TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
3649 VarDecl *Var
Douglas Gregor23a44be2009-08-20 07:17:43 +00003650 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregor9d879762009-08-11 05:31:07 +00003651 if (!Var)
3652 return SemaRef.ExprError();
3653
3654 if (!getDerived().AlwaysRebuild() &&
3655 Var == E->getVarDecl())
3656 return SemaRef.Owned(E->Retain());
3657
3658 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
3659 /*FIXME:*/E->getStartLoc(),
3660 Var);
3661}
3662
3663template<typename Derived>
3664Sema::OwningExprResult
3665TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
3666 // Transform the type that we're allocating
3667 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3668 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
3669 if (AllocType.isNull())
3670 return SemaRef.ExprError();
3671
3672 // Transform the size of the array we're allocating (if any).
3673 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
3674 if (ArraySize.isInvalid())
3675 return SemaRef.ExprError();
3676
3677 // Transform the placement arguments (if any).
3678 bool ArgumentChanged = false;
3679 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
3680 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
3681 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
3682 if (Arg.isInvalid())
3683 return SemaRef.ExprError();
3684
3685 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
3686 PlacementArgs.push_back(Arg.take());
3687 }
3688
Douglas Gregor23a44be2009-08-20 07:17:43 +00003689 // transform the constructor arguments (if any).
Douglas Gregor9d879762009-08-11 05:31:07 +00003690 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
3691 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
3692 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
3693 if (Arg.isInvalid())
3694 return SemaRef.ExprError();
3695
3696 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
3697 ConstructorArgs.push_back(Arg.take());
3698 }
3699
3700 if (!getDerived().AlwaysRebuild() &&
3701 AllocType == E->getAllocatedType() &&
3702 ArraySize.get() == E->getArraySize() &&
3703 !ArgumentChanged)
3704 return SemaRef.Owned(E->Retain());
3705
3706 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
3707 E->isGlobalNew(),
3708 /*FIXME:*/E->getLocStart(),
3709 move_arg(PlacementArgs),
3710 /*FIXME:*/E->getLocStart(),
3711 E->isParenTypeId(),
3712 AllocType,
3713 /*FIXME:*/E->getLocStart(),
3714 /*FIXME:*/SourceRange(),
3715 move(ArraySize),
3716 /*FIXME:*/E->getLocStart(),
3717 move_arg(ConstructorArgs),
3718 E->getLocEnd());
3719}
3720
3721template<typename Derived>
3722Sema::OwningExprResult
3723TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
3724 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
3725 if (Operand.isInvalid())
3726 return SemaRef.ExprError();
3727
3728 if (!getDerived().AlwaysRebuild() &&
3729 Operand.get() == E->getArgument())
3730 return SemaRef.Owned(E->Retain());
3731
3732 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
3733 E->isGlobalDelete(),
3734 E->isArrayForm(),
3735 move(Operand));
3736}
3737
3738template<typename Derived>
3739Sema::OwningExprResult
3740TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
3741 UnresolvedFunctionNameExpr *E) {
3742 // There is no transformation we can apply to an unresolved function name.
3743 return SemaRef.Owned(E->Retain());
3744}
3745
3746template<typename Derived>
3747Sema::OwningExprResult
3748TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
3749 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3750
3751 QualType T = getDerived().TransformType(E->getQueriedType());
3752 if (T.isNull())
3753 return SemaRef.ExprError();
3754
3755 if (!getDerived().AlwaysRebuild() &&
3756 T == E->getQueriedType())
3757 return SemaRef.Owned(E->Retain());
3758
3759 // FIXME: Bad location information
3760 SourceLocation FakeLParenLoc
3761 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
3762
3763 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
3764 E->getLocStart(),
3765 /*FIXME:*/FakeLParenLoc,
3766 T,
3767 E->getLocEnd());
3768}
3769
3770template<typename Derived>
3771Sema::OwningExprResult
3772TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
3773 NestedNameSpecifier *NNS
3774 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3775 E->getQualifierRange());
3776 if (!NNS)
3777 return SemaRef.ExprError();
3778
3779 NamedDecl *ND
3780 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3781 if (!ND)
3782 return SemaRef.ExprError();
3783
3784 if (!getDerived().AlwaysRebuild() &&
3785 NNS == E->getQualifier() &&
3786 ND == E->getDecl())
3787 return SemaRef.Owned(E->Retain());
3788
3789 return getDerived().RebuildQualifiedDeclRefExpr(NNS,
3790 E->getQualifierRange(),
3791 ND,
3792 E->getLocation(),
3793 /*FIXME:*/false);
3794}
3795
3796template<typename Derived>
3797Sema::OwningExprResult
3798TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
3799 UnresolvedDeclRefExpr *E) {
3800 NestedNameSpecifier *NNS
3801 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3802 E->getQualifierRange());
3803 if (!NNS)
3804 return SemaRef.ExprError();
3805
3806 // FIXME: Transform the declaration name
3807 DeclarationName Name = E->getDeclName();
3808
3809 if (!getDerived().AlwaysRebuild() &&
3810 NNS == E->getQualifier() &&
3811 Name == E->getDeclName())
3812 return SemaRef.Owned(E->Retain());
3813
3814 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
3815 E->getQualifierRange(),
3816 Name,
3817 E->getLocation(),
3818 /*FIXME:*/false);
3819}
3820
3821template<typename Derived>
3822Sema::OwningExprResult
3823TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
3824 TemplateName Template
3825 = getDerived().TransformTemplateName(E->getTemplateName());
3826 if (Template.isNull())
3827 return SemaRef.ExprError();
3828
3829 llvm::SmallVector<TemplateArgument, 4> TransArgs;
3830 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
3831 TemplateArgument TransArg
3832 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
3833 if (TransArg.isNull())
3834 return SemaRef.ExprError();
3835
3836 TransArgs.push_back(TransArg);
3837 }
3838
3839 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
3840 // compare template arguments (yet).
3841
3842 // FIXME: It's possible that we'll find out now that the template name
3843 // actually refers to a type, in which case the caller is actually dealing
3844 // with a functional cast. Give a reasonable error message!
3845 return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
3846 E->getLAngleLoc(),
3847 TransArgs.data(),
3848 TransArgs.size(),
3849 E->getRAngleLoc());
3850}
3851
3852template<typename Derived>
3853Sema::OwningExprResult
3854TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
3855 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
3856
3857 QualType T = getDerived().TransformType(E->getType());
3858 if (T.isNull())
3859 return SemaRef.ExprError();
3860
3861 CXXConstructorDecl *Constructor
3862 = cast_or_null<CXXConstructorDecl>(
3863 getDerived().TransformDecl(E->getConstructor()));
3864 if (!Constructor)
3865 return SemaRef.ExprError();
3866
3867 bool ArgumentChanged = false;
3868 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3869 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
3870 ArgEnd = E->arg_end();
3871 Arg != ArgEnd; ++Arg) {
3872 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
3873 if (TransArg.isInvalid())
3874 return SemaRef.ExprError();
3875
3876 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
3877 Args.push_back(TransArg.takeAs<Expr>());
3878 }
3879
3880 if (!getDerived().AlwaysRebuild() &&
3881 T == E->getType() &&
3882 Constructor == E->getConstructor() &&
3883 !ArgumentChanged)
3884 return SemaRef.Owned(E->Retain());
3885
3886 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
3887 move_arg(Args));
3888}
3889
3890/// \brief Transform a C++ temporary-binding expression.
3891///
3892/// The transformation of a temporary-binding expression always attempts to
3893/// bind a new temporary variable to its subexpression, even if the
3894/// subexpression itself did not change, because the temporary variable itself
3895/// must be unique.
3896template<typename Derived>
3897Sema::OwningExprResult
3898TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
3899 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3900 if (SubExpr.isInvalid())
3901 return SemaRef.ExprError();
3902
3903 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
3904}
3905
3906/// \brief Transform a C++ expression that contains temporaries that should
3907/// be destroyed after the expression is evaluated.
3908///
3909/// The transformation of a full expression always attempts to build a new
3910/// CXXExprWithTemporaries expression, even if the
3911/// subexpression itself did not change, because it will need to capture the
3912/// the new temporary variables introduced in the subexpression.
3913template<typename Derived>
3914Sema::OwningExprResult
3915TreeTransform<Derived>::TransformCXXExprWithTemporaries(
3916 CXXExprWithTemporaries *E) {
3917 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3918 if (SubExpr.isInvalid())
3919 return SemaRef.ExprError();
3920
3921 return SemaRef.Owned(
3922 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
3923 E->shouldDestroyTemporaries()));
3924}
3925
3926template<typename Derived>
3927Sema::OwningExprResult
3928TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
3929 CXXTemporaryObjectExpr *E) {
3930 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3931 QualType T = getDerived().TransformType(E->getType());
3932 if (T.isNull())
3933 return SemaRef.ExprError();
3934
3935 CXXConstructorDecl *Constructor
3936 = cast_or_null<CXXConstructorDecl>(
3937 getDerived().TransformDecl(E->getConstructor()));
3938 if (!Constructor)
3939 return SemaRef.ExprError();
3940
3941 bool ArgumentChanged = false;
3942 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3943 Args.reserve(E->getNumArgs());
3944 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
3945 ArgEnd = E->arg_end();
3946 Arg != ArgEnd; ++Arg) {
3947 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
3948 if (TransArg.isInvalid())
3949 return SemaRef.ExprError();
3950
3951 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
3952 Args.push_back((Expr *)TransArg.release());
3953 }
3954
3955 if (!getDerived().AlwaysRebuild() &&
3956 T == E->getType() &&
3957 Constructor == E->getConstructor() &&
3958 !ArgumentChanged)
3959 return SemaRef.Owned(E->Retain());
3960
3961 // FIXME: Bogus location information
3962 SourceLocation CommaLoc;
3963 if (Args.size() > 1) {
3964 Expr *First = (Expr *)Args[0];
3965 CommaLoc
3966 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
3967 }
3968 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
3969 T,
3970 /*FIXME:*/E->getTypeBeginLoc(),
3971 move_arg(Args),
3972 &CommaLoc,
3973 E->getLocEnd());
3974}
3975
3976template<typename Derived>
3977Sema::OwningExprResult
3978TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
3979 CXXUnresolvedConstructExpr *E) {
3980 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
3981 QualType T = getDerived().TransformType(E->getTypeAsWritten());
3982 if (T.isNull())
3983 return SemaRef.ExprError();
3984
3985 bool ArgumentChanged = false;
3986 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3987 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
3988 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
3989 ArgEnd = E->arg_end();
3990 Arg != ArgEnd; ++Arg) {
3991 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
3992 if (TransArg.isInvalid())
3993 return SemaRef.ExprError();
3994
3995 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
3996 FakeCommaLocs.push_back(
3997 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
3998 Args.push_back(TransArg.takeAs<Expr>());
3999 }
4000
4001 if (!getDerived().AlwaysRebuild() &&
4002 T == E->getTypeAsWritten() &&
4003 !ArgumentChanged)
4004 return SemaRef.Owned(E->Retain());
4005
4006 // FIXME: we're faking the locations of the commas
4007 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4008 T,
4009 E->getLParenLoc(),
4010 move_arg(Args),
4011 FakeCommaLocs.data(),
4012 E->getRParenLoc());
4013}
4014
Douglas Gregore399ad42009-08-26 22:36:53 +00004015template<typename Derived>
4016Sema::OwningExprResult
4017TreeTransform<Derived>::TransformCXXQualifiedMemberExpr(
4018 CXXQualifiedMemberExpr *E) {
4019 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4020 if (Base.isInvalid())
4021 return SemaRef.ExprError();
4022
4023 NamedDecl *Member
4024 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
4025 if (!Member)
4026 return SemaRef.ExprError();
4027
4028 NestedNameSpecifier *Qualifier
4029 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4030 E->getQualifierRange());
4031 if (Qualifier == 0)
4032 return SemaRef.ExprError();
4033
4034 if (!getDerived().AlwaysRebuild() &&
4035 Base.get() == E->getBase() &&
4036 Member == E->getMemberDecl() &&
4037 Qualifier == E->getQualifier())
4038 return SemaRef.Owned(E->Retain());
4039
4040 // FIXME: Bogus source location for the operator
4041 SourceLocation FakeOperatorLoc
4042 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
4043
4044 return getDerived().RebuildCXXQualifiedMemberExpr(move(Base),
4045 FakeOperatorLoc,
4046 E->isArrow(),
4047 Qualifier,
4048 E->getQualifierRange(),
4049 E->getMemberLoc(),
4050 Member);
4051}
4052
Douglas Gregor9d879762009-08-11 05:31:07 +00004053template<typename Derived>
4054Sema::OwningExprResult
4055TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
4056 CXXUnresolvedMemberExpr *E) {
4057 // Transform the base of the expression.
4058 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4059 if (Base.isInvalid())
4060 return SemaRef.ExprError();
4061
4062 // FIXME: Transform the declaration name
4063 DeclarationName Name = E->getMember();
4064
4065 if (!getDerived().AlwaysRebuild() &&
4066 Base.get() == E->getBase() &&
4067 Name == E->getMember())
4068 return SemaRef.Owned(E->Retain());
4069
4070 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4071 E->isArrow(),
4072 E->getOperatorLoc(),
4073 E->getMember(),
4074 E->getMemberLoc());
4075}
4076
4077template<typename Derived>
4078Sema::OwningExprResult
4079TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4080 return SemaRef.Owned(E->Retain());
4081}
4082
4083template<typename Derived>
4084Sema::OwningExprResult
4085TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
4086 // FIXME: poor source location
4087 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4088 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4089 if (EncodedType.isNull())
4090 return SemaRef.ExprError();
4091
4092 if (!getDerived().AlwaysRebuild() &&
4093 EncodedType == E->getEncodedType())
4094 return SemaRef.Owned(E->Retain());
4095
4096 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4097 EncodedType,
4098 E->getRParenLoc());
4099}
4100
4101template<typename Derived>
4102Sema::OwningExprResult
4103TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
4104 // FIXME: Implement this!
4105 assert(false && "Cannot transform Objective-C expressions yet");
4106 return SemaRef.Owned(E->Retain());
4107}
4108
4109template<typename Derived>
4110Sema::OwningExprResult
4111TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4112 return SemaRef.Owned(E->Retain());
4113}
4114
4115template<typename Derived>
4116Sema::OwningExprResult
4117TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4118 ObjCProtocolDecl *Protocol
4119 = cast_or_null<ObjCProtocolDecl>(
4120 getDerived().TransformDecl(E->getProtocol()));
4121 if (!Protocol)
4122 return SemaRef.ExprError();
4123
4124 if (!getDerived().AlwaysRebuild() &&
4125 Protocol == E->getProtocol())
4126 return SemaRef.Owned(E->Retain());
4127
4128 return getDerived().RebuildObjCProtocolExpr(Protocol,
4129 E->getAtLoc(),
4130 /*FIXME:*/E->getAtLoc(),
4131 /*FIXME:*/E->getAtLoc(),
4132 E->getRParenLoc());
4133
4134}
4135
4136template<typename Derived>
4137Sema::OwningExprResult
4138TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
4139 // FIXME: Implement this!
4140 assert(false && "Cannot transform Objective-C expressions yet");
4141 return SemaRef.Owned(E->Retain());
4142}
4143
4144template<typename Derived>
4145Sema::OwningExprResult
4146TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4147 // FIXME: Implement this!
4148 assert(false && "Cannot transform Objective-C expressions yet");
4149 return SemaRef.Owned(E->Retain());
4150}
4151
4152template<typename Derived>
4153Sema::OwningExprResult
Fariborz Jahanian128cdc52009-08-20 17:02:02 +00004154TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
4155 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregor9d879762009-08-11 05:31:07 +00004156 // FIXME: Implement this!
4157 assert(false && "Cannot transform Objective-C expressions yet");
4158 return SemaRef.Owned(E->Retain());
4159}
4160
4161template<typename Derived>
4162Sema::OwningExprResult
4163TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
4164 // FIXME: Implement this!
4165 assert(false && "Cannot transform Objective-C expressions yet");
4166 return SemaRef.Owned(E->Retain());
4167}
4168
4169template<typename Derived>
4170Sema::OwningExprResult
4171TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
4172 // FIXME: Implement this!
4173 assert(false && "Cannot transform Objective-C expressions yet");
4174 return SemaRef.Owned(E->Retain());
4175}
4176
4177template<typename Derived>
4178Sema::OwningExprResult
4179TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
4180 bool ArgumentChanged = false;
4181 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4182 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4183 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4184 if (SubExpr.isInvalid())
4185 return SemaRef.ExprError();
4186
4187 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4188 SubExprs.push_back(SubExpr.takeAs<Expr>());
4189 }
4190
4191 if (!getDerived().AlwaysRebuild() &&
4192 !ArgumentChanged)
4193 return SemaRef.Owned(E->Retain());
4194
4195 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4196 move_arg(SubExprs),
4197 E->getRParenLoc());
4198}
4199
4200template<typename Derived>
4201Sema::OwningExprResult
4202TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
4203 // FIXME: Implement this!
4204 assert(false && "Cannot transform block expressions yet");
4205 return SemaRef.Owned(E->Retain());
4206}
4207
4208template<typename Derived>
4209Sema::OwningExprResult
4210TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
4211 // FIXME: Implement this!
4212 assert(false && "Cannot transform block-related expressions yet");
4213 return SemaRef.Owned(E->Retain());
4214}
4215
4216//===----------------------------------------------------------------------===//
Douglas Gregor841324a2009-08-04 16:50:30 +00004217// Type reconstruction
4218//===----------------------------------------------------------------------===//
4219
4220template<typename Derived>
4221QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
4222 return SemaRef.BuildPointerType(PointeeType, 0,
4223 getDerived().getBaseLocation(),
4224 getDerived().getBaseEntity());
4225}
4226
4227template<typename Derived>
4228QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
4229 return SemaRef.BuildBlockPointerType(PointeeType, 0,
4230 getDerived().getBaseLocation(),
4231 getDerived().getBaseEntity());
4232}
4233
4234template<typename Derived>
4235QualType
4236TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
4237 return SemaRef.BuildReferenceType(ReferentType, true, 0,
4238 getDerived().getBaseLocation(),
4239 getDerived().getBaseEntity());
4240}
4241
4242template<typename Derived>
4243QualType
4244TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
4245 return SemaRef.BuildReferenceType(ReferentType, false, 0,
4246 getDerived().getBaseLocation(),
4247 getDerived().getBaseEntity());
4248}
4249
4250template<typename Derived>
4251QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
4252 QualType ClassType) {
4253 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
4254 getDerived().getBaseLocation(),
4255 getDerived().getBaseEntity());
4256}
4257
4258template<typename Derived>
4259QualType
4260TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4261 ArrayType::ArraySizeModifier SizeMod,
4262 const llvm::APInt *Size,
4263 Expr *SizeExpr,
4264 unsigned IndexTypeQuals,
4265 SourceRange BracketsRange) {
4266 if (SizeExpr || !Size)
4267 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4268 IndexTypeQuals, BracketsRange,
4269 getDerived().getBaseEntity());
4270
4271 QualType Types[] = {
4272 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4273 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4274 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
4275 };
4276 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4277 QualType SizeType;
4278 for (unsigned I = 0; I != NumTypes; ++I)
4279 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4280 SizeType = Types[I];
4281 break;
4282 }
4283
4284 if (SizeType.isNull())
4285 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
4286
4287 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
4288 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
4289 IndexTypeQuals, BracketsRange,
4290 getDerived().getBaseEntity());
4291}
4292
4293template<typename Derived>
4294QualType
4295TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
4296 ArrayType::ArraySizeModifier SizeMod,
4297 const llvm::APInt &Size,
4298 unsigned IndexTypeQuals) {
4299 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
4300 IndexTypeQuals, SourceRange());
4301}
4302
4303template<typename Derived>
4304QualType
4305TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
4306 ArrayType::ArraySizeModifier SizeMod,
4307 const llvm::APInt &Size,
4308 Expr *SizeExpr,
4309 unsigned IndexTypeQuals,
4310 SourceRange BracketsRange) {
4311 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
4312 IndexTypeQuals, BracketsRange);
4313}
4314
4315template<typename Derived>
4316QualType
4317TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
4318 QualType ElementType,
4319 ArrayType::ArraySizeModifier SizeMod,
4320 const llvm::APInt &Size,
4321 unsigned IndexTypeQuals) {
4322 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
4323 IndexTypeQuals, SourceRange());
4324}
4325
4326template<typename Derived>
4327QualType
4328TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
4329 ArrayType::ArraySizeModifier SizeMod,
4330 unsigned IndexTypeQuals) {
4331 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
4332 IndexTypeQuals, SourceRange());
4333}
4334
4335template<typename Derived>
4336QualType
4337TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
4338 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +00004339 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004340 unsigned IndexTypeQuals,
4341 SourceRange BracketsRange) {
4342 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
4343 SizeExpr.takeAs<Expr>(),
4344 IndexTypeQuals, BracketsRange);
4345}
4346
4347template<typename Derived>
4348QualType
4349TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
4350 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregor9d879762009-08-11 05:31:07 +00004351 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004352 unsigned IndexTypeQuals,
4353 SourceRange BracketsRange) {
4354 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
4355 SizeExpr.takeAs<Expr>(),
4356 IndexTypeQuals, BracketsRange);
4357}
4358
4359template<typename Derived>
4360QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4361 unsigned NumElements) {
4362 // FIXME: semantic checking!
4363 return SemaRef.Context.getVectorType(ElementType, NumElements);
4364}
4365
4366template<typename Derived>
4367QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4368 unsigned NumElements,
4369 SourceLocation AttributeLoc) {
4370 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4371 NumElements, true);
4372 IntegerLiteral *VectorSize
4373 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
4374 AttributeLoc);
4375 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4376 AttributeLoc);
4377}
4378
4379template<typename Derived>
4380QualType
4381TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregor9d879762009-08-11 05:31:07 +00004382 ExprArg SizeExpr,
Douglas Gregor841324a2009-08-04 16:50:30 +00004383 SourceLocation AttributeLoc) {
4384 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4385}
4386
4387template<typename Derived>
4388QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
4389 QualType *ParamTypes,
4390 unsigned NumParamTypes,
4391 bool Variadic,
4392 unsigned Quals) {
4393 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
4394 Quals,
4395 getDerived().getBaseLocation(),
4396 getDerived().getBaseEntity());
4397}
4398
4399template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00004400QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor841324a2009-08-04 16:50:30 +00004401 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4402}
4403
4404template<typename Derived>
4405QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4406 return SemaRef.Context.getTypeOfType(Underlying);
4407}
4408
4409template<typename Derived>
Douglas Gregor9d879762009-08-11 05:31:07 +00004410QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor841324a2009-08-04 16:50:30 +00004411 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4412}
4413
4414template<typename Derived>
4415QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4416 TemplateName Template,
4417 const TemplateArgument *Args,
4418 unsigned NumArgs) {
4419 // FIXME: Missing source locations for the template name, <, >.
4420 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
4421 SourceLocation(), Args, NumArgs,
4422 SourceLocation());
4423}
4424
Douglas Gregor12431cb2009-08-06 05:28:30 +00004425template<typename Derived>
4426NestedNameSpecifier *
4427TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4428 SourceRange Range,
4429 IdentifierInfo &II) {
4430 CXXScopeSpec SS;
4431 // FIXME: The source location information is all wrong.
4432 SS.setRange(Range);
4433 SS.setScopeRep(Prefix);
4434 return static_cast<NestedNameSpecifier *>(
4435 SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregorc03d3302009-08-25 22:51:20 +00004436 Range.getEnd(), II,
4437 false));
Douglas Gregor12431cb2009-08-06 05:28:30 +00004438}
4439
4440template<typename Derived>
4441NestedNameSpecifier *
4442TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4443 SourceRange Range,
4444 NamespaceDecl *NS) {
4445 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
4446}
4447
4448template<typename Derived>
4449NestedNameSpecifier *
4450TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4451 SourceRange Range,
4452 bool TemplateKW,
4453 QualType T) {
4454 if (T->isDependentType() || T->isRecordType() ||
4455 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
4456 assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
4457 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
4458 T.getTypePtr());
4459 }
4460
4461 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
4462 return 0;
4463}
4464
Douglas Gregor214d0462009-08-06 06:41:21 +00004465template<typename Derived>
4466TemplateName
4467TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4468 bool TemplateKW,
4469 TemplateDecl *Template) {
4470 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
4471 Template);
4472}
4473
4474template<typename Derived>
4475TemplateName
4476TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4477 bool TemplateKW,
4478 OverloadedFunctionDecl *Ovl) {
4479 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
4480}
4481
4482template<typename Derived>
4483TemplateName
4484TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
4485 const IdentifierInfo &II) {
4486 if (Qualifier->isDependent())
4487 return SemaRef.Context.getDependentTemplateName(Qualifier, &II);
4488
4489 // Somewhat redundant with ActOnDependentTemplateName.
4490 CXXScopeSpec SS;
4491 SS.setRange(SourceRange(getDerived().getBaseLocation()));
4492 SS.setScopeRep(Qualifier);
4493 Sema::TemplateTy Template;
Douglas Gregorc03d3302009-08-25 22:51:20 +00004494 TemplateNameKind TNK = SemaRef.isTemplateName(II, 0, &SS, false, Template);
Douglas Gregor214d0462009-08-06 06:41:21 +00004495 if (TNK == TNK_Non_template) {
4496 SemaRef.Diag(getDerived().getBaseLocation(),
4497 diag::err_template_kw_refers_to_non_template)
4498 << &II;
4499 return TemplateName();
4500 } else if (TNK == TNK_Function_template) {
4501 SemaRef.Diag(getDerived().getBaseLocation(),
4502 diag::err_template_kw_refers_to_non_template)
4503 << &II;
4504 return TemplateName();
4505 }
4506
4507 return Template.getAsVal<TemplateName>();
4508}
Douglas Gregor9d879762009-08-11 05:31:07 +00004509
4510template<typename Derived>
4511Sema::OwningExprResult
4512TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
4513 SourceLocation OpLoc,
4514 ExprArg Callee,
4515 ExprArg First,
4516 ExprArg Second) {
4517 Expr *FirstExpr = (Expr *)First.get();
4518 Expr *SecondExpr = (Expr *)Second.get();
4519 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
4520
4521 // Determine whether this should be a builtin operation.
4522 if (SecondExpr == 0 || isPostIncDec) {
4523 if (!FirstExpr->getType()->isOverloadableType()) {
4524 // The argument is not of overloadable type, so try to create a
4525 // built-in unary operation.
4526 UnaryOperator::Opcode Opc
4527 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4528
4529 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
4530 }
4531 } else {
4532 if (!FirstExpr->getType()->isOverloadableType() &&
4533 !SecondExpr->getType()->isOverloadableType()) {
4534 // Neither of the arguments is an overloadable type, so try to
4535 // create a built-in binary operation.
4536 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
4537 OwningExprResult Result
4538 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
4539 if (Result.isInvalid())
4540 return SemaRef.ExprError();
4541
4542 First.release();
4543 Second.release();
4544 return move(Result);
4545 }
4546 }
4547
4548 // Compute the transformed set of functions (and function templates) to be
4549 // used during overload resolution.
4550 Sema::FunctionSet Functions;
4551
4552 DeclRefExpr *DRE = cast<DeclRefExpr>((Expr *)Callee.get());
4553 OverloadedFunctionDecl *Overloads
4554 = cast<OverloadedFunctionDecl>(DRE->getDecl());
4555
4556 // FIXME: Do we have to check
4557 // IsAcceptableNonMemberOperatorCandidate for each of these?
4558 for (OverloadedFunctionDecl::function_iterator
4559 F = Overloads->function_begin(),
4560 FEnd = Overloads->function_end();
4561 F != FEnd; ++F)
4562 Functions.insert(*F);
4563
4564 // Add any functions found via argument-dependent lookup.
4565 Expr *Args[2] = { FirstExpr, SecondExpr };
4566 unsigned NumArgs = 1 + (SecondExpr != 0);
4567 DeclarationName OpName
4568 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
4569 SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
4570
4571 // Create the overloaded operator invocation for unary operators.
4572 if (NumArgs == 1 || isPostIncDec) {
4573 UnaryOperator::Opcode Opc
4574 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
4575 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
4576 }
4577
4578 // Create the overloaded operator invocation for binary operators.
4579 BinaryOperator::Opcode Opc =
4580 BinaryOperator::getOverloadedOpcode(Op);
4581 OwningExprResult Result
4582 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
4583 if (Result.isInvalid())
4584 return SemaRef.ExprError();
4585
4586 First.release();
4587 Second.release();
4588 return move(Result);
4589}
Douglas Gregor214d0462009-08-06 06:41:21 +00004590
Douglas Gregor841324a2009-08-04 16:50:30 +00004591} // end namespace clang
4592
4593#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H