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