blob: c935f8118ac82c8acc074b831bc4659ab3b69a8d [file] [log] [blame]
Douglas Gregor841324a2009-08-04 16:50:30 +00001//===------- TreeTransform.h - Semantic Tree Transformation ---------------===/
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements a semantic tree transformation that takes a given
10// AST and rebuilds it, possibly transforming some nodes in the process.
11//
12//===----------------------------------------------------------------------===/
13#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_SEMA_TREETRANSFORM_H
15
16#include "Sema.h"
Douglas Gregor12431cb2009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregor72f34bb2009-08-06 22:17:10 +000018#include "clang/AST/Expr.h"
Douglas Gregor841324a2009-08-04 16:50:30 +000019#include <algorithm>
20
21namespace clang {
22
23/// \brief A semantic tree transformation that allows one to transform one
24/// abstract syntax tree into another.
25///
26/// A new tree transformation is defined by creating a new subclass \c X of
27/// \c TreeTransform<X> and then overriding certain operations to provide
28/// behavior specific to that transformation. For example, template
29/// instantiation is implemented as a tree transformation where the
30/// transformation of TemplateTypeParmType nodes involves substituting the
31/// template arguments for their corresponding template parameters; a similar
32/// transformation is performed for non-type template parameters and
33/// template template parameters.
34///
35/// This tree-transformation template uses static polymorphism to allow
36/// subclasses to customize any of its operations. Thus, a subclass can
37/// override any of the transformation or rebuild operators by providing an
38/// operation with the same signature as the default implementation. The
39/// overridding function should not be virtual.
40///
41/// Semantic tree transformations are split into two stages, either of which
42/// can be replaced by a subclass. The "transform" step transforms an AST node
43/// or the parts of an AST node using the various transformation functions,
44/// then passes the pieces on to the "rebuild" step, which constructs a new AST
45/// node of the appropriate kind from the pieces. The default transformation
46/// routines recursively transform the operands to composite AST nodes (e.g.,
47/// the pointee type of a PointerType node) and, if any of those operand nodes
48/// were changed by the transformation, invokes the rebuild operation to create
49/// a new AST node.
50///
51/// Subclasses can customize the transformation at various levels. The
Douglas Gregor2999faa2009-08-04 22:27:00 +000052/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor841324a2009-08-04 16:50:30 +000053/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
54/// TransformTemplateName(), or TransformTemplateArgument() with entirely
55/// new implementations.
56///
57/// For more fine-grained transformations, subclasses can replace any of the
58/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
59/// PointerType) to alter the transformation. As mentioned previously,
60/// replacing TransformTemplateTypeParmType() allows template instantiation
61/// to substitute template arguments for their corresponding template
62/// parameters. Additionally, subclasses can override the \c RebuildXXX
63/// functions to control how AST nodes are rebuilt when their operands change.
64/// By default, \c TreeTransform will invoke semantic analysis to rebuild
65/// AST nodes. However, certain other tree transformations (e.g, cloning) may
66/// be able to use more efficient rebuild steps.
67///
68/// There are a handful of other functions that can be overridden, allowing one
69/// to avoid traversing nodes that don't need any transformation
70/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
71/// operands have not changed (\c AlwaysRebuild()), and customize the
72/// default locations and entity names used for type-checking
73/// (\c getBaseLocation(), \c getBaseEntity()).
74///
75/// FIXME: In the future, TreeTransform will support transformation of
76/// statements and expressions as well as types.
77template<typename Derived>
78class TreeTransform {
79protected:
80 Sema &SemaRef;
81
82public:
83 /// \brief Initializes a new tree transformer.
84 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
85
86 /// \brief Retrieves a reference to the derived class.
87 Derived &getDerived() { return static_cast<Derived&>(*this); }
88
89 /// \brief Retrieves a reference to the derived class.
90 const Derived &getDerived() const {
91 return static_cast<const Derived&>(*this);
92 }
93
94 /// \brief Retrieves a reference to the semantic analysis object used for
95 /// this tree transform.
96 Sema &getSema() const { return SemaRef; }
97
98 /// \brief Whether the transformation should always rebuild AST nodes, even
99 /// if none of the children have changed.
100 ///
101 /// Subclasses may override this function to specify when the transformation
102 /// should rebuild all AST nodes.
103 bool AlwaysRebuild() { return false; }
104
105 /// \brief Returns the location of the entity being transformed, if that
106 /// information was not available elsewhere in the AST.
107 ///
108 /// By default, returns no source-location information. Subclasses can
109 /// provide an alternative implementation that provides better location
110 /// information.
111 SourceLocation getBaseLocation() { return SourceLocation(); }
112
113 /// \brief Returns the name of the entity being transformed, if that
114 /// information was not available elsewhere in the AST.
115 ///
116 /// By default, returns an empty name. Subclasses can provide an alternative
117 /// implementation with a more precise name.
118 DeclarationName getBaseEntity() { return DeclarationName(); }
119
120 /// \brief Determine whether the given type \p T has already been
121 /// transformed.
122 ///
123 /// Subclasses can provide an alternative implementation of this routine
124 /// to short-circuit evaluation when it is known that a given type will
125 /// not change. For example, template instantiation need not traverse
126 /// non-dependent types.
127 bool AlreadyTransformed(QualType T) {
128 return T.isNull();
129 }
130
131 /// \brief Transforms the given type into another type.
132 ///
133 /// By default, this routine transforms a type by delegating to the
134 /// appropriate TransformXXXType to build a new type, then applying
135 /// the qualifiers on \p T to the resulting type with AddTypeQualifiers.
136 /// Subclasses may override this function (to take over all type
137 /// transformations), some set of the TransformXXXType functions, or
138 /// the AddTypeQualifiers function to alter the transformation.
139 ///
140 /// \returns the transformed type.
141 QualType TransformType(QualType T);
142
143 /// \brief Transform the given type by adding the given set of qualifiers
144 /// and returning the result.
145 ///
146 /// FIXME: By default, this routine adds type qualifiers only to types that
147 /// can have qualifiers, and silently suppresses those qualifiers that are
148 /// not permitted (e.g., qualifiers on reference or function types). This
149 /// is the right thing for template instantiation, but probably not for
150 /// other clients.
151 QualType AddTypeQualifiers(QualType T, unsigned CVRQualifiers);
152
Douglas Gregor72f34bb2009-08-06 22:17:10 +0000153 /// \brief Transform the given statement.
Douglas Gregor841324a2009-08-04 16:50:30 +0000154 ///
155 /// FIXME: At the moment, subclasses must override this.
Douglas Gregor72f34bb2009-08-06 22:17:10 +0000156 Sema::OwningStmtResult TransformStmt(Stmt *S);
157
158 /// \brief Transform the given expression.
159 ///
160 /// By default, invokes the derived class's TransformStmt() and downcasts
161 /// the result. Subclasses may override this function to provide alternate
162 /// behavior.
Douglas Gregor841324a2009-08-04 16:50:30 +0000163 Sema::OwningExprResult TransformExpr(Expr *E);
164
165 /// \brief Transform the given declaration, which is referenced from a type
166 /// or expression.
167 ///
Douglas Gregor12431cb2009-08-06 05:28:30 +0000168 /// By default, acts as the identity function on declarations. Subclasses
169 /// may override this function to provide alternate behavior.
170 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregor841324a2009-08-04 16:50:30 +0000171
172 /// \brief Transform the given nested-name-specifier.
173 ///
Douglas Gregor12431cb2009-08-06 05:28:30 +0000174 /// By default, transforms all of the types and declarations within the
175 /// nested-name-specifier. Subclasses may override this function to provide
176 /// alternate behavior.
Douglas Gregor841324a2009-08-04 16:50:30 +0000177 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
178 SourceRange Range);
179
180 /// \brief Transform the given template name.
181 ///
Douglas Gregor214d0462009-08-06 06:41:21 +0000182 /// By default, transforms the template name by transforming the declarations
183 /// and nested-name-specifiers that occur within the template name.
184 /// Subclasses may override this function to provide alternate behavior.
185 TemplateName TransformTemplateName(TemplateName Name);
Douglas Gregor841324a2009-08-04 16:50:30 +0000186
187 /// \brief Transform the given template argument.
188 ///
Douglas Gregor2999faa2009-08-04 22:27:00 +0000189 /// By default, this operation transforms the type, expression, or
190 /// declaration stored within the template argument and constructs a
191 /// new template argument from the transformed result. Subclasses may
192 /// override this function to provide alternate behavior.
Douglas Gregor841324a2009-08-04 16:50:30 +0000193 TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
194
195#define ABSTRACT_TYPE(CLASS, PARENT)
196#define TYPE(CLASS, PARENT) \
197 QualType Transform##CLASS##Type(const CLASS##Type *T);
198#include "clang/AST/TypeNodes.def"
199
200 /// \brief Build a new pointer type given its pointee type.
201 ///
202 /// By default, performs semantic analysis when building the pointer type.
203 /// Subclasses may override this routine to provide different behavior.
204 QualType RebuildPointerType(QualType PointeeType);
205
206 /// \brief Build a new block pointer type given its pointee type.
207 ///
208 /// By default, performs semantic analysis when building the block pointer
209 /// type. Subclasses may override this routine to provide different behavior.
210 QualType RebuildBlockPointerType(QualType PointeeType);
211
212 /// \brief Build a new lvalue reference type given the type it references.
213 ///
214 /// By default, performs semantic analysis when building the lvalue reference
215 /// type. Subclasses may override this routine to provide different behavior.
216 QualType RebuildLValueReferenceType(QualType ReferentType);
217
218 /// \brief Build a new rvalue reference type given the type it references.
219 ///
220 /// By default, performs semantic analysis when building the rvalue reference
221 /// type. Subclasses may override this routine to provide different behavior.
222 QualType RebuildRValueReferenceType(QualType ReferentType);
223
224 /// \brief Build a new member pointer type given the pointee type and the
225 /// class type it refers into.
226 ///
227 /// By default, performs semantic analysis when building the member pointer
228 /// type. Subclasses may override this routine to provide different behavior.
229 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
230
231 /// \brief Build a new array type given the element type, size
232 /// modifier, size of the array (if known), size expression, and index type
233 /// qualifiers.
234 ///
235 /// By default, performs semantic analysis when building the array type.
236 /// Subclasses may override this routine to provide different behavior.
237 /// Also by default, all of the other Rebuild*Array
238 QualType RebuildArrayType(QualType ElementType,
239 ArrayType::ArraySizeModifier SizeMod,
240 const llvm::APInt *Size,
241 Expr *SizeExpr,
242 unsigned IndexTypeQuals,
243 SourceRange BracketsRange);
244
245 /// \brief Build a new constant array type given the element type, size
246 /// modifier, (known) size of the array, and index type qualifiers.
247 ///
248 /// By default, performs semantic analysis when building the array type.
249 /// Subclasses may override this routine to provide different behavior.
250 QualType RebuildConstantArrayType(QualType ElementType,
251 ArrayType::ArraySizeModifier SizeMod,
252 const llvm::APInt &Size,
253 unsigned IndexTypeQuals);
254
255 /// \brief Build a new constant array type given the element type, size
256 /// modifier, (known) size of the array, size expression, and index type
257 /// qualifiers.
258 ///
259 /// By default, performs semantic analysis when building the array type.
260 /// Subclasses may override this routine to provide different behavior.
261 QualType RebuildConstantArrayWithExprType(QualType ElementType,
262 ArrayType::ArraySizeModifier SizeMod,
263 const llvm::APInt &Size,
264 Expr *SizeExpr,
265 unsigned IndexTypeQuals,
266 SourceRange BracketsRange);
267
268 /// \brief Build a new constant array type given the element type, size
269 /// modifier, (known) size of the array, and index type qualifiers.
270 ///
271 /// By default, performs semantic analysis when building the array type.
272 /// Subclasses may override this routine to provide different behavior.
273 QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
274 ArrayType::ArraySizeModifier SizeMod,
275 const llvm::APInt &Size,
276 unsigned IndexTypeQuals);
277
278 /// \brief Build a new incomplete array type given the element type, size
279 /// modifier, and index type qualifiers.
280 ///
281 /// By default, performs semantic analysis when building the array type.
282 /// Subclasses may override this routine to provide different behavior.
283 QualType RebuildIncompleteArrayType(QualType ElementType,
284 ArrayType::ArraySizeModifier SizeMod,
285 unsigned IndexTypeQuals);
286
287 /// \brief Build a new variable-length array type given the element type,
288 /// size modifier, size expression, and index type qualifiers.
289 ///
290 /// By default, performs semantic analysis when building the array type.
291 /// Subclasses may override this routine to provide different behavior.
292 QualType RebuildVariableArrayType(QualType ElementType,
293 ArrayType::ArraySizeModifier SizeMod,
294 Sema::ExprArg SizeExpr,
295 unsigned IndexTypeQuals,
296 SourceRange BracketsRange);
297
298 /// \brief Build a new dependent-sized array type given the element type,
299 /// size modifier, size expression, and index type qualifiers.
300 ///
301 /// By default, performs semantic analysis when building the array type.
302 /// Subclasses may override this routine to provide different behavior.
303 QualType RebuildDependentSizedArrayType(QualType ElementType,
304 ArrayType::ArraySizeModifier SizeMod,
305 Sema::ExprArg SizeExpr,
306 unsigned IndexTypeQuals,
307 SourceRange BracketsRange);
308
309 /// \brief Build a new vector type given the element type and
310 /// number of elements.
311 ///
312 /// By default, performs semantic analysis when building the vector type.
313 /// Subclasses may override this routine to provide different behavior.
314 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
315
316 /// \brief Build a new extended vector type given the element type and
317 /// number of elements.
318 ///
319 /// By default, performs semantic analysis when building the vector type.
320 /// Subclasses may override this routine to provide different behavior.
321 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
322 SourceLocation AttributeLoc);
323
324 /// \brief Build a new potentially dependently-sized extended vector type
325 /// given the element type and number of elements.
326 ///
327 /// By default, performs semantic analysis when building the vector type.
328 /// Subclasses may override this routine to provide different behavior.
329 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
330 Sema::ExprArg SizeExpr,
331 SourceLocation AttributeLoc);
332
333 /// \brief Build a new function type.
334 ///
335 /// By default, performs semantic analysis when building the function type.
336 /// Subclasses may override this routine to provide different behavior.
337 QualType RebuildFunctionProtoType(QualType T,
338 QualType *ParamTypes,
339 unsigned NumParamTypes,
340 bool Variadic, unsigned Quals);
341
342 /// \brief Build a new typedef type.
343 QualType RebuildTypedefType(TypedefDecl *Typedef) {
344 return SemaRef.Context.getTypeDeclType(Typedef);
345 }
346
347 /// \brief Build a new class/struct/union type.
348 QualType RebuildRecordType(RecordDecl *Record) {
349 return SemaRef.Context.getTypeDeclType(Record);
350 }
351
352 /// \brief Build a new Enum type.
353 QualType RebuildEnumType(EnumDecl *Enum) {
354 return SemaRef.Context.getTypeDeclType(Enum);
355 }
356
357 /// \brief Build a new typeof(expr) type.
358 ///
359 /// By default, performs semantic analysis when building the typeof type.
360 /// Subclasses may override this routine to provide different behavior.
361 QualType RebuildTypeOfExprType(Sema::ExprArg Underlying);
362
363 /// \brief Build a new typeof(type) type.
364 ///
365 /// By default, builds a new TypeOfType with the given underlying type.
366 QualType RebuildTypeOfType(QualType Underlying);
367
368 /// \brief Build a new C++0x decltype type.
369 ///
370 /// By default, performs semantic analysis when building the decltype type.
371 /// Subclasses may override this routine to provide different behavior.
372 QualType RebuildDecltypeType(Sema::ExprArg Underlying);
373
374 /// \brief Build a new template specialization type.
375 ///
376 /// By default, performs semantic analysis when building the template
377 /// specialization type. Subclasses may override this routine to provide
378 /// different behavior.
379 QualType RebuildTemplateSpecializationType(TemplateName Template,
380 const TemplateArgument *Args,
381 unsigned NumArgs);
382
383 /// \brief Build a new qualified name type.
384 ///
385 /// By default, builds a new QualifiedNameType type from the
386 /// nested-name-specifier and the named type. Subclasses may override
387 /// this routine to provide different behavior.
388 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
389 return SemaRef.Context.getQualifiedNameType(NNS, Named);
390 }
391
392 /// \brief Build a new typename type that refers to a template-id.
393 ///
394 /// By default, builds a new TypenameType type from the nested-name-specifier
395 /// and the given type. Subclasses may override this routine to provide
396 /// different behavior.
397 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
398 if (NNS->isDependent())
399 return SemaRef.Context.getTypenameType(NNS,
400 cast<TemplateSpecializationType>(T));
401
402 return SemaRef.Context.getQualifiedNameType(NNS, T);
403 }
404
405 /// \brief Build a new typename type that refers to an identifier.
406 ///
407 /// By default, performs semantic analysis when building the typename type
408 /// (or qualified name type). Subclasses may override this routine to provide
409 /// different behavior.
410 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
411 const IdentifierInfo *Id) {
412 return SemaRef.CheckTypenameType(NNS, *Id,
413 SourceRange(getDerived().getBaseLocation()));
Douglas Gregor12431cb2009-08-06 05:28:30 +0000414 }
415
416 /// \brief Build a new nested-name-specifier given the prefix and an
417 /// identifier that names the next step in the nested-name-specifier.
418 ///
419 /// By default, performs semantic analysis when building the new
420 /// nested-name-specifier. Subclasses may override this routine to provide
421 /// different behavior.
422 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
423 SourceRange Range,
424 IdentifierInfo &II);
425
426 /// \brief Build a new nested-name-specifier given the prefix and the
427 /// namespace named in the next step in the nested-name-specifier.
428 ///
429 /// By default, performs semantic analysis when building the new
430 /// nested-name-specifier. Subclasses may override this routine to provide
431 /// different behavior.
432 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
433 SourceRange Range,
434 NamespaceDecl *NS);
435
436 /// \brief Build a new nested-name-specifier given the prefix and the
437 /// type named in the next step in the nested-name-specifier.
438 ///
439 /// By default, performs semantic analysis when building the new
440 /// nested-name-specifier. Subclasses may override this routine to provide
441 /// different behavior.
442 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
443 SourceRange Range,
444 bool TemplateKW,
445 QualType T);
Douglas Gregor214d0462009-08-06 06:41:21 +0000446
447 /// \brief Build a new template name given a nested name specifier, a flag
448 /// indicating whether the "template" keyword was provided, and the template
449 /// that the template name refers to.
450 ///
451 /// By default, builds the new template name directly. Subclasses may override
452 /// this routine to provide different behavior.
453 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
454 bool TemplateKW,
455 TemplateDecl *Template);
456
457 /// \brief Build a new template name given a nested name specifier, a flag
458 /// indicating whether the "template" keyword was provided, and a set of
459 /// overloaded function templates.
460 ///
461 /// By default, builds the new template name directly. Subclasses may override
462 /// this routine to provide different behavior.
463 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
464 bool TemplateKW,
465 OverloadedFunctionDecl *Ovl);
466
467 /// \brief Build a new template name given a nested name specifier and the
468 /// name that is referred to as a template.
469 ///
470 /// By default, performs semantic analysis to determine whether the name can
471 /// be resolved to a specific template, then builds the appropriate kind of
472 /// template name. Subclasses may override this routine to provide different
473 /// behavior.
474 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
475 const IdentifierInfo &II);
Douglas Gregor841324a2009-08-04 16:50:30 +0000476};
477
Douglas Gregor2999faa2009-08-04 22:27:00 +0000478template<typename Derived>
Douglas Gregor72f34bb2009-08-06 22:17:10 +0000479Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
480 Sema::OwningStmtResult Result = getDerived().TransformStmt(E);
481 if (Result.isInvalid())
482 return SemaRef.ExprError();
483
484 return SemaRef.Owned(cast_or_null<Stmt>(Result.takeAs<Stmt>()));
485}
486
487template<typename Derived>
Douglas Gregor12431cb2009-08-06 05:28:30 +0000488NestedNameSpecifier *
489TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
490 SourceRange Range) {
491 // Instantiate the prefix of this nested name specifier.
492 NestedNameSpecifier *Prefix = NNS->getPrefix();
493 if (Prefix) {
494 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
495 if (!Prefix)
496 return 0;
497 }
498
499 switch (NNS->getKind()) {
500 case NestedNameSpecifier::Identifier:
501 assert(Prefix &&
502 "Can't have an identifier nested-name-specifier with no prefix");
503 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
504 return NNS;
505
506 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
507 *NNS->getAsIdentifier());
508
509 case NestedNameSpecifier::Namespace: {
510 NamespaceDecl *NS
511 = cast_or_null<NamespaceDecl>(
512 getDerived().TransformDecl(NNS->getAsNamespace()));
513 if (!getDerived().AlwaysRebuild() &&
514 Prefix == NNS->getPrefix() &&
515 NS == NNS->getAsNamespace())
516 return NNS;
517
518 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
519 }
520
521 case NestedNameSpecifier::Global:
522 // There is no meaningful transformation that one could perform on the
523 // global scope.
524 return NNS;
525
526 case NestedNameSpecifier::TypeSpecWithTemplate:
527 case NestedNameSpecifier::TypeSpec: {
528 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor214d0462009-08-06 06:41:21 +0000529 if (T.isNull())
530 return 0;
531
Douglas Gregor12431cb2009-08-06 05:28:30 +0000532 if (!getDerived().AlwaysRebuild() &&
533 Prefix == NNS->getPrefix() &&
534 T == QualType(NNS->getAsType(), 0))
535 return NNS;
536
537 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
538 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
539 T);
540 }
541 }
542
543 // Required to silence a GCC warning
544 return 0;
545}
546
547template<typename Derived>
Douglas Gregor214d0462009-08-06 06:41:21 +0000548TemplateName
549TreeTransform<Derived>::TransformTemplateName(TemplateName Name) {
550 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
551 NestedNameSpecifier *NNS
552 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
553 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
554 if (!NNS)
555 return TemplateName();
556
557 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
558 TemplateDecl *TransTemplate
559 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
560 if (!TransTemplate)
561 return TemplateName();
562
563 if (!getDerived().AlwaysRebuild() &&
564 NNS == QTN->getQualifier() &&
565 TransTemplate == Template)
566 return Name;
567
568 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
569 TransTemplate);
570 }
571
572 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
573 assert(Ovl && "Not a template name or an overload set?");
574 OverloadedFunctionDecl *TransOvl
575 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
576 if (!TransOvl)
577 return TemplateName();
578
579 if (!getDerived().AlwaysRebuild() &&
580 NNS == QTN->getQualifier() &&
581 TransOvl == Ovl)
582 return Name;
583
584 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
585 TransOvl);
586 }
587
588 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
589 NestedNameSpecifier *NNS
590 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
591 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
592 if (!NNS)
593 return TemplateName();
594
595 if (!getDerived().AlwaysRebuild() &&
596 NNS == DTN->getQualifier())
597 return Name;
598
599 return getDerived().RebuildTemplateName(NNS, *DTN->getName());
600 }
601
602 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
603 TemplateDecl *TransTemplate
604 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
605 if (!TransTemplate)
606 return TemplateName();
607
608 if (!getDerived().AlwaysRebuild() &&
609 TransTemplate == Template)
610 return Name;
611
612 return TemplateName(TransTemplate);
613 }
614
615 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
616 assert(Ovl && "Not a template name or an overload set?");
617 OverloadedFunctionDecl *TransOvl
618 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
619 if (!TransOvl)
620 return TemplateName();
621
622 if (!getDerived().AlwaysRebuild() &&
623 TransOvl == Ovl)
624 return Name;
625
626 return TemplateName(TransOvl);
627}
628
629template<typename Derived>
Douglas Gregor2999faa2009-08-04 22:27:00 +0000630TemplateArgument
631TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
632 switch (Arg.getKind()) {
633 case TemplateArgument::Null:
634 case TemplateArgument::Integral:
635 return Arg;
636
637 case TemplateArgument::Type: {
638 QualType T = getDerived().TransformType(Arg.getAsType());
639 if (T.isNull())
640 return TemplateArgument();
641 return TemplateArgument(Arg.getLocation(), T);
642 }
643
644 case TemplateArgument::Declaration: {
645 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
646 if (!D)
647 return TemplateArgument();
648 return TemplateArgument(Arg.getLocation(), D);
649 }
650
651 case TemplateArgument::Expression: {
652 // Template argument expressions are not potentially evaluated.
653 EnterExpressionEvaluationContext Unevaluated(getSema(),
654 Action::Unevaluated);
655
656 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
657 if (E.isInvalid())
658 return TemplateArgument();
659 return TemplateArgument(E.takeAs<Expr>());
660 }
661
662 case TemplateArgument::Pack: {
663 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
664 TransformedArgs.reserve(Arg.pack_size());
665 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
666 AEnd = Arg.pack_end();
667 A != AEnd; ++A) {
668 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
669 if (TA.isNull())
670 return TA;
671
672 TransformedArgs.push_back(TA);
673 }
674 TemplateArgument Result;
675 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
676 true);
677 return Result;
678 }
679 }
680
681 // Work around bogus GCC warning
682 return TemplateArgument();
683}
684
Douglas Gregor841324a2009-08-04 16:50:30 +0000685//===----------------------------------------------------------------------===//
686// Type transformation
687//===----------------------------------------------------------------------===//
688
689template<typename Derived>
690QualType TreeTransform<Derived>::TransformType(QualType T) {
691 if (getDerived().AlreadyTransformed(T))
692 return T;
693
694 QualType Result;
695 switch (T->getTypeClass()) {
696#define ABSTRACT_TYPE(CLASS, PARENT)
697#define TYPE(CLASS, PARENT) \
698 case Type::CLASS: \
699 Result = getDerived().Transform##CLASS##Type( \
700 static_cast<CLASS##Type*>(T.getTypePtr())); \
701 break;
702#include "clang/AST/TypeNodes.def"
703 }
704
705 if (Result.isNull() || T == Result)
706 return Result;
707
708 return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
709}
710
711template<typename Derived>
712QualType
713TreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
714 if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
715 return T.getWithAdditionalQualifiers(CVRQualifiers);
716
717 return T;
718}
719
720template<typename Derived>
721QualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
722 // FIXME: Implement
723 return QualType(T, 0);
724}
725
726template<typename Derived>
727QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
728 // Nothing to do
729 return QualType(T, 0);
730}
731
732template<typename Derived>
733QualType TreeTransform<Derived>::TransformFixedWidthIntType(
734 const FixedWidthIntType *T) {
735 // FIXME: Implement
736 return QualType(T, 0);
737}
738
739template<typename Derived>
740QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
741 // FIXME: Implement
742 return QualType(T, 0);
743}
744
745template<typename Derived>
746QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
747 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
748 if (PointeeType.isNull())
749 return QualType();
750
751 if (!getDerived().AlwaysRebuild() &&
752 PointeeType == T->getPointeeType())
753 return QualType(T, 0);
754
755 return getDerived().RebuildPointerType(PointeeType);
756}
757
758template<typename Derived>
759QualType
760TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
761 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
762 if (PointeeType.isNull())
763 return QualType();
764
765 if (!getDerived().AlwaysRebuild() &&
766 PointeeType == T->getPointeeType())
767 return QualType(T, 0);
768
769 return getDerived().RebuildBlockPointerType(PointeeType);
770}
771
772template<typename Derived>
773QualType
774TreeTransform<Derived>::TransformLValueReferenceType(
775 const LValueReferenceType *T) {
776 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
777 if (PointeeType.isNull())
778 return QualType();
779
780 if (!getDerived().AlwaysRebuild() &&
781 PointeeType == T->getPointeeType())
782 return QualType(T, 0);
783
784 return getDerived().RebuildLValueReferenceType(PointeeType);
785}
786
787template<typename Derived>
788QualType
789TreeTransform<Derived>::TransformRValueReferenceType(
790 const RValueReferenceType *T) {
791 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
792 if (PointeeType.isNull())
793 return QualType();
794
795 if (!getDerived().AlwaysRebuild() &&
796 PointeeType == T->getPointeeType())
797 return QualType(T, 0);
798
799 return getDerived().RebuildRValueReferenceType(PointeeType);
800}
801
802template<typename Derived>
803QualType
804TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
805 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
806 if (PointeeType.isNull())
807 return QualType();
808
809 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
810 if (ClassType.isNull())
811 return QualType();
812
813 if (!getDerived().AlwaysRebuild() &&
814 PointeeType == T->getPointeeType() &&
815 ClassType == QualType(T->getClass(), 0))
816 return QualType(T, 0);
817
818 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
819}
820
821template<typename Derived>
822QualType
823TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
824 QualType ElementType = getDerived().TransformType(T->getElementType());
825 if (ElementType.isNull())
826 return QualType();
827
828 if (!getDerived().AlwaysRebuild() &&
829 ElementType == T->getElementType())
830 return QualType(T, 0);
831
832 return getDerived().RebuildConstantArrayType(ElementType,
833 T->getSizeModifier(),
834 T->getSize(),
835 T->getIndexTypeQualifier());
836}
837
838template<typename Derived>
839QualType
840TreeTransform<Derived>::TransformConstantArrayWithExprType(
841 const ConstantArrayWithExprType *T) {
842 QualType ElementType = getDerived().TransformType(T->getElementType());
843 if (ElementType.isNull())
844 return QualType();
845
Douglas Gregor2999faa2009-08-04 22:27:00 +0000846 // Array bounds are not potentially evaluated contexts
847 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
848
849 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
850 if (Size.isInvalid())
851 return QualType();
852
Douglas Gregor841324a2009-08-04 16:50:30 +0000853 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor2999faa2009-08-04 22:27:00 +0000854 ElementType == T->getElementType() &&
855 Size.get() == T->getSizeExpr())
Douglas Gregor841324a2009-08-04 16:50:30 +0000856 return QualType(T, 0);
857
858 return getDerived().RebuildConstantArrayWithExprType(ElementType,
859 T->getSizeModifier(),
860 T->getSize(),
Douglas Gregor2999faa2009-08-04 22:27:00 +0000861 Size.takeAs<Expr>(),
Douglas Gregor841324a2009-08-04 16:50:30 +0000862 T->getIndexTypeQualifier(),
863 T->getBracketsRange());
864}
865
866template<typename Derived>
867QualType
868TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
869 const ConstantArrayWithoutExprType *T) {
870 QualType ElementType = getDerived().TransformType(T->getElementType());
871 if (ElementType.isNull())
872 return QualType();
873
874 if (!getDerived().AlwaysRebuild() &&
875 ElementType == T->getElementType())
876 return QualType(T, 0);
877
878 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
879 T->getSizeModifier(),
880 T->getSize(),
881 T->getIndexTypeQualifier());
882}
883
884template<typename Derived>
885QualType TreeTransform<Derived>::TransformIncompleteArrayType(
886 const IncompleteArrayType *T) {
887 QualType ElementType = getDerived().TransformType(T->getElementType());
888 if (ElementType.isNull())
889 return QualType();
890
891 if (!getDerived().AlwaysRebuild() &&
892 ElementType == T->getElementType())
893 return QualType(T, 0);
894
895 return getDerived().RebuildIncompleteArrayType(ElementType,
896 T->getSizeModifier(),
897 T->getIndexTypeQualifier());
898}
899
900template<typename Derived>
901QualType TreeTransform<Derived>::TransformVariableArrayType(
902 const VariableArrayType *T) {
903 QualType ElementType = getDerived().TransformType(T->getElementType());
904 if (ElementType.isNull())
905 return QualType();
906
Douglas Gregor2999faa2009-08-04 22:27:00 +0000907 // Array bounds are not potentially evaluated contexts
908 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
909
Douglas Gregor841324a2009-08-04 16:50:30 +0000910 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
911 if (Size.isInvalid())
912 return QualType();
913
914 if (!getDerived().AlwaysRebuild() &&
915 ElementType == T->getElementType() &&
916 Size.get() == T->getSizeExpr()) {
917 Size.take();
918 return QualType(T, 0);
919 }
920
921 return getDerived().RebuildVariableArrayType(ElementType,
922 T->getSizeModifier(),
923 move(Size),
924 T->getIndexTypeQualifier(),
925 T->getBracketsRange());
926}
927
928template<typename Derived>
929QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
930 const DependentSizedArrayType *T) {
931 QualType ElementType = getDerived().TransformType(T->getElementType());
932 if (ElementType.isNull())
933 return QualType();
934
Douglas Gregor2999faa2009-08-04 22:27:00 +0000935 // Array bounds are not potentially evaluated contexts
936 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
937
Douglas Gregor841324a2009-08-04 16:50:30 +0000938 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
939 if (Size.isInvalid())
940 return QualType();
941
942 if (!getDerived().AlwaysRebuild() &&
943 ElementType == T->getElementType() &&
944 Size.get() == T->getSizeExpr()) {
945 Size.take();
946 return QualType(T, 0);
947 }
948
949 return getDerived().RebuildDependentSizedArrayType(ElementType,
950 T->getSizeModifier(),
951 move(Size),
952 T->getIndexTypeQualifier(),
953 T->getBracketsRange());
954}
955
956template<typename Derived>
957QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
958 const DependentSizedExtVectorType *T) {
959 QualType ElementType = getDerived().TransformType(T->getElementType());
960 if (ElementType.isNull())
961 return QualType();
962
Douglas Gregor2999faa2009-08-04 22:27:00 +0000963 // Vector sizes are not potentially evaluated contexts
964 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
965
Douglas Gregor841324a2009-08-04 16:50:30 +0000966 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
967 if (Size.isInvalid())
968 return QualType();
969
970 if (!getDerived().AlwaysRebuild() &&
971 ElementType == T->getElementType() &&
972 Size.get() == T->getSizeExpr()) {
973 Size.take();
974 return QualType(T, 0);
975 }
976
977 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
978 move(Size),
979 T->getAttributeLoc());
980}
981
982template<typename Derived>
983QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
984 QualType ElementType = getDerived().TransformType(T->getElementType());
985 if (ElementType.isNull())
986 return QualType();
987
988 if (!getDerived().AlwaysRebuild() &&
989 ElementType == T->getElementType())
990 return QualType(T, 0);
991
992 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
993}
994
995template<typename Derived>
996QualType
997TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
998 QualType ElementType = getDerived().TransformType(T->getElementType());
999 if (ElementType.isNull())
1000 return QualType();
1001
1002 if (!getDerived().AlwaysRebuild() &&
1003 ElementType == T->getElementType())
1004 return QualType(T, 0);
1005
1006 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
1007 /*FIXME*/SourceLocation());
1008}
1009
1010template<typename Derived>
1011QualType TreeTransform<Derived>::TransformFunctionProtoType(
1012 const FunctionProtoType *T) {
1013 QualType ResultType = getDerived().TransformType(T->getResultType());
1014 if (ResultType.isNull())
1015 return QualType();
1016
1017 llvm::SmallVector<QualType, 4> ParamTypes;
1018 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
1019 ParamEnd = T->arg_type_end();
1020 Param != ParamEnd; ++Param) {
1021 QualType P = getDerived().TransformType(*Param);
1022 if (P.isNull())
1023 return QualType();
1024
1025 ParamTypes.push_back(P);
1026 }
1027
1028 if (!getDerived().AlwaysRebuild() &&
1029 ResultType == T->getResultType() &&
1030 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
1031 return QualType(T, 0);
1032
1033 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
1034 ParamTypes.size(), T->isVariadic(),
1035 T->getTypeQuals());
1036}
1037
1038template<typename Derived>
1039QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
1040 const FunctionNoProtoType *T) {
1041 // FIXME: Implement
1042 return QualType(T, 0);
1043}
1044
1045template<typename Derived>
1046QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
1047 TypedefDecl *Typedef
1048 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
1049 if (!Typedef)
1050 return QualType();
1051
1052 if (!getDerived().AlwaysRebuild() &&
1053 Typedef == T->getDecl())
1054 return QualType(T, 0);
1055
1056 return getDerived().RebuildTypedefType(Typedef);
1057}
1058
1059template<typename Derived>
1060QualType TreeTransform<Derived>::TransformTypeOfExprType(
1061 const TypeOfExprType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00001062 // typeof expressions are not potentially evaluated contexts
1063 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
1064
Douglas Gregor841324a2009-08-04 16:50:30 +00001065 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
1066 if (E.isInvalid())
1067 return QualType();
1068
1069 if (!getDerived().AlwaysRebuild() &&
1070 E.get() == T->getUnderlyingExpr()) {
1071 E.take();
1072 return QualType(T, 0);
1073 }
1074
1075 return getDerived().RebuildTypeOfExprType(move(E));
1076}
1077
1078template<typename Derived>
1079QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
1080 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
1081 if (Underlying.isNull())
1082 return QualType();
1083
1084 if (!getDerived().AlwaysRebuild() &&
1085 Underlying == T->getUnderlyingType())
1086 return QualType(T, 0);
1087
1088 return getDerived().RebuildTypeOfType(Underlying);
1089}
1090
1091template<typename Derived>
1092QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +00001093 // decltype expressions are not potentially evaluated contexts
1094 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
1095
Douglas Gregor841324a2009-08-04 16:50:30 +00001096 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
1097 if (E.isInvalid())
1098 return QualType();
1099
1100 if (!getDerived().AlwaysRebuild() &&
1101 E.get() == T->getUnderlyingExpr()) {
1102 E.take();
1103 return QualType(T, 0);
1104 }
1105
1106 return getDerived().RebuildDecltypeType(move(E));
1107}
1108
1109template<typename Derived>
1110QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
1111 RecordDecl *Record
1112 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
1113 if (!Record)
1114 return QualType();
1115
1116 if (!getDerived().AlwaysRebuild() &&
1117 Record == T->getDecl())
1118 return QualType(T, 0);
1119
1120 return getDerived().RebuildRecordType(Record);
1121}
1122
1123template<typename Derived>
1124QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
1125 EnumDecl *Enum
1126 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
1127 if (!Enum)
1128 return QualType();
1129
1130 if (!getDerived().AlwaysRebuild() &&
1131 Enum == T->getDecl())
1132 return QualType(T, 0);
1133
1134 return getDerived().RebuildEnumType(Enum);
1135}
1136
1137template<typename Derived>
1138QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
1139 const TemplateTypeParmType *T) {
1140 // Nothing to do
1141 return QualType(T, 0);
1142}
1143
1144template<typename Derived>
1145QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
1146 const TemplateSpecializationType *T) {
1147 TemplateName Template
1148 = getDerived().TransformTemplateName(T->getTemplateName());
1149 if (Template.isNull())
1150 return QualType();
1151
1152 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
1153 NewTemplateArgs.reserve(T->getNumArgs());
1154 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
1155 Arg != ArgEnd; ++Arg) {
1156 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
1157 if (NewArg.isNull())
1158 return QualType();
1159
1160 NewTemplateArgs.push_back(NewArg);
1161 }
1162
1163 // FIXME: early abort if all of the template arguments and such are the
1164 // same.
1165
1166 // FIXME: We're missing the locations of the template name, '<', and '>'.
1167 return getDerived().RebuildTemplateSpecializationType(Template,
1168 NewTemplateArgs.data(),
1169 NewTemplateArgs.size());
1170}
1171
1172template<typename Derived>
1173QualType TreeTransform<Derived>::TransformQualifiedNameType(
1174 const QualifiedNameType *T) {
1175 NestedNameSpecifier *NNS
1176 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
1177 SourceRange());
1178 if (!NNS)
1179 return QualType();
1180
1181 QualType Named = getDerived().TransformType(T->getNamedType());
1182 if (Named.isNull())
1183 return QualType();
1184
1185 if (!getDerived().AlwaysRebuild() &&
1186 NNS == T->getQualifier() &&
1187 Named == T->getNamedType())
1188 return QualType(T, 0);
1189
1190 return getDerived().RebuildQualifiedNameType(NNS, Named);
1191}
1192
1193template<typename Derived>
1194QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
1195 NestedNameSpecifier *NNS
1196 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor3f220e82009-08-06 16:20:37 +00001197 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregor841324a2009-08-04 16:50:30 +00001198 if (!NNS)
1199 return QualType();
1200
1201 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
1202 QualType NewTemplateId
1203 = getDerived().TransformType(QualType(TemplateId, 0));
1204 if (NewTemplateId.isNull())
1205 return QualType();
1206
1207 if (!getDerived().AlwaysRebuild() &&
1208 NNS == T->getQualifier() &&
1209 NewTemplateId == QualType(TemplateId, 0))
1210 return QualType(T, 0);
1211
1212 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
1213 }
1214
1215 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
1216}
1217
1218template<typename Derived>
1219QualType TreeTransform<Derived>::TransformObjCInterfaceType(
1220 const ObjCInterfaceType *T) {
1221 // FIXME: Implement
1222 return QualType(T, 0);
1223}
1224
1225template<typename Derived>
1226QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
1227 const ObjCObjectPointerType *T) {
1228 // FIXME: Implement
1229 return QualType(T, 0);
1230}
1231
1232//===----------------------------------------------------------------------===//
1233// Type reconstruction
1234//===----------------------------------------------------------------------===//
1235
1236template<typename Derived>
1237QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
1238 return SemaRef.BuildPointerType(PointeeType, 0,
1239 getDerived().getBaseLocation(),
1240 getDerived().getBaseEntity());
1241}
1242
1243template<typename Derived>
1244QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
1245 return SemaRef.BuildBlockPointerType(PointeeType, 0,
1246 getDerived().getBaseLocation(),
1247 getDerived().getBaseEntity());
1248}
1249
1250template<typename Derived>
1251QualType
1252TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
1253 return SemaRef.BuildReferenceType(ReferentType, true, 0,
1254 getDerived().getBaseLocation(),
1255 getDerived().getBaseEntity());
1256}
1257
1258template<typename Derived>
1259QualType
1260TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
1261 return SemaRef.BuildReferenceType(ReferentType, false, 0,
1262 getDerived().getBaseLocation(),
1263 getDerived().getBaseEntity());
1264}
1265
1266template<typename Derived>
1267QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
1268 QualType ClassType) {
1269 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
1270 getDerived().getBaseLocation(),
1271 getDerived().getBaseEntity());
1272}
1273
1274template<typename Derived>
1275QualType
1276TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
1277 ArrayType::ArraySizeModifier SizeMod,
1278 const llvm::APInt *Size,
1279 Expr *SizeExpr,
1280 unsigned IndexTypeQuals,
1281 SourceRange BracketsRange) {
1282 if (SizeExpr || !Size)
1283 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
1284 IndexTypeQuals, BracketsRange,
1285 getDerived().getBaseEntity());
1286
1287 QualType Types[] = {
1288 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
1289 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
1290 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
1291 };
1292 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
1293 QualType SizeType;
1294 for (unsigned I = 0; I != NumTypes; ++I)
1295 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
1296 SizeType = Types[I];
1297 break;
1298 }
1299
1300 if (SizeType.isNull())
1301 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
1302
1303 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
1304 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
1305 IndexTypeQuals, BracketsRange,
1306 getDerived().getBaseEntity());
1307}
1308
1309template<typename Derived>
1310QualType
1311TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
1312 ArrayType::ArraySizeModifier SizeMod,
1313 const llvm::APInt &Size,
1314 unsigned IndexTypeQuals) {
1315 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1316 IndexTypeQuals, SourceRange());
1317}
1318
1319template<typename Derived>
1320QualType
1321TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
1322 ArrayType::ArraySizeModifier SizeMod,
1323 const llvm::APInt &Size,
1324 Expr *SizeExpr,
1325 unsigned IndexTypeQuals,
1326 SourceRange BracketsRange) {
1327 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
1328 IndexTypeQuals, BracketsRange);
1329}
1330
1331template<typename Derived>
1332QualType
1333TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
1334 QualType ElementType,
1335 ArrayType::ArraySizeModifier SizeMod,
1336 const llvm::APInt &Size,
1337 unsigned IndexTypeQuals) {
1338 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1339 IndexTypeQuals, SourceRange());
1340}
1341
1342template<typename Derived>
1343QualType
1344TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
1345 ArrayType::ArraySizeModifier SizeMod,
1346 unsigned IndexTypeQuals) {
1347 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
1348 IndexTypeQuals, SourceRange());
1349}
1350
1351template<typename Derived>
1352QualType
1353TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
1354 ArrayType::ArraySizeModifier SizeMod,
1355 Sema::ExprArg SizeExpr,
1356 unsigned IndexTypeQuals,
1357 SourceRange BracketsRange) {
1358 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1359 SizeExpr.takeAs<Expr>(),
1360 IndexTypeQuals, BracketsRange);
1361}
1362
1363template<typename Derived>
1364QualType
1365TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
1366 ArrayType::ArraySizeModifier SizeMod,
1367 Sema::ExprArg SizeExpr,
1368 unsigned IndexTypeQuals,
1369 SourceRange BracketsRange) {
1370 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1371 SizeExpr.takeAs<Expr>(),
1372 IndexTypeQuals, BracketsRange);
1373}
1374
1375template<typename Derived>
1376QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
1377 unsigned NumElements) {
1378 // FIXME: semantic checking!
1379 return SemaRef.Context.getVectorType(ElementType, NumElements);
1380}
1381
1382template<typename Derived>
1383QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
1384 unsigned NumElements,
1385 SourceLocation AttributeLoc) {
1386 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
1387 NumElements, true);
1388 IntegerLiteral *VectorSize
1389 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
1390 AttributeLoc);
1391 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
1392 AttributeLoc);
1393}
1394
1395template<typename Derived>
1396QualType
1397TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
1398 Sema::ExprArg SizeExpr,
1399 SourceLocation AttributeLoc) {
1400 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
1401}
1402
1403template<typename Derived>
1404QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
1405 QualType *ParamTypes,
1406 unsigned NumParamTypes,
1407 bool Variadic,
1408 unsigned Quals) {
1409 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
1410 Quals,
1411 getDerived().getBaseLocation(),
1412 getDerived().getBaseEntity());
1413}
1414
1415template<typename Derived>
1416QualType TreeTransform<Derived>::RebuildTypeOfExprType(Sema::ExprArg E) {
1417 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
1418}
1419
1420template<typename Derived>
1421QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
1422 return SemaRef.Context.getTypeOfType(Underlying);
1423}
1424
1425template<typename Derived>
1426QualType TreeTransform<Derived>::RebuildDecltypeType(Sema::ExprArg E) {
1427 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
1428}
1429
1430template<typename Derived>
1431QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
1432 TemplateName Template,
1433 const TemplateArgument *Args,
1434 unsigned NumArgs) {
1435 // FIXME: Missing source locations for the template name, <, >.
1436 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
1437 SourceLocation(), Args, NumArgs,
1438 SourceLocation());
1439}
1440
Douglas Gregor12431cb2009-08-06 05:28:30 +00001441template<typename Derived>
1442NestedNameSpecifier *
1443TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1444 SourceRange Range,
1445 IdentifierInfo &II) {
1446 CXXScopeSpec SS;
1447 // FIXME: The source location information is all wrong.
1448 SS.setRange(Range);
1449 SS.setScopeRep(Prefix);
1450 return static_cast<NestedNameSpecifier *>(
1451 SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(),
1452 Range.getEnd(), II));
1453}
1454
1455template<typename Derived>
1456NestedNameSpecifier *
1457TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1458 SourceRange Range,
1459 NamespaceDecl *NS) {
1460 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
1461}
1462
1463template<typename Derived>
1464NestedNameSpecifier *
1465TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1466 SourceRange Range,
1467 bool TemplateKW,
1468 QualType T) {
1469 if (T->isDependentType() || T->isRecordType() ||
1470 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
1471 assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
1472 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
1473 T.getTypePtr());
1474 }
1475
1476 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
1477 return 0;
1478}
1479
Douglas Gregor214d0462009-08-06 06:41:21 +00001480template<typename Derived>
1481TemplateName
1482TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
1483 bool TemplateKW,
1484 TemplateDecl *Template) {
1485 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
1486 Template);
1487}
1488
1489template<typename Derived>
1490TemplateName
1491TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
1492 bool TemplateKW,
1493 OverloadedFunctionDecl *Ovl) {
1494 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
1495}
1496
1497template<typename Derived>
1498TemplateName
1499TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
1500 const IdentifierInfo &II) {
1501 if (Qualifier->isDependent())
1502 return SemaRef.Context.getDependentTemplateName(Qualifier, &II);
1503
1504 // Somewhat redundant with ActOnDependentTemplateName.
1505 CXXScopeSpec SS;
1506 SS.setRange(SourceRange(getDerived().getBaseLocation()));
1507 SS.setScopeRep(Qualifier);
1508 Sema::TemplateTy Template;
1509 TemplateNameKind TNK = SemaRef.isTemplateName(II, 0, Template, &SS);
1510 if (TNK == TNK_Non_template) {
1511 SemaRef.Diag(getDerived().getBaseLocation(),
1512 diag::err_template_kw_refers_to_non_template)
1513 << &II;
1514 return TemplateName();
1515 } else if (TNK == TNK_Function_template) {
1516 SemaRef.Diag(getDerived().getBaseLocation(),
1517 diag::err_template_kw_refers_to_non_template)
1518 << &II;
1519 return TemplateName();
1520 }
1521
1522 return Template.getAsVal<TemplateName>();
1523}
1524
Douglas Gregor841324a2009-08-04 16:50:30 +00001525} // end namespace clang
1526
1527#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H