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