TreeTransform.h revision dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7
1577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===------- TreeTransform.h - Semantic Tree Transformation ---------------===/
2577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//
3577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//                     The LLVM Compiler Infrastructure
4577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//
5577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor// This file is distributed under the University of Illinois Open Source
6577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor// License. See LICENSE.TXT for details.
7577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===/
8577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//
9577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//  This file implements a semantic tree transformation that takes a given
10577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//  AST and rebuilds it, possibly transforming some nodes in the process.
11577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//
12577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===/
13577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
14577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define LLVM_CLANG_SEMA_TREETRANSFORM_H
15577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
16577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include "Sema.h"
17dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor#include "clang/Sema/SemaDiagnostic.h"
18577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include <algorithm>
19577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
20577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregornamespace clang {
21577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
22577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// \brief A semantic tree transformation that allows one to transform one
23577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// abstract syntax tree into another.
24577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
25577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// A new tree transformation is defined by creating a new subclass \c X of
26577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// \c TreeTransform<X> and then overriding certain operations to provide
27577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// behavior specific to that transformation. For example, template
28577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// instantiation is implemented as a tree transformation where the
29577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// transformation of TemplateTypeParmType nodes involves substituting the
30577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// template arguments for their corresponding template parameters; a similar
31577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// transformation is performed for non-type template parameters and
32577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// template template parameters.
33577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
34577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// This tree-transformation template uses static polymorphism to allow
35577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// subclasses to customize any of its operations. Thus, a subclass can
36577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// override any of the transformation or rebuild operators by providing an
37577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// operation with the same signature as the default implementation. The
38577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// overridding function should not be virtual.
39577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
40577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// Semantic tree transformations are split into two stages, either of which
41577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// can be replaced by a subclass. The "transform" step transforms an AST node
42577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// or the parts of an AST node using the various transformation functions,
43577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// then passes the pieces on to the "rebuild" step, which constructs a new AST
44577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// node of the appropriate kind from the pieces. The default transformation
45577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// routines recursively transform the operands to composite AST nodes (e.g.,
46577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// the pointee type of a PointerType node) and, if any of those operand nodes
47577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// were changed by the transformation, invokes the rebuild operation to create
48577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// a new AST node.
49577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
50577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// Subclasses can customize the transformation at various levels. The
51670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor/// most coarse-grained transformations involve replacing TransformType(),
52577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
53577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// TransformTemplateName(), or TransformTemplateArgument() with entirely
54577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// new implementations.
55577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
56577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// For more fine-grained transformations, subclasses can replace any of the
57577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
58577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// PointerType) to alter the transformation. As mentioned previously,
59577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// replacing TransformTemplateTypeParmType() allows template instantiation
60577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// to substitute template arguments for their corresponding template
61577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// parameters. Additionally, subclasses can override the \c RebuildXXX
62577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// functions to control how AST nodes are rebuilt when their operands change.
63577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// By default, \c TreeTransform will invoke semantic analysis to rebuild
64577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// AST nodes. However, certain other tree transformations (e.g, cloning) may
65577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// be able to use more efficient rebuild steps.
66577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
67577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// There are a handful of other functions that can be overridden, allowing one
68577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// to avoid traversing nodes that don't need any transformation
69577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
70577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// operands have not changed (\c AlwaysRebuild()), and customize the
71577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// default locations and entity names used for type-checking
72577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// (\c getBaseLocation(), \c getBaseEntity()).
73577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
74577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// FIXME: In the future, TreeTransform will support transformation of
75577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// statements and expressions as well as types.
76577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
77577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregorclass TreeTransform {
78577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregorprotected:
79577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema &SemaRef;
80577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
81577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregorpublic:
82577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Initializes a new tree transformer.
83577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
84577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
85577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Retrieves a reference to the derived class.
86577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Derived &getDerived() { return static_cast<Derived&>(*this); }
87577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
88577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Retrieves a reference to the derived class.
89577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  const Derived &getDerived() const {
90577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return static_cast<const Derived&>(*this);
91577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
92577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
93577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Retrieves a reference to the semantic analysis object used for
94577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// this tree transform.
95577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema &getSema() const { return SemaRef; }
96577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
97577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Whether the transformation should always rebuild AST nodes, even
98577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// if none of the children have changed.
99577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
100577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this function to specify when the transformation
101577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// should rebuild all AST nodes.
102577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  bool AlwaysRebuild() { return false; }
103577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
104577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Returns the location of the entity being transformed, if that
105577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// information was not available elsewhere in the AST.
106577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
107577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, returns no source-location information. Subclasses can
108577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// provide an alternative implementation that provides better location
109577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// information.
110577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  SourceLocation getBaseLocation() { return SourceLocation(); }
111577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
112577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Returns the name of the entity being transformed, if that
113577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// information was not available elsewhere in the AST.
114577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
115577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, returns an empty name. Subclasses can provide an alternative
116577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// implementation with a more precise name.
117577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  DeclarationName getBaseEntity() { return DeclarationName(); }
118577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
119577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Determine whether the given type \p T has already been
120577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// transformed.
121577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
122577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses can provide an alternative implementation of this routine
123577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// to short-circuit evaluation when it is known that a given type will
124577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// not change. For example, template instantiation need not traverse
125577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// non-dependent types.
126577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  bool AlreadyTransformed(QualType T) {
127577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return T.isNull();
128577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
129577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
130577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transforms the given type into another type.
131577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
132577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, this routine transforms a type by delegating to the
133577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// appropriate TransformXXXType to build a new type, then applying
134577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// the qualifiers on \p T to the resulting type with AddTypeQualifiers.
135577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this function (to take over all type
136577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// transformations), some set of the TransformXXXType functions, or
137577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// the AddTypeQualifiers function to alter the transformation.
138577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
139577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \returns the transformed type.
140577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType TransformType(QualType T);
141577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
142577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given type by adding the given set of qualifiers
143577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// and returning the result.
144577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
145577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// FIXME: By default, this routine adds type qualifiers only to types that
146577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// can have qualifiers, and silently suppresses those qualifiers that are
147577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// not permitted (e.g., qualifiers on reference or function types). This
148577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// is the right thing for template instantiation, but probably not for
149577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// other clients.
150577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType AddTypeQualifiers(QualType T, unsigned CVRQualifiers);
151577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
152577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given expression.
153577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
154577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// FIXME: At the moment, subclasses must override this.
155577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult TransformExpr(Expr *E);
156577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
157577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given declaration, which is referenced from a type
158577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// or expression.
159577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
160dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, acts as the identity function on declarations. Subclasses
161dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// may override this function to provide alternate behavior.
162dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  Decl *TransformDecl(Decl *D) { return D; }
163577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
164577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given nested-name-specifier.
165577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
166dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, transforms all of the types and declarations within the
167dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// nested-name-specifier. Subclasses may override this function to provide
168dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// alternate behavior.
169577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
170577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    SourceRange Range);
171577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
172577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given template name.
173577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
174577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// FIXME: At the moment, subclasses must override this.
175577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TemplateName TransformTemplateName(TemplateName Template);
176577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
177577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given template argument.
178577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
179670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// By default, this operation transforms the type, expression, or
180670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// declaration stored within the template argument and constructs a
181670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// new template argument from the transformed result. Subclasses may
182670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// override this function to provide alternate behavior.
183577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
184577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
185577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT)
186577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define TYPE(CLASS, PARENT)                                   \
187577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Transform##CLASS##Type(const CLASS##Type *T);
188577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include "clang/AST/TypeNodes.def"
189577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
190577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new pointer type given its pointee type.
191577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
192577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the pointer type.
193577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
194577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildPointerType(QualType PointeeType);
195577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
196577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new block pointer type given its pointee type.
197577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
198577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the block pointer
199577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
200577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildBlockPointerType(QualType PointeeType);
201577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
202577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new lvalue reference type given the type it references.
203577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
204577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the lvalue reference
205577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
206577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildLValueReferenceType(QualType ReferentType);
207577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
208577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new rvalue reference type given the type it references.
209577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
210577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the rvalue reference
211577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
212577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildRValueReferenceType(QualType ReferentType);
213577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
214577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new member pointer type given the pointee type and the
215577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// class type it refers into.
216577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
217577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the member pointer
218577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
219577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
220577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
221577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new array type given the element type, size
222577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, size of the array (if known), size expression, and index type
223577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// qualifiers.
224577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
225577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
226577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
227577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Also by default, all of the other Rebuild*Array
228577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildArrayType(QualType ElementType,
229577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            ArrayType::ArraySizeModifier SizeMod,
230577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            const llvm::APInt *Size,
231577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            Expr *SizeExpr,
232577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            unsigned IndexTypeQuals,
233577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            SourceRange BracketsRange);
234577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
235577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new constant array type given the element type, size
236577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, (known) size of the array, and index type qualifiers.
237577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
238577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
239577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
240577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildConstantArrayType(QualType ElementType,
241577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    ArrayType::ArraySizeModifier SizeMod,
242577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    const llvm::APInt &Size,
243577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    unsigned IndexTypeQuals);
244577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
245577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new constant array type given the element type, size
246577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, (known) size of the array, size expression, and index type
247577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// qualifiers.
248577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
249577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
250577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
251577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildConstantArrayWithExprType(QualType ElementType,
252577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            ArrayType::ArraySizeModifier SizeMod,
253577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            const llvm::APInt &Size,
254577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            Expr *SizeExpr,
255577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            unsigned IndexTypeQuals,
256577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            SourceRange BracketsRange);
257577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
258577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new constant array type given the element type, size
259577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, (known) size of the array, and index type qualifiers.
260577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
261577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
262577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
263577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
264577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               ArrayType::ArraySizeModifier SizeMod,
265577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               const llvm::APInt &Size,
266577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               unsigned IndexTypeQuals);
267577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
268577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new incomplete array type given the element type, size
269577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, and index type qualifiers.
270577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
271577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
272577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
273577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildIncompleteArrayType(QualType ElementType,
274577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      ArrayType::ArraySizeModifier SizeMod,
275577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      unsigned IndexTypeQuals);
276577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
277577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new variable-length array type given the element type,
278577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// size modifier, size expression, and index type qualifiers.
279577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
280577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
281577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
282577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildVariableArrayType(QualType ElementType,
283577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    ArrayType::ArraySizeModifier SizeMod,
284577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    Sema::ExprArg SizeExpr,
285577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    unsigned IndexTypeQuals,
286577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    SourceRange BracketsRange);
287577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
288577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new dependent-sized array type given the element type,
289577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// size modifier, size expression, and index type qualifiers.
290577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
291577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
292577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
293577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildDependentSizedArrayType(QualType ElementType,
294577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
295577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          Sema::ExprArg SizeExpr,
296577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          unsigned IndexTypeQuals,
297577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          SourceRange BracketsRange);
298577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
299577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new vector type given the element type and
300577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// number of elements.
301577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
302577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the vector type.
303577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
304577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
305577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
306577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new extended vector type given the element type and
307577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// number of elements.
308577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
309577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the vector type.
310577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
311577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
312577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                SourceLocation AttributeLoc);
313577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
314577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new potentially dependently-sized extended vector type
315577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// given the element type and number of elements.
316577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
317577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the vector type.
318577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
319577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildDependentSizedExtVectorType(QualType ElementType,
320577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              Sema::ExprArg SizeExpr,
321577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              SourceLocation AttributeLoc);
322577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
323577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new function type.
324577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
325577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the function type.
326577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
327577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildFunctionProtoType(QualType T,
328577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    QualType *ParamTypes,
329577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    unsigned NumParamTypes,
330577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    bool Variadic, unsigned Quals);
331577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
332577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typedef type.
333577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypedefType(TypedefDecl *Typedef) {
334577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getTypeDeclType(Typedef);
335577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
336577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
337577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new class/struct/union type.
338577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildRecordType(RecordDecl *Record) {
339577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getTypeDeclType(Record);
340577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
341577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
342577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new Enum type.
343577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildEnumType(EnumDecl *Enum) {
344577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getTypeDeclType(Enum);
345577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
346577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
347577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typeof(expr) type.
348577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
349577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the typeof type.
350577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
351577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypeOfExprType(Sema::ExprArg Underlying);
352577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
353577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typeof(type) type.
354577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
355577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, builds a new TypeOfType with the given underlying type.
356577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypeOfType(QualType Underlying);
357577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
358577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new C++0x decltype type.
359577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
360577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the decltype type.
361577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
362577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildDecltypeType(Sema::ExprArg Underlying);
363577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
364577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new template specialization type.
365577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
366577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the template
367577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// specialization type. Subclasses may override this routine to provide
368577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// different behavior.
369577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTemplateSpecializationType(TemplateName Template,
370577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                             const TemplateArgument *Args,
371577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                             unsigned NumArgs);
372577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
373577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new qualified name type.
374577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
375577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, builds a new QualifiedNameType type from the
376577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// nested-name-specifier and the named type. Subclasses may override
377577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// this routine to provide different behavior.
378577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
379577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getQualifiedNameType(NNS, Named);
380577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
381577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
382577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typename type that refers to a template-id.
383577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
384577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, builds a new TypenameType type from the nested-name-specifier
385577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// and the given type. Subclasses may override this routine to provide
386577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// different behavior.
387577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
388577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (NNS->isDependent())
389577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return SemaRef.Context.getTypenameType(NNS,
390577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          cast<TemplateSpecializationType>(T));
391577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
392577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getQualifiedNameType(NNS, T);
393577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
394577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
395577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typename type that refers to an identifier.
396577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
397577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the typename type
398577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// (or qualified name type). Subclasses may override this routine to provide
399577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// different behavior.
400577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypenameType(NestedNameSpecifier *NNS,
401577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                               const IdentifierInfo *Id) {
402577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.CheckTypenameType(NNS, *Id,
403577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  SourceRange(getDerived().getBaseLocation()));
404dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
405dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
406dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// \brief Build a new nested-name-specifier given the prefix and an
407dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// identifier that names the next step in the nested-name-specifier.
408dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  ///
409dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, performs semantic analysis when building the new
410dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// nested-name-specifier. Subclasses may override this routine to provide
411dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// different behavior.
412dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
413dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  SourceRange Range,
414dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  IdentifierInfo &II);
415dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
416dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// \brief Build a new nested-name-specifier given the prefix and the
417dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// namespace named in the next step in the nested-name-specifier.
418dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  ///
419dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, performs semantic analysis when building the new
420dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// nested-name-specifier. Subclasses may override this routine to provide
421dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// different behavior.
422dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
423dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  SourceRange Range,
424dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  NamespaceDecl *NS);
425dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
426dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// \brief Build a new nested-name-specifier given the prefix and the
427dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// type named in the next step in the nested-name-specifier.
428dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  ///
429dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, performs semantic analysis when building the new
430dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// nested-name-specifier. Subclasses may override this routine to provide
431dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// different behavior.
432dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
433dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  SourceRange Range,
434dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  bool TemplateKW,
435dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  QualType T);
436577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor};
437577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
438670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregortemplate<typename Derived>
439dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
440dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
441dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                     SourceRange Range) {
442dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  // Instantiate the prefix of this nested name specifier.
443dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  NestedNameSpecifier *Prefix = NNS->getPrefix();
444dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  if (Prefix) {
445dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
446dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!Prefix)
447dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return 0;
448dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
449dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
450dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  switch (NNS->getKind()) {
451dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::Identifier:
452dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    assert(Prefix &&
453dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor           "Can't have an identifier nested-name-specifier with no prefix");
454dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
455dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return NNS;
456dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
457dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
458dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   *NNS->getAsIdentifier());
459dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
460dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::Namespace: {
461dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    NamespaceDecl *NS
462dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      = cast_or_null<NamespaceDecl>(
463dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                            getDerived().TransformDecl(NNS->getAsNamespace()));
464dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!getDerived().AlwaysRebuild() &&
465dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        Prefix == NNS->getPrefix() &&
466dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        NS == NNS->getAsNamespace())
467dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return NNS;
468dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
469dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
470dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
471dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
472dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::Global:
473dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    // There is no meaningful transformation that one could perform on the
474dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    // global scope.
475dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return NNS;
476dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
477dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::TypeSpecWithTemplate:
478dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::TypeSpec: {
479dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
480dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!getDerived().AlwaysRebuild() &&
481dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        Prefix == NNS->getPrefix() &&
482dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        T == QualType(NNS->getAsType(), 0))
483dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return NNS;
484dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
485dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
486dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                  NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
487dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   T);
488dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
489dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
490dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
491dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  // Required to silence a GCC warning
492dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return 0;
493dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
494dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
495dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
496670444ed30cc8ff66eb4847d921d9af0291a7111Douglas GregorTemplateArgument
497670444ed30cc8ff66eb4847d921d9af0291a7111Douglas GregorTreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
498670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  switch (Arg.getKind()) {
499670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Null:
500670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Integral:
501670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return Arg;
502670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
503670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Type: {
504670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    QualType T = getDerived().TransformType(Arg.getAsType());
505670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    if (T.isNull())
506670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      return TemplateArgument();
507670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return TemplateArgument(Arg.getLocation(), T);
508670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
509670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
510670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Declaration: {
511670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
512670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    if (!D)
513670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      return TemplateArgument();
514670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return TemplateArgument(Arg.getLocation(), D);
515670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
516670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
517670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Expression: {
518670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    // Template argument expressions are not potentially evaluated.
519670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    EnterExpressionEvaluationContext Unevaluated(getSema(),
520670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                                                 Action::Unevaluated);
521670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
522670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
523670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    if (E.isInvalid())
524670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      return TemplateArgument();
525670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return TemplateArgument(E.takeAs<Expr>());
526670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
527670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
528670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Pack: {
529670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
530670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    TransformedArgs.reserve(Arg.pack_size());
531670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
532670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                                      AEnd = Arg.pack_end();
533670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor         A != AEnd; ++A) {
534670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
535670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      if (TA.isNull())
536670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor        return TA;
537670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
538670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      TransformedArgs.push_back(TA);
539670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    }
540670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    TemplateArgument Result;
541670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
542670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                           true);
543670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return Result;
544670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
545670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
546670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
547670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Work around bogus GCC warning
548670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  return TemplateArgument();
549670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor}
550670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
551577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
552577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor// Type transformation
553577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
554577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
555577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
556577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformType(QualType T) {
557577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (getDerived().AlreadyTransformed(T))
558577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return T;
559577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
560577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Result;
561577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  switch (T->getTypeClass()) {
562577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT)
563577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define TYPE(CLASS, PARENT)                                                  \
564577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    case Type::CLASS:                                                        \
565577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Result = getDerived().Transform##CLASS##Type(                          \
566577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  static_cast<CLASS##Type*>(T.getTypePtr())); \
567577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      break;
568577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include "clang/AST/TypeNodes.def"
569577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
570577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
571577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Result.isNull() || T == Result)
572577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return Result;
573577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
574577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
575577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
576577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
577577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
578577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
579577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
580577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
581577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return T.getWithAdditionalQualifiers(CVRQualifiers);
582577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
583577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return T;
584577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
585577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
586577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
587577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
588577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
589577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
590577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
591577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
592577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
593577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
594577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // Nothing to do
595577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
596577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
597577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
598577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
599577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformFixedWidthIntType(
600577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const FixedWidthIntType *T) {
601577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
602577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
603577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
604577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
605577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
606577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
607577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
608577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
609577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
610577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
611577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
612577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
613577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
614577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
615577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
616577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
617577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
618577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
619577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
620577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
621577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildPointerType(PointeeType);
622577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
623577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
624577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
625577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
626577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
627577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
628577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
629577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
630577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
631577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
632577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
633577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
634577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
635577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildBlockPointerType(PointeeType);
636577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
637577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
638577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
639577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
640577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformLValueReferenceType(
641577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               const LValueReferenceType *T) {
642577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
643577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
644577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
645577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
646577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
647577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
648577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
649577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
650577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildLValueReferenceType(PointeeType);
651577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
652577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
653577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
654577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
655577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformRValueReferenceType(
656577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              const RValueReferenceType *T) {
657577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
658577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
659577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
660577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
661577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
662577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
663577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
664577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
665577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildRValueReferenceType(PointeeType);
666577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
667577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
668577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
669577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
670577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
671577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
672577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
673577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
674577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
675577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
676577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ClassType.isNull())
677577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
678577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
679577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
680577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType() &&
681577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ClassType == QualType(T->getClass(), 0))
682577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
683577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
684577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
685577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
686577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
687577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
688577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
689577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
690577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
691577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
692577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
693577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
694577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
695577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
696577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
697577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
698577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildConstantArrayType(ElementType,
699577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getSizeModifier(),
700577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getSize(),
701577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getIndexTypeQualifier());
702577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
703577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
704577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
705577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
706577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformConstantArrayWithExprType(
707577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      const ConstantArrayWithExprType *T) {
708577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
709577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
710577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
711577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
712670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Array bounds are not potentially evaluated contexts
713670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
714670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
715670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
716670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  if (Size.isInvalid())
717670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return QualType();
718670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
719577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
720670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      ElementType == T->getElementType() &&
721670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      Size.get() == T->getSizeExpr())
722577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
723577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
724577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildConstantArrayWithExprType(ElementType,
725577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSizeModifier(),
726577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSize(),
727670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                                                       Size.takeAs<Expr>(),
728577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                   T->getIndexTypeQualifier(),
729577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getBracketsRange());
730577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
731577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
732577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
733577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
734577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformConstantArrayWithoutExprType(
735577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      const ConstantArrayWithoutExprType *T) {
736577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
737577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
738577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
739577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
740577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
741577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
742577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
743577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
744577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
745577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSizeModifier(),
746577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSize(),
747577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    T->getIndexTypeQualifier());
748577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
749577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
750577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
751577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformIncompleteArrayType(
752577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              const IncompleteArrayType *T) {
753577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
754577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
755577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
756577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
757577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
758577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
759577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
760577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
761577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildIncompleteArrayType(ElementType,
762577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 T->getSizeModifier(),
763577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 T->getIndexTypeQualifier());
764577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
765577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
766577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
767577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformVariableArrayType(
768577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const VariableArrayType *T) {
769577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
770577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
771577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
772577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
773670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Array bounds are not potentially evaluated contexts
774670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
775670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
776577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
777577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Size.isInvalid())
778577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
779577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
780577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
781577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType() &&
782577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Size.get() == T->getSizeExpr()) {
783577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    Size.take();
784577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
785577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
786577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
787577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildVariableArrayType(ElementType,
788577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getSizeModifier(),
789577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               move(Size),
790577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getIndexTypeQualifier(),
791577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getBracketsRange());
792577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
793577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
794577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
795577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformDependentSizedArrayType(
796577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          const DependentSizedArrayType *T) {
797577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
798577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
799577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
800577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
801670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Array bounds are not potentially evaluated contexts
802670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
803670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
804577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
805577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Size.isInvalid())
806577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
807577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
808577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
809577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType() &&
810577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Size.get() == T->getSizeExpr()) {
811577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    Size.take();
812577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
813577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
814577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
815577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildDependentSizedArrayType(ElementType,
816577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     T->getSizeModifier(),
817577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     move(Size),
818577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     T->getIndexTypeQualifier(),
819577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     T->getBracketsRange());
820577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
821577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
822577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
823577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
824577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      const DependentSizedExtVectorType *T) {
825577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
826577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
827577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
828577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
829670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Vector sizes are not potentially evaluated contexts
830670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
831670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
832577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
833577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Size.isInvalid())
834577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
835577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
836577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
837577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType() &&
838577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Size.get() == T->getSizeExpr()) {
839577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    Size.take();
840577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
841577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
842577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
843577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildDependentSizedExtVectorType(ElementType,
844577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         move(Size),
845577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         T->getAttributeLoc());
846577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
847577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
848577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
849577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
850577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
851577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
852577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
853577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
854577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
855577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
856577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
857577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
858577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildVectorType(ElementType, T->getNumElements());
859577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
860577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
861577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
862577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
863577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
864577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
865577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
866577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
867577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
868577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
869577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
870577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
871577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
872577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
873577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                           /*FIXME*/SourceLocation());
874577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
875577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
876577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
877577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformFunctionProtoType(
878577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const FunctionProtoType *T) {
879577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ResultType = getDerived().TransformType(T->getResultType());
880577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ResultType.isNull())
881577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
882577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
883577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  llvm::SmallVector<QualType, 4> ParamTypes;
884577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
885577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         ParamEnd = T->arg_type_end();
886577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor       Param != ParamEnd; ++Param) {
887577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    QualType P = getDerived().TransformType(*Param);
888577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (P.isNull())
889577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType();
890577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
891577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    ParamTypes.push_back(P);
892577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
893577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
894577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
895577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ResultType == T->getResultType() &&
896577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
897577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
898577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
899577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
900577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               ParamTypes.size(), T->isVariadic(),
901577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getTypeQuals());
902577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
903577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
904577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
905577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformFunctionNoProtoType(
906577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                const FunctionNoProtoType *T) {
907577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
908577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
909577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
910577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
911577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
912577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
913577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TypedefDecl *Typedef
914577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
915577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!Typedef)
916577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
917577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
918577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
919577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Typedef == T->getDecl())
920577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
921577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
922577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypedefType(Typedef);
923577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
924577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
925577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
926577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypeOfExprType(
927577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    const TypeOfExprType *T) {
928670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // typeof expressions are not potentially evaluated contexts
929670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
930670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
931577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
932577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (E.isInvalid())
933577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
934577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
935577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
936577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      E.get() == T->getUnderlyingExpr()) {
937577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    E.take();
938577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
939577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
940577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
941577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypeOfExprType(move(E));
942577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
943577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
944577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
945577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
946577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
947577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Underlying.isNull())
948577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
949577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
950577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
951577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Underlying == T->getUnderlyingType())
952577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
953577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
954577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypeOfType(Underlying);
955577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
956577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
957577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
958577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
959670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // decltype expressions are not potentially evaluated contexts
960670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
961670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
962577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
963577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (E.isInvalid())
964577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
965577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
966577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
967577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      E.get() == T->getUnderlyingExpr()) {
968577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    E.take();
969577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
970577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
971577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
972577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildDecltypeType(move(E));
973577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
974577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
975577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
976577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
977577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  RecordDecl *Record
978577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
979577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!Record)
980577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
981577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
982577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
983577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Record == T->getDecl())
984577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
985577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
986577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildRecordType(Record);
987577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
988577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
989577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
990577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
991577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  EnumDecl *Enum
992577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
993577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!Enum)
994577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
995577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
996577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
997577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Enum == T->getDecl())
998577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
999577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1000577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildEnumType(Enum);
1001577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1002577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1003577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1004577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTemplateTypeParmType(
1005577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              const TemplateTypeParmType *T) {
1006577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // Nothing to do
1007577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1008577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1009577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1010577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1011577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTemplateSpecializationType(
1012577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        const TemplateSpecializationType *T) {
1013577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TemplateName Template
1014577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = getDerived().TransformTemplateName(T->getTemplateName());
1015577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Template.isNull())
1016577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1017577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1018577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
1019577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NewTemplateArgs.reserve(T->getNumArgs());
1020577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
1021577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor       Arg != ArgEnd; ++Arg) {
1022577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
1023577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (NewArg.isNull())
1024577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType();
1025577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1026577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    NewTemplateArgs.push_back(NewArg);
1027577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1028577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1029577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: early abort if all of the template arguments and such are the
1030577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // same.
1031577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1032577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: We're missing the locations of the template name, '<', and '>'.
1033577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTemplateSpecializationType(Template,
1034577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        NewTemplateArgs.data(),
1035577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        NewTemplateArgs.size());
1036577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1037577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1038577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1039577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformQualifiedNameType(
1040577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const QualifiedNameType *T) {
1041577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NestedNameSpecifier *NNS
1042577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
1043577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                SourceRange());
1044577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!NNS)
1045577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1046577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1047577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Named = getDerived().TransformType(T->getNamedType());
1048577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Named.isNull())
1049577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1050577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1051577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1052577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      NNS == T->getQualifier() &&
1053577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Named == T->getNamedType())
1054577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1055577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1056577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildQualifiedNameType(NNS, Named);
1057577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1058577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1059577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1060577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
1061577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NestedNameSpecifier *NNS
1062577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
1063577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                SourceRange(getDerived().getBaseLocation()));
1064577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!NNS)
1065577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1066577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1067577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
1068577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    QualType NewTemplateId
1069577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      = getDerived().TransformType(QualType(TemplateId, 0));
1070577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (NewTemplateId.isNull())
1071577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType();
1072577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1073577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (!getDerived().AlwaysRebuild() &&
1074577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor        NNS == T->getQualifier() &&
1075577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor        NewTemplateId == QualType(TemplateId, 0))
1076577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType(T, 0);
1077577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1078577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return getDerived().RebuildTypenameType(NNS, NewTemplateId);
1079577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1080577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1081577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
1082577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1083577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1084577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1085577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformObjCInterfaceType(
1086577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const ObjCInterfaceType *T) {
1087577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
1088577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1089577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1090577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1091577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1092577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformObjCObjectPointerType(
1093577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                             const ObjCObjectPointerType *T) {
1094577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
1095577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1096577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1097577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1098577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
1099577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor// Type reconstruction
1100577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
1101577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1102577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1103577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
1104577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildPointerType(PointeeType, 0,
1105577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  getDerived().getBaseLocation(),
1106577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  getDerived().getBaseEntity());
1107577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1108577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1109577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1110577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
1111577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildBlockPointerType(PointeeType, 0,
1112577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       getDerived().getBaseLocation(),
1113577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       getDerived().getBaseEntity());
1114577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1115577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1116577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1117577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1118577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
1119577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildReferenceType(ReferentType, true, 0,
1120577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseLocation(),
1121577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseEntity());
1122577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1123577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1124577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1125577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1126577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
1127577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildReferenceType(ReferentType, false, 0,
1128577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseLocation(),
1129577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseEntity());
1130577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1131577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1132577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1133577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
1134577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          QualType ClassType) {
1135577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
1136577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        getDerived().getBaseLocation(),
1137577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        getDerived().getBaseEntity());
1138577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1139577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1140577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1141577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1142577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildArrayType(QualType ElementType,
1143577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         ArrayType::ArraySizeModifier SizeMod,
1144577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         const llvm::APInt *Size,
1145577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         Expr *SizeExpr,
1146577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         unsigned IndexTypeQuals,
1147577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         SourceRange BracketsRange) {
1148577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (SizeExpr || !Size)
1149577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
1150577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  IndexTypeQuals, BracketsRange,
1151577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  getDerived().getBaseEntity());
1152577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1153577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Types[] = {
1154577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
1155577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
1156577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
1157577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  };
1158577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
1159577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType SizeType;
1160577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  for (unsigned I = 0; I != NumTypes; ++I)
1161577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
1162577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      SizeType = Types[I];
1163577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      break;
1164577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    }
1165577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1166577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (SizeType.isNull())
1167577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
1168577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1169577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
1170577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
1171577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                IndexTypeQuals, BracketsRange,
1172577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                getDerived().getBaseEntity());
1173577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1174577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1175577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1176577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1177577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
1178577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 ArrayType::ArraySizeModifier SizeMod,
1179577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 const llvm::APInt &Size,
1180577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 unsigned IndexTypeQuals) {
1181577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1182577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        IndexTypeQuals, SourceRange());
1183577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1184577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1185577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1186577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1187577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
1188577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1189577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                      const llvm::APInt &Size,
1190577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         Expr *SizeExpr,
1191577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                      unsigned IndexTypeQuals,
1192577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    SourceRange BracketsRange) {
1193577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
1194577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, BracketsRange);
1195577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1196577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1197577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1198577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1199577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
1200577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        QualType ElementType,
1201577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1202577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       const llvm::APInt &Size,
1203577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     unsigned IndexTypeQuals) {
1204577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1205577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, SourceRange());
1206577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1207577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1208577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1209577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1210577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
1211577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1212577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 unsigned IndexTypeQuals) {
1213577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
1214577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, SourceRange());
1215577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1216577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1217577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1218577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1219577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
1220577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1221577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 Sema::ExprArg SizeExpr,
1222577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 unsigned IndexTypeQuals,
1223577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 SourceRange BracketsRange) {
1224577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1225577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       SizeExpr.takeAs<Expr>(),
1226577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, BracketsRange);
1227577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1228577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1229577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1230577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1231577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
1232577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1233577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       Sema::ExprArg SizeExpr,
1234577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       unsigned IndexTypeQuals,
1235577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                   SourceRange BracketsRange) {
1236577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1237577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       SizeExpr.takeAs<Expr>(),
1238577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, BracketsRange);
1239577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1240577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1241577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1242577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
1243577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                   unsigned NumElements) {
1244577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: semantic checking!
1245577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.Context.getVectorType(ElementType, NumElements);
1246577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1247577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1248577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1249577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
1250577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                      unsigned NumElements,
1251577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 SourceLocation AttributeLoc) {
1252577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
1253577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                          NumElements, true);
1254577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  IntegerLiteral *VectorSize
1255577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
1256577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                           AttributeLoc);
1257577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
1258577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    AttributeLoc);
1259577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1260577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1261577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1262577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1263577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
1264577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         Sema::ExprArg SizeExpr,
1265577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  SourceLocation AttributeLoc) {
1266577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
1267577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1268577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1269577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1270577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
1271577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          QualType *ParamTypes,
1272577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        unsigned NumParamTypes,
1273577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          bool Variadic,
1274577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          unsigned Quals) {
1275577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
1276577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                   Quals,
1277577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                   getDerived().getBaseLocation(),
1278577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                   getDerived().getBaseEntity());
1279577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1280577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1281577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1282577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildTypeOfExprType(Sema::ExprArg E) {
1283577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
1284577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1285577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1286577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1287577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
1288577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.Context.getTypeOfType(Underlying);
1289577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1290577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1291577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1292577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildDecltypeType(Sema::ExprArg E) {
1293577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
1294577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1295577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1296577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1297577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
1298577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        TemplateName Template,
1299577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 const TemplateArgument *Args,
1300577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                           unsigned NumArgs) {
1301577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Missing source locations for the template name, <, >.
1302577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
1303577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                     SourceLocation(), Args, NumArgs,
1304577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                     SourceLocation());
1305577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1306577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1307dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
1308dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
1309dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1310dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   SourceRange Range,
1311dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   IdentifierInfo &II) {
1312dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  CXXScopeSpec SS;
1313dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  // FIXME: The source location information is all wrong.
1314dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  SS.setRange(Range);
1315dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  SS.setScopeRep(Prefix);
1316dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return static_cast<NestedNameSpecifier *>(
1317dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                    SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(),
1318dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                        Range.getEnd(), II));
1319dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
1320dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1321dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
1322dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
1323dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1324dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   SourceRange Range,
1325dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   NamespaceDecl *NS) {
1326dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
1327dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
1328dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1329dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
1330dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
1331dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1332dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   SourceRange Range,
1333dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   bool TemplateKW,
1334dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   QualType T) {
1335dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  if (T->isDependentType() || T->isRecordType() ||
1336dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
1337dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
1338dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
1339dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                       T.getTypePtr());
1340dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
1341dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1342dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
1343dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return 0;
1344dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
1345dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1346577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor} // end namespace clang
1347577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1348577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
1349