blob: 70ad317924efaf8be8653ebebedd5c55fb38b04e [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 Gregor841324a2009-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 Gregor2999faa2009-08-04 22:27:00 +000051/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor841324a2009-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 Gregor12431cb2009-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 Gregor841324a2009-08-04 16:50:30 +0000163
164 /// \brief Transform the given nested-name-specifier.
165 ///
Douglas Gregor12431cb2009-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 Gregor841324a2009-08-04 16:50:30 +0000169 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
170 SourceRange Range);
171
172 /// \brief Transform the given template name.
173 ///
174 /// FIXME: At the moment, subclasses must override this.
175 TemplateName TransformTemplateName(TemplateName Template);
176
177 /// \brief Transform the given template argument.
178 ///
Douglas Gregor2999faa2009-08-04 22:27:00 +0000179 /// By default, this operation transforms the type, expression, or
180 /// declaration stored within the template argument and constructs a
181 /// new template argument from the transformed result. Subclasses may
182 /// override this function to provide alternate behavior.
Douglas Gregor841324a2009-08-04 16:50:30 +0000183 TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
184
185#define ABSTRACT_TYPE(CLASS, PARENT)
186#define TYPE(CLASS, PARENT) \
187 QualType Transform##CLASS##Type(const CLASS##Type *T);
188#include "clang/AST/TypeNodes.def"
189
190 /// \brief Build a new pointer type given its pointee type.
191 ///
192 /// By default, performs semantic analysis when building the pointer type.
193 /// Subclasses may override this routine to provide different behavior.
194 QualType RebuildPointerType(QualType PointeeType);
195
196 /// \brief Build a new block pointer type given its pointee type.
197 ///
198 /// By default, performs semantic analysis when building the block pointer
199 /// type. Subclasses may override this routine to provide different behavior.
200 QualType RebuildBlockPointerType(QualType PointeeType);
201
202 /// \brief Build a new lvalue reference type given the type it references.
203 ///
204 /// By default, performs semantic analysis when building the lvalue reference
205 /// type. Subclasses may override this routine to provide different behavior.
206 QualType RebuildLValueReferenceType(QualType ReferentType);
207
208 /// \brief Build a new rvalue reference type given the type it references.
209 ///
210 /// By default, performs semantic analysis when building the rvalue reference
211 /// type. Subclasses may override this routine to provide different behavior.
212 QualType RebuildRValueReferenceType(QualType ReferentType);
213
214 /// \brief Build a new member pointer type given the pointee type and the
215 /// class type it refers into.
216 ///
217 /// By default, performs semantic analysis when building the member pointer
218 /// type. Subclasses may override this routine to provide different behavior.
219 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
220
221 /// \brief Build a new array type given the element type, size
222 /// modifier, size of the array (if known), size expression, and index type
223 /// qualifiers.
224 ///
225 /// By default, performs semantic analysis when building the array type.
226 /// Subclasses may override this routine to provide different behavior.
227 /// Also by default, all of the other Rebuild*Array
228 QualType RebuildArrayType(QualType ElementType,
229 ArrayType::ArraySizeModifier SizeMod,
230 const llvm::APInt *Size,
231 Expr *SizeExpr,
232 unsigned IndexTypeQuals,
233 SourceRange BracketsRange);
234
235 /// \brief Build a new constant array type given the element type, size
236 /// modifier, (known) size of the array, and index type qualifiers.
237 ///
238 /// By default, performs semantic analysis when building the array type.
239 /// Subclasses may override this routine to provide different behavior.
240 QualType RebuildConstantArrayType(QualType ElementType,
241 ArrayType::ArraySizeModifier SizeMod,
242 const llvm::APInt &Size,
243 unsigned IndexTypeQuals);
244
245 /// \brief Build a new constant array type given the element type, size
246 /// modifier, (known) size of the array, size expression, and index type
247 /// qualifiers.
248 ///
249 /// By default, performs semantic analysis when building the array type.
250 /// Subclasses may override this routine to provide different behavior.
251 QualType RebuildConstantArrayWithExprType(QualType ElementType,
252 ArrayType::ArraySizeModifier SizeMod,
253 const llvm::APInt &Size,
254 Expr *SizeExpr,
255 unsigned IndexTypeQuals,
256 SourceRange BracketsRange);
257
258 /// \brief Build a new constant array type given the element type, size
259 /// modifier, (known) size of the array, and index type qualifiers.
260 ///
261 /// By default, performs semantic analysis when building the array type.
262 /// Subclasses may override this routine to provide different behavior.
263 QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
264 ArrayType::ArraySizeModifier SizeMod,
265 const llvm::APInt &Size,
266 unsigned IndexTypeQuals);
267
268 /// \brief Build a new incomplete array type given the element type, size
269 /// modifier, 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 RebuildIncompleteArrayType(QualType ElementType,
274 ArrayType::ArraySizeModifier SizeMod,
275 unsigned IndexTypeQuals);
276
277 /// \brief Build a new variable-length array type given the element type,
278 /// size modifier, size expression, and index type qualifiers.
279 ///
280 /// By default, performs semantic analysis when building the array type.
281 /// Subclasses may override this routine to provide different behavior.
282 QualType RebuildVariableArrayType(QualType ElementType,
283 ArrayType::ArraySizeModifier SizeMod,
284 Sema::ExprArg SizeExpr,
285 unsigned IndexTypeQuals,
286 SourceRange BracketsRange);
287
288 /// \brief Build a new dependent-sized array type given the element type,
289 /// size modifier, size expression, and index type qualifiers.
290 ///
291 /// By default, performs semantic analysis when building the array type.
292 /// Subclasses may override this routine to provide different behavior.
293 QualType RebuildDependentSizedArrayType(QualType ElementType,
294 ArrayType::ArraySizeModifier SizeMod,
295 Sema::ExprArg SizeExpr,
296 unsigned IndexTypeQuals,
297 SourceRange BracketsRange);
298
299 /// \brief Build a new vector type given the element type and
300 /// number of elements.
301 ///
302 /// By default, performs semantic analysis when building the vector type.
303 /// Subclasses may override this routine to provide different behavior.
304 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
305
306 /// \brief Build a new extended vector type given the element type and
307 /// number of elements.
308 ///
309 /// By default, performs semantic analysis when building the vector type.
310 /// Subclasses may override this routine to provide different behavior.
311 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
312 SourceLocation AttributeLoc);
313
314 /// \brief Build a new potentially dependently-sized extended vector type
315 /// given the element type and number of elements.
316 ///
317 /// By default, performs semantic analysis when building the vector type.
318 /// Subclasses may override this routine to provide different behavior.
319 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
320 Sema::ExprArg SizeExpr,
321 SourceLocation AttributeLoc);
322
323 /// \brief Build a new function type.
324 ///
325 /// By default, performs semantic analysis when building the function type.
326 /// Subclasses may override this routine to provide different behavior.
327 QualType RebuildFunctionProtoType(QualType T,
328 QualType *ParamTypes,
329 unsigned NumParamTypes,
330 bool Variadic, unsigned Quals);
331
332 /// \brief Build a new typedef type.
333 QualType RebuildTypedefType(TypedefDecl *Typedef) {
334 return SemaRef.Context.getTypeDeclType(Typedef);
335 }
336
337 /// \brief Build a new class/struct/union type.
338 QualType RebuildRecordType(RecordDecl *Record) {
339 return SemaRef.Context.getTypeDeclType(Record);
340 }
341
342 /// \brief Build a new Enum type.
343 QualType RebuildEnumType(EnumDecl *Enum) {
344 return SemaRef.Context.getTypeDeclType(Enum);
345 }
346
347 /// \brief Build a new typeof(expr) type.
348 ///
349 /// By default, performs semantic analysis when building the typeof type.
350 /// Subclasses may override this routine to provide different behavior.
351 QualType RebuildTypeOfExprType(Sema::ExprArg Underlying);
352
353 /// \brief Build a new typeof(type) type.
354 ///
355 /// By default, builds a new TypeOfType with the given underlying type.
356 QualType RebuildTypeOfType(QualType Underlying);
357
358 /// \brief Build a new C++0x decltype type.
359 ///
360 /// By default, performs semantic analysis when building the decltype type.
361 /// Subclasses may override this routine to provide different behavior.
362 QualType RebuildDecltypeType(Sema::ExprArg Underlying);
363
364 /// \brief Build a new template specialization type.
365 ///
366 /// By default, performs semantic analysis when building the template
367 /// specialization type. Subclasses may override this routine to provide
368 /// different behavior.
369 QualType RebuildTemplateSpecializationType(TemplateName Template,
370 const TemplateArgument *Args,
371 unsigned NumArgs);
372
373 /// \brief Build a new qualified name type.
374 ///
375 /// By default, builds a new QualifiedNameType type from the
376 /// nested-name-specifier and the named type. Subclasses may override
377 /// this routine to provide different behavior.
378 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
379 return SemaRef.Context.getQualifiedNameType(NNS, Named);
380 }
381
382 /// \brief Build a new typename type that refers to a template-id.
383 ///
384 /// By default, builds a new TypenameType type from the nested-name-specifier
385 /// and the given type. Subclasses may override this routine to provide
386 /// different behavior.
387 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
388 if (NNS->isDependent())
389 return SemaRef.Context.getTypenameType(NNS,
390 cast<TemplateSpecializationType>(T));
391
392 return SemaRef.Context.getQualifiedNameType(NNS, T);
393 }
394
395 /// \brief Build a new typename type that refers to an identifier.
396 ///
397 /// By default, performs semantic analysis when building the typename type
398 /// (or qualified name type). Subclasses may override this routine to provide
399 /// different behavior.
400 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
401 const IdentifierInfo *Id) {
402 return SemaRef.CheckTypenameType(NNS, *Id,
403 SourceRange(getDerived().getBaseLocation()));
Douglas Gregor12431cb2009-08-06 05:28:30 +0000404 }
405
406 /// \brief Build a new nested-name-specifier given the prefix and an
407 /// identifier that names the next step in the nested-name-specifier.
408 ///
409 /// By default, performs semantic analysis when building the new
410 /// nested-name-specifier. Subclasses may override this routine to provide
411 /// different behavior.
412 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
413 SourceRange Range,
414 IdentifierInfo &II);
415
416 /// \brief Build a new nested-name-specifier given the prefix and the
417 /// namespace named in 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 NamespaceDecl *NS);
425
426 /// \brief Build a new nested-name-specifier given the prefix and the
427 /// type 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 bool TemplateKW,
435 QualType T);
Douglas Gregor841324a2009-08-04 16:50:30 +0000436};
437
Douglas Gregor2999faa2009-08-04 22:27:00 +0000438template<typename Derived>
Douglas Gregor12431cb2009-08-06 05:28:30 +0000439NestedNameSpecifier *
440TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
441 SourceRange Range) {
442 // Instantiate the prefix of this nested name specifier.
443 NestedNameSpecifier *Prefix = NNS->getPrefix();
444 if (Prefix) {
445 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
446 if (!Prefix)
447 return 0;
448 }
449
450 switch (NNS->getKind()) {
451 case NestedNameSpecifier::Identifier:
452 assert(Prefix &&
453 "Can't have an identifier nested-name-specifier with no prefix");
454 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
455 return NNS;
456
457 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
458 *NNS->getAsIdentifier());
459
460 case NestedNameSpecifier::Namespace: {
461 NamespaceDecl *NS
462 = cast_or_null<NamespaceDecl>(
463 getDerived().TransformDecl(NNS->getAsNamespace()));
464 if (!getDerived().AlwaysRebuild() &&
465 Prefix == NNS->getPrefix() &&
466 NS == NNS->getAsNamespace())
467 return NNS;
468
469 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
470 }
471
472 case NestedNameSpecifier::Global:
473 // There is no meaningful transformation that one could perform on the
474 // global scope.
475 return NNS;
476
477 case NestedNameSpecifier::TypeSpecWithTemplate:
478 case NestedNameSpecifier::TypeSpec: {
479 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
480 if (!getDerived().AlwaysRebuild() &&
481 Prefix == NNS->getPrefix() &&
482 T == QualType(NNS->getAsType(), 0))
483 return NNS;
484
485 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
486 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
487 T);
488 }
489 }
490
491 // Required to silence a GCC warning
492 return 0;
493}
494
495template<typename Derived>
Douglas Gregor2999faa2009-08-04 22:27:00 +0000496TemplateArgument
497TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
498 switch (Arg.getKind()) {
499 case TemplateArgument::Null:
500 case TemplateArgument::Integral:
501 return Arg;
502
503 case TemplateArgument::Type: {
504 QualType T = getDerived().TransformType(Arg.getAsType());
505 if (T.isNull())
506 return TemplateArgument();
507 return TemplateArgument(Arg.getLocation(), T);
508 }
509
510 case TemplateArgument::Declaration: {
511 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
512 if (!D)
513 return TemplateArgument();
514 return TemplateArgument(Arg.getLocation(), D);
515 }
516
517 case TemplateArgument::Expression: {
518 // Template argument expressions are not potentially evaluated.
519 EnterExpressionEvaluationContext Unevaluated(getSema(),
520 Action::Unevaluated);
521
522 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
523 if (E.isInvalid())
524 return TemplateArgument();
525 return TemplateArgument(E.takeAs<Expr>());
526 }
527
528 case TemplateArgument::Pack: {
529 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
530 TransformedArgs.reserve(Arg.pack_size());
531 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
532 AEnd = Arg.pack_end();
533 A != AEnd; ++A) {
534 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
535 if (TA.isNull())
536 return TA;
537
538 TransformedArgs.push_back(TA);
539 }
540 TemplateArgument Result;
541 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
542 true);
543 return Result;
544 }
545 }
546
547 // Work around bogus GCC warning
548 return TemplateArgument();
549}
550
Douglas Gregor841324a2009-08-04 16:50:30 +0000551//===----------------------------------------------------------------------===//
552// Type transformation
553//===----------------------------------------------------------------------===//
554
555template<typename Derived>
556QualType TreeTransform<Derived>::TransformType(QualType T) {
557 if (getDerived().AlreadyTransformed(T))
558 return T;
559
560 QualType Result;
561 switch (T->getTypeClass()) {
562#define ABSTRACT_TYPE(CLASS, PARENT)
563#define TYPE(CLASS, PARENT) \
564 case Type::CLASS: \
565 Result = getDerived().Transform##CLASS##Type( \
566 static_cast<CLASS##Type*>(T.getTypePtr())); \
567 break;
568#include "clang/AST/TypeNodes.def"
569 }
570
571 if (Result.isNull() || T == Result)
572 return Result;
573
574 return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
575}
576
577template<typename Derived>
578QualType
579TreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
580 if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
581 return T.getWithAdditionalQualifiers(CVRQualifiers);
582
583 return T;
584}
585
586template<typename Derived>
587QualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
588 // FIXME: Implement
589 return QualType(T, 0);
590}
591
592template<typename Derived>
593QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
594 // Nothing to do
595 return QualType(T, 0);
596}
597
598template<typename Derived>
599QualType TreeTransform<Derived>::TransformFixedWidthIntType(
600 const FixedWidthIntType *T) {
601 // FIXME: Implement
602 return QualType(T, 0);
603}
604
605template<typename Derived>
606QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
607 // FIXME: Implement
608 return QualType(T, 0);
609}
610
611template<typename Derived>
612QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
613 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
614 if (PointeeType.isNull())
615 return QualType();
616
617 if (!getDerived().AlwaysRebuild() &&
618 PointeeType == T->getPointeeType())
619 return QualType(T, 0);
620
621 return getDerived().RebuildPointerType(PointeeType);
622}
623
624template<typename Derived>
625QualType
626TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
627 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
628 if (PointeeType.isNull())
629 return QualType();
630
631 if (!getDerived().AlwaysRebuild() &&
632 PointeeType == T->getPointeeType())
633 return QualType(T, 0);
634
635 return getDerived().RebuildBlockPointerType(PointeeType);
636}
637
638template<typename Derived>
639QualType
640TreeTransform<Derived>::TransformLValueReferenceType(
641 const LValueReferenceType *T) {
642 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
643 if (PointeeType.isNull())
644 return QualType();
645
646 if (!getDerived().AlwaysRebuild() &&
647 PointeeType == T->getPointeeType())
648 return QualType(T, 0);
649
650 return getDerived().RebuildLValueReferenceType(PointeeType);
651}
652
653template<typename Derived>
654QualType
655TreeTransform<Derived>::TransformRValueReferenceType(
656 const RValueReferenceType *T) {
657 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
658 if (PointeeType.isNull())
659 return QualType();
660
661 if (!getDerived().AlwaysRebuild() &&
662 PointeeType == T->getPointeeType())
663 return QualType(T, 0);
664
665 return getDerived().RebuildRValueReferenceType(PointeeType);
666}
667
668template<typename Derived>
669QualType
670TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
671 QualType PointeeType = getDerived().TransformType(T->getPointeeType());
672 if (PointeeType.isNull())
673 return QualType();
674
675 QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
676 if (ClassType.isNull())
677 return QualType();
678
679 if (!getDerived().AlwaysRebuild() &&
680 PointeeType == T->getPointeeType() &&
681 ClassType == QualType(T->getClass(), 0))
682 return QualType(T, 0);
683
684 return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
685}
686
687template<typename Derived>
688QualType
689TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
690 QualType ElementType = getDerived().TransformType(T->getElementType());
691 if (ElementType.isNull())
692 return QualType();
693
694 if (!getDerived().AlwaysRebuild() &&
695 ElementType == T->getElementType())
696 return QualType(T, 0);
697
698 return getDerived().RebuildConstantArrayType(ElementType,
699 T->getSizeModifier(),
700 T->getSize(),
701 T->getIndexTypeQualifier());
702}
703
704template<typename Derived>
705QualType
706TreeTransform<Derived>::TransformConstantArrayWithExprType(
707 const ConstantArrayWithExprType *T) {
708 QualType ElementType = getDerived().TransformType(T->getElementType());
709 if (ElementType.isNull())
710 return QualType();
711
Douglas Gregor2999faa2009-08-04 22:27:00 +0000712 // Array bounds are not potentially evaluated contexts
713 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
714
715 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
716 if (Size.isInvalid())
717 return QualType();
718
Douglas Gregor841324a2009-08-04 16:50:30 +0000719 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor2999faa2009-08-04 22:27:00 +0000720 ElementType == T->getElementType() &&
721 Size.get() == T->getSizeExpr())
Douglas Gregor841324a2009-08-04 16:50:30 +0000722 return QualType(T, 0);
723
724 return getDerived().RebuildConstantArrayWithExprType(ElementType,
725 T->getSizeModifier(),
726 T->getSize(),
Douglas Gregor2999faa2009-08-04 22:27:00 +0000727 Size.takeAs<Expr>(),
Douglas Gregor841324a2009-08-04 16:50:30 +0000728 T->getIndexTypeQualifier(),
729 T->getBracketsRange());
730}
731
732template<typename Derived>
733QualType
734TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
735 const ConstantArrayWithoutExprType *T) {
736 QualType ElementType = getDerived().TransformType(T->getElementType());
737 if (ElementType.isNull())
738 return QualType();
739
740 if (!getDerived().AlwaysRebuild() &&
741 ElementType == T->getElementType())
742 return QualType(T, 0);
743
744 return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
745 T->getSizeModifier(),
746 T->getSize(),
747 T->getIndexTypeQualifier());
748}
749
750template<typename Derived>
751QualType TreeTransform<Derived>::TransformIncompleteArrayType(
752 const IncompleteArrayType *T) {
753 QualType ElementType = getDerived().TransformType(T->getElementType());
754 if (ElementType.isNull())
755 return QualType();
756
757 if (!getDerived().AlwaysRebuild() &&
758 ElementType == T->getElementType())
759 return QualType(T, 0);
760
761 return getDerived().RebuildIncompleteArrayType(ElementType,
762 T->getSizeModifier(),
763 T->getIndexTypeQualifier());
764}
765
766template<typename Derived>
767QualType TreeTransform<Derived>::TransformVariableArrayType(
768 const VariableArrayType *T) {
769 QualType ElementType = getDerived().TransformType(T->getElementType());
770 if (ElementType.isNull())
771 return QualType();
772
Douglas Gregor2999faa2009-08-04 22:27:00 +0000773 // Array bounds are not potentially evaluated contexts
774 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
775
Douglas Gregor841324a2009-08-04 16:50:30 +0000776 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
777 if (Size.isInvalid())
778 return QualType();
779
780 if (!getDerived().AlwaysRebuild() &&
781 ElementType == T->getElementType() &&
782 Size.get() == T->getSizeExpr()) {
783 Size.take();
784 return QualType(T, 0);
785 }
786
787 return getDerived().RebuildVariableArrayType(ElementType,
788 T->getSizeModifier(),
789 move(Size),
790 T->getIndexTypeQualifier(),
791 T->getBracketsRange());
792}
793
794template<typename Derived>
795QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
796 const DependentSizedArrayType *T) {
797 QualType ElementType = getDerived().TransformType(T->getElementType());
798 if (ElementType.isNull())
799 return QualType();
800
Douglas Gregor2999faa2009-08-04 22:27:00 +0000801 // Array bounds are not potentially evaluated contexts
802 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
803
Douglas Gregor841324a2009-08-04 16:50:30 +0000804 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
805 if (Size.isInvalid())
806 return QualType();
807
808 if (!getDerived().AlwaysRebuild() &&
809 ElementType == T->getElementType() &&
810 Size.get() == T->getSizeExpr()) {
811 Size.take();
812 return QualType(T, 0);
813 }
814
815 return getDerived().RebuildDependentSizedArrayType(ElementType,
816 T->getSizeModifier(),
817 move(Size),
818 T->getIndexTypeQualifier(),
819 T->getBracketsRange());
820}
821
822template<typename Derived>
823QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
824 const DependentSizedExtVectorType *T) {
825 QualType ElementType = getDerived().TransformType(T->getElementType());
826 if (ElementType.isNull())
827 return QualType();
828
Douglas Gregor2999faa2009-08-04 22:27:00 +0000829 // Vector sizes are not potentially evaluated contexts
830 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
831
Douglas Gregor841324a2009-08-04 16:50:30 +0000832 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
833 if (Size.isInvalid())
834 return QualType();
835
836 if (!getDerived().AlwaysRebuild() &&
837 ElementType == T->getElementType() &&
838 Size.get() == T->getSizeExpr()) {
839 Size.take();
840 return QualType(T, 0);
841 }
842
843 return getDerived().RebuildDependentSizedExtVectorType(ElementType,
844 move(Size),
845 T->getAttributeLoc());
846}
847
848template<typename Derived>
849QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
850 QualType ElementType = getDerived().TransformType(T->getElementType());
851 if (ElementType.isNull())
852 return QualType();
853
854 if (!getDerived().AlwaysRebuild() &&
855 ElementType == T->getElementType())
856 return QualType(T, 0);
857
858 return getDerived().RebuildVectorType(ElementType, T->getNumElements());
859}
860
861template<typename Derived>
862QualType
863TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
864 QualType ElementType = getDerived().TransformType(T->getElementType());
865 if (ElementType.isNull())
866 return QualType();
867
868 if (!getDerived().AlwaysRebuild() &&
869 ElementType == T->getElementType())
870 return QualType(T, 0);
871
872 return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
873 /*FIXME*/SourceLocation());
874}
875
876template<typename Derived>
877QualType TreeTransform<Derived>::TransformFunctionProtoType(
878 const FunctionProtoType *T) {
879 QualType ResultType = getDerived().TransformType(T->getResultType());
880 if (ResultType.isNull())
881 return QualType();
882
883 llvm::SmallVector<QualType, 4> ParamTypes;
884 for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
885 ParamEnd = T->arg_type_end();
886 Param != ParamEnd; ++Param) {
887 QualType P = getDerived().TransformType(*Param);
888 if (P.isNull())
889 return QualType();
890
891 ParamTypes.push_back(P);
892 }
893
894 if (!getDerived().AlwaysRebuild() &&
895 ResultType == T->getResultType() &&
896 std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
897 return QualType(T, 0);
898
899 return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
900 ParamTypes.size(), T->isVariadic(),
901 T->getTypeQuals());
902}
903
904template<typename Derived>
905QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
906 const FunctionNoProtoType *T) {
907 // FIXME: Implement
908 return QualType(T, 0);
909}
910
911template<typename Derived>
912QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
913 TypedefDecl *Typedef
914 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
915 if (!Typedef)
916 return QualType();
917
918 if (!getDerived().AlwaysRebuild() &&
919 Typedef == T->getDecl())
920 return QualType(T, 0);
921
922 return getDerived().RebuildTypedefType(Typedef);
923}
924
925template<typename Derived>
926QualType TreeTransform<Derived>::TransformTypeOfExprType(
927 const TypeOfExprType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +0000928 // typeof expressions are not potentially evaluated contexts
929 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
930
Douglas Gregor841324a2009-08-04 16:50:30 +0000931 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
932 if (E.isInvalid())
933 return QualType();
934
935 if (!getDerived().AlwaysRebuild() &&
936 E.get() == T->getUnderlyingExpr()) {
937 E.take();
938 return QualType(T, 0);
939 }
940
941 return getDerived().RebuildTypeOfExprType(move(E));
942}
943
944template<typename Derived>
945QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
946 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
947 if (Underlying.isNull())
948 return QualType();
949
950 if (!getDerived().AlwaysRebuild() &&
951 Underlying == T->getUnderlyingType())
952 return QualType(T, 0);
953
954 return getDerived().RebuildTypeOfType(Underlying);
955}
956
957template<typename Derived>
958QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
Douglas Gregor2999faa2009-08-04 22:27:00 +0000959 // decltype expressions are not potentially evaluated contexts
960 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
961
Douglas Gregor841324a2009-08-04 16:50:30 +0000962 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
963 if (E.isInvalid())
964 return QualType();
965
966 if (!getDerived().AlwaysRebuild() &&
967 E.get() == T->getUnderlyingExpr()) {
968 E.take();
969 return QualType(T, 0);
970 }
971
972 return getDerived().RebuildDecltypeType(move(E));
973}
974
975template<typename Derived>
976QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
977 RecordDecl *Record
978 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
979 if (!Record)
980 return QualType();
981
982 if (!getDerived().AlwaysRebuild() &&
983 Record == T->getDecl())
984 return QualType(T, 0);
985
986 return getDerived().RebuildRecordType(Record);
987}
988
989template<typename Derived>
990QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
991 EnumDecl *Enum
992 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
993 if (!Enum)
994 return QualType();
995
996 if (!getDerived().AlwaysRebuild() &&
997 Enum == T->getDecl())
998 return QualType(T, 0);
999
1000 return getDerived().RebuildEnumType(Enum);
1001}
1002
1003template<typename Derived>
1004QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
1005 const TemplateTypeParmType *T) {
1006 // Nothing to do
1007 return QualType(T, 0);
1008}
1009
1010template<typename Derived>
1011QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
1012 const TemplateSpecializationType *T) {
1013 TemplateName Template
1014 = getDerived().TransformTemplateName(T->getTemplateName());
1015 if (Template.isNull())
1016 return QualType();
1017
1018 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
1019 NewTemplateArgs.reserve(T->getNumArgs());
1020 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
1021 Arg != ArgEnd; ++Arg) {
1022 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
1023 if (NewArg.isNull())
1024 return QualType();
1025
1026 NewTemplateArgs.push_back(NewArg);
1027 }
1028
1029 // FIXME: early abort if all of the template arguments and such are the
1030 // same.
1031
1032 // FIXME: We're missing the locations of the template name, '<', and '>'.
1033 return getDerived().RebuildTemplateSpecializationType(Template,
1034 NewTemplateArgs.data(),
1035 NewTemplateArgs.size());
1036}
1037
1038template<typename Derived>
1039QualType TreeTransform<Derived>::TransformQualifiedNameType(
1040 const QualifiedNameType *T) {
1041 NestedNameSpecifier *NNS
1042 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
1043 SourceRange());
1044 if (!NNS)
1045 return QualType();
1046
1047 QualType Named = getDerived().TransformType(T->getNamedType());
1048 if (Named.isNull())
1049 return QualType();
1050
1051 if (!getDerived().AlwaysRebuild() &&
1052 NNS == T->getQualifier() &&
1053 Named == T->getNamedType())
1054 return QualType(T, 0);
1055
1056 return getDerived().RebuildQualifiedNameType(NNS, Named);
1057}
1058
1059template<typename Derived>
1060QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
1061 NestedNameSpecifier *NNS
1062 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
1063 SourceRange(getDerived().getBaseLocation()));
1064 if (!NNS)
1065 return QualType();
1066
1067 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
1068 QualType NewTemplateId
1069 = getDerived().TransformType(QualType(TemplateId, 0));
1070 if (NewTemplateId.isNull())
1071 return QualType();
1072
1073 if (!getDerived().AlwaysRebuild() &&
1074 NNS == T->getQualifier() &&
1075 NewTemplateId == QualType(TemplateId, 0))
1076 return QualType(T, 0);
1077
1078 return getDerived().RebuildTypenameType(NNS, NewTemplateId);
1079 }
1080
1081 return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
1082}
1083
1084template<typename Derived>
1085QualType TreeTransform<Derived>::TransformObjCInterfaceType(
1086 const ObjCInterfaceType *T) {
1087 // FIXME: Implement
1088 return QualType(T, 0);
1089}
1090
1091template<typename Derived>
1092QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
1093 const ObjCObjectPointerType *T) {
1094 // FIXME: Implement
1095 return QualType(T, 0);
1096}
1097
1098//===----------------------------------------------------------------------===//
1099// Type reconstruction
1100//===----------------------------------------------------------------------===//
1101
1102template<typename Derived>
1103QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
1104 return SemaRef.BuildPointerType(PointeeType, 0,
1105 getDerived().getBaseLocation(),
1106 getDerived().getBaseEntity());
1107}
1108
1109template<typename Derived>
1110QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
1111 return SemaRef.BuildBlockPointerType(PointeeType, 0,
1112 getDerived().getBaseLocation(),
1113 getDerived().getBaseEntity());
1114}
1115
1116template<typename Derived>
1117QualType
1118TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
1119 return SemaRef.BuildReferenceType(ReferentType, true, 0,
1120 getDerived().getBaseLocation(),
1121 getDerived().getBaseEntity());
1122}
1123
1124template<typename Derived>
1125QualType
1126TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
1127 return SemaRef.BuildReferenceType(ReferentType, false, 0,
1128 getDerived().getBaseLocation(),
1129 getDerived().getBaseEntity());
1130}
1131
1132template<typename Derived>
1133QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
1134 QualType ClassType) {
1135 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
1136 getDerived().getBaseLocation(),
1137 getDerived().getBaseEntity());
1138}
1139
1140template<typename Derived>
1141QualType
1142TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
1143 ArrayType::ArraySizeModifier SizeMod,
1144 const llvm::APInt *Size,
1145 Expr *SizeExpr,
1146 unsigned IndexTypeQuals,
1147 SourceRange BracketsRange) {
1148 if (SizeExpr || !Size)
1149 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
1150 IndexTypeQuals, BracketsRange,
1151 getDerived().getBaseEntity());
1152
1153 QualType Types[] = {
1154 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
1155 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
1156 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
1157 };
1158 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
1159 QualType SizeType;
1160 for (unsigned I = 0; I != NumTypes; ++I)
1161 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
1162 SizeType = Types[I];
1163 break;
1164 }
1165
1166 if (SizeType.isNull())
1167 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
1168
1169 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
1170 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
1171 IndexTypeQuals, BracketsRange,
1172 getDerived().getBaseEntity());
1173}
1174
1175template<typename Derived>
1176QualType
1177TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
1178 ArrayType::ArraySizeModifier SizeMod,
1179 const llvm::APInt &Size,
1180 unsigned IndexTypeQuals) {
1181 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1182 IndexTypeQuals, SourceRange());
1183}
1184
1185template<typename Derived>
1186QualType
1187TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
1188 ArrayType::ArraySizeModifier SizeMod,
1189 const llvm::APInt &Size,
1190 Expr *SizeExpr,
1191 unsigned IndexTypeQuals,
1192 SourceRange BracketsRange) {
1193 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
1194 IndexTypeQuals, BracketsRange);
1195}
1196
1197template<typename Derived>
1198QualType
1199TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
1200 QualType ElementType,
1201 ArrayType::ArraySizeModifier SizeMod,
1202 const llvm::APInt &Size,
1203 unsigned IndexTypeQuals) {
1204 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1205 IndexTypeQuals, SourceRange());
1206}
1207
1208template<typename Derived>
1209QualType
1210TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
1211 ArrayType::ArraySizeModifier SizeMod,
1212 unsigned IndexTypeQuals) {
1213 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
1214 IndexTypeQuals, SourceRange());
1215}
1216
1217template<typename Derived>
1218QualType
1219TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
1220 ArrayType::ArraySizeModifier SizeMod,
1221 Sema::ExprArg SizeExpr,
1222 unsigned IndexTypeQuals,
1223 SourceRange BracketsRange) {
1224 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1225 SizeExpr.takeAs<Expr>(),
1226 IndexTypeQuals, BracketsRange);
1227}
1228
1229template<typename Derived>
1230QualType
1231TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
1232 ArrayType::ArraySizeModifier SizeMod,
1233 Sema::ExprArg SizeExpr,
1234 unsigned IndexTypeQuals,
1235 SourceRange BracketsRange) {
1236 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1237 SizeExpr.takeAs<Expr>(),
1238 IndexTypeQuals, BracketsRange);
1239}
1240
1241template<typename Derived>
1242QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
1243 unsigned NumElements) {
1244 // FIXME: semantic checking!
1245 return SemaRef.Context.getVectorType(ElementType, NumElements);
1246}
1247
1248template<typename Derived>
1249QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
1250 unsigned NumElements,
1251 SourceLocation AttributeLoc) {
1252 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
1253 NumElements, true);
1254 IntegerLiteral *VectorSize
1255 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
1256 AttributeLoc);
1257 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
1258 AttributeLoc);
1259}
1260
1261template<typename Derived>
1262QualType
1263TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
1264 Sema::ExprArg SizeExpr,
1265 SourceLocation AttributeLoc) {
1266 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
1267}
1268
1269template<typename Derived>
1270QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
1271 QualType *ParamTypes,
1272 unsigned NumParamTypes,
1273 bool Variadic,
1274 unsigned Quals) {
1275 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
1276 Quals,
1277 getDerived().getBaseLocation(),
1278 getDerived().getBaseEntity());
1279}
1280
1281template<typename Derived>
1282QualType TreeTransform<Derived>::RebuildTypeOfExprType(Sema::ExprArg E) {
1283 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
1284}
1285
1286template<typename Derived>
1287QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
1288 return SemaRef.Context.getTypeOfType(Underlying);
1289}
1290
1291template<typename Derived>
1292QualType TreeTransform<Derived>::RebuildDecltypeType(Sema::ExprArg E) {
1293 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
1294}
1295
1296template<typename Derived>
1297QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
1298 TemplateName Template,
1299 const TemplateArgument *Args,
1300 unsigned NumArgs) {
1301 // FIXME: Missing source locations for the template name, <, >.
1302 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
1303 SourceLocation(), Args, NumArgs,
1304 SourceLocation());
1305}
1306
Douglas Gregor12431cb2009-08-06 05:28:30 +00001307template<typename Derived>
1308NestedNameSpecifier *
1309TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1310 SourceRange Range,
1311 IdentifierInfo &II) {
1312 CXXScopeSpec SS;
1313 // FIXME: The source location information is all wrong.
1314 SS.setRange(Range);
1315 SS.setScopeRep(Prefix);
1316 return static_cast<NestedNameSpecifier *>(
1317 SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(),
1318 Range.getEnd(), II));
1319}
1320
1321template<typename Derived>
1322NestedNameSpecifier *
1323TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1324 SourceRange Range,
1325 NamespaceDecl *NS) {
1326 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
1327}
1328
1329template<typename Derived>
1330NestedNameSpecifier *
1331TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1332 SourceRange Range,
1333 bool TemplateKW,
1334 QualType T) {
1335 if (T->isDependentType() || T->isRecordType() ||
1336 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
1337 assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
1338 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
1339 T.getTypePtr());
1340 }
1341
1342 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
1343 return 0;
1344}
1345
Douglas Gregor841324a2009-08-04 16:50:30 +00001346} // end namespace clang
1347
1348#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H