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