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