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