TreeTransform.h revision 657c1acfc47d5c315ce864f2089b692262532a17
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"
18657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor#include "clang/AST/Expr.h"
19577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include <algorithm>
20577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
21577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregornamespace clang {
22577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
23577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// \brief A semantic tree transformation that allows one to transform one
24577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// abstract syntax tree into another.
25577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
26577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// A new tree transformation is defined by creating a new subclass \c X of
27577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// \c TreeTransform<X> and then overriding certain operations to provide
28577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// behavior specific to that transformation. For example, template
29577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// instantiation is implemented as a tree transformation where the
30577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// transformation of TemplateTypeParmType nodes involves substituting the
31577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// template arguments for their corresponding template parameters; a similar
32577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// transformation is performed for non-type template parameters and
33577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// template template parameters.
34577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
35577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// This tree-transformation template uses static polymorphism to allow
36577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// subclasses to customize any of its operations. Thus, a subclass can
37577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// override any of the transformation or rebuild operators by providing an
38577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// operation with the same signature as the default implementation. The
39577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// overridding function should not be virtual.
40577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
41577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// Semantic tree transformations are split into two stages, either of which
42577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// can be replaced by a subclass. The "transform" step transforms an AST node
43577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// or the parts of an AST node using the various transformation functions,
44577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// then passes the pieces on to the "rebuild" step, which constructs a new AST
45577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// node of the appropriate kind from the pieces. The default transformation
46577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// routines recursively transform the operands to composite AST nodes (e.g.,
47577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// the pointee type of a PointerType node) and, if any of those operand nodes
48577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// were changed by the transformation, invokes the rebuild operation to create
49577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// a new AST node.
50577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
51577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// Subclasses can customize the transformation at various levels. The
52670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor/// most coarse-grained transformations involve replacing TransformType(),
53577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
54577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// TransformTemplateName(), or TransformTemplateArgument() with entirely
55577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// new implementations.
56577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
57577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// For more fine-grained transformations, subclasses can replace any of the
58577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
59577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// PointerType) to alter the transformation. As mentioned previously,
60577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// replacing TransformTemplateTypeParmType() allows template instantiation
61577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// to substitute template arguments for their corresponding template
62577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// parameters. Additionally, subclasses can override the \c RebuildXXX
63577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// functions to control how AST nodes are rebuilt when their operands change.
64577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// By default, \c TreeTransform will invoke semantic analysis to rebuild
65577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// AST nodes. However, certain other tree transformations (e.g, cloning) may
66577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// be able to use more efficient rebuild steps.
67577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
68577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// There are a handful of other functions that can be overridden, allowing one
69577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// to avoid traversing nodes that don't need any transformation
70577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
71577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// operands have not changed (\c AlwaysRebuild()), and customize the
72577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// default locations and entity names used for type-checking
73577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// (\c getBaseLocation(), \c getBaseEntity()).
74577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor///
75577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// FIXME: In the future, TreeTransform will support transformation of
76577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor/// statements and expressions as well as types.
77577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
78577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregorclass TreeTransform {
79577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregorprotected:
80577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema &SemaRef;
81577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
82577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregorpublic:
83577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Initializes a new tree transformer.
84577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
85577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
86577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Retrieves a reference to the derived class.
87577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Derived &getDerived() { return static_cast<Derived&>(*this); }
88577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
89577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Retrieves a reference to the derived class.
90577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  const Derived &getDerived() const {
91577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return static_cast<const Derived&>(*this);
92577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
93577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
94577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Retrieves a reference to the semantic analysis object used for
95577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// this tree transform.
96577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema &getSema() const { return SemaRef; }
97577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
98577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Whether the transformation should always rebuild AST nodes, even
99577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// if none of the children have changed.
100577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
101577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this function to specify when the transformation
102577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// should rebuild all AST nodes.
103577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  bool AlwaysRebuild() { return false; }
104577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
105577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Returns the location of the entity being transformed, if that
106577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// information was not available elsewhere in the AST.
107577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
108577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, returns no source-location information. Subclasses can
109577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// provide an alternative implementation that provides better location
110577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// information.
111577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  SourceLocation getBaseLocation() { return SourceLocation(); }
112577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
113577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Returns the name of the entity being transformed, if that
114577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// information was not available elsewhere in the AST.
115577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
116577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, returns an empty name. Subclasses can provide an alternative
117577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// implementation with a more precise name.
118577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  DeclarationName getBaseEntity() { return DeclarationName(); }
119577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
120577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Determine whether the given type \p T has already been
121577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// transformed.
122577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
123577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses can provide an alternative implementation of this routine
124577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// to short-circuit evaluation when it is known that a given type will
125577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// not change. For example, template instantiation need not traverse
126577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// non-dependent types.
127577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  bool AlreadyTransformed(QualType T) {
128577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return T.isNull();
129577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
130577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
131577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transforms the given type into another type.
132577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
133577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, this routine transforms a type by delegating to the
134577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// appropriate TransformXXXType to build a new type, then applying
135577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// the qualifiers on \p T to the resulting type with AddTypeQualifiers.
136577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this function (to take over all type
137577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// transformations), some set of the TransformXXXType functions, or
138577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// the AddTypeQualifiers function to alter the transformation.
139577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
140577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \returns the transformed type.
141577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType TransformType(QualType T);
142577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
143577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given type by adding the given set of qualifiers
144577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// and returning the result.
145577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
146577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// FIXME: By default, this routine adds type qualifiers only to types that
147577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// can have qualifiers, and silently suppresses those qualifiers that are
148577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// not permitted (e.g., qualifiers on reference or function types). This
149577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// is the right thing for template instantiation, but probably not for
150577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// other clients.
151577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType AddTypeQualifiers(QualType T, unsigned CVRQualifiers);
152577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
153657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  /// \brief Transform the given statement.
154577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
155577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// FIXME: At the moment, subclasses must override this.
156657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  Sema::OwningStmtResult TransformStmt(Stmt *S);
157657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor
158657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  /// \brief Transform the given expression.
159657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  ///
160657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  /// By default, invokes the derived class's TransformStmt() and downcasts
161657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  /// the result. Subclasses may override this function to provide alternate
162657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  /// behavior.
163577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult TransformExpr(Expr *E);
164577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
165577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given declaration, which is referenced from a type
166577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// or expression.
167577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
168dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, acts as the identity function on declarations. Subclasses
169dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// may override this function to provide alternate behavior.
170dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  Decl *TransformDecl(Decl *D) { return D; }
171577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
172577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given nested-name-specifier.
173577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
174dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, transforms all of the types and declarations within the
175dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// nested-name-specifier. Subclasses may override this function to provide
176dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// alternate behavior.
177577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
178577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    SourceRange Range);
179577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
180577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given template name.
181577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
182d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// By default, transforms the template name by transforming the declarations
183d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// and nested-name-specifiers that occur within the template name.
184d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// Subclasses may override this function to provide alternate behavior.
185d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  TemplateName TransformTemplateName(TemplateName Name);
186577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
187577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Transform the given template argument.
188577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
189670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// By default, this operation transforms the type, expression, or
190670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// declaration stored within the template argument and constructs a
191670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// new template argument from the transformed result. Subclasses may
192670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  /// override this function to provide alternate behavior.
193577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
194577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
195577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT)
196577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define TYPE(CLASS, PARENT)                                   \
197577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Transform##CLASS##Type(const CLASS##Type *T);
198577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include "clang/AST/TypeNodes.def"
199577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
200577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new pointer type given its pointee type.
201577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
202577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the pointer type.
203577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
204577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildPointerType(QualType PointeeType);
205577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
206577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new block pointer type given its pointee type.
207577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
208577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the block pointer
209577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
210577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildBlockPointerType(QualType PointeeType);
211577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
212577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new lvalue reference type given the type it references.
213577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
214577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the lvalue reference
215577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
216577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildLValueReferenceType(QualType ReferentType);
217577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
218577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new rvalue reference type given the type it references.
219577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
220577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the rvalue reference
221577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
222577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildRValueReferenceType(QualType ReferentType);
223577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
224577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new member pointer type given the pointee type and the
225577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// class type it refers into.
226577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
227577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the member pointer
228577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// type. Subclasses may override this routine to provide different behavior.
229577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
230577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
231577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new array type given the element type, size
232577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, size of the array (if known), size expression, and index type
233577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// qualifiers.
234577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
235577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
236577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
237577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Also by default, all of the other Rebuild*Array
238577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildArrayType(QualType ElementType,
239577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            ArrayType::ArraySizeModifier SizeMod,
240577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            const llvm::APInt *Size,
241577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            Expr *SizeExpr,
242577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            unsigned IndexTypeQuals,
243577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                            SourceRange BracketsRange);
244577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
245577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new constant array type given the element type, size
246577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, (known) size of the array, and index type qualifiers.
247577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
248577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
249577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
250577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildConstantArrayType(QualType ElementType,
251577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    ArrayType::ArraySizeModifier SizeMod,
252577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    const llvm::APInt &Size,
253577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    unsigned IndexTypeQuals);
254577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
255577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new constant array type given the element type, size
256577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, (known) size of the array, size expression, and index type
257577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// qualifiers.
258577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
259577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
260577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
261577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildConstantArrayWithExprType(QualType ElementType,
262577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            ArrayType::ArraySizeModifier SizeMod,
263577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            const llvm::APInt &Size,
264577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            Expr *SizeExpr,
265577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            unsigned IndexTypeQuals,
266577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                            SourceRange BracketsRange);
267577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
268577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new constant array type given the element type, size
269577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, (known) size of the array, 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 RebuildConstantArrayWithoutExprType(QualType ElementType,
274577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               ArrayType::ArraySizeModifier SizeMod,
275577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               const llvm::APInt &Size,
276577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               unsigned IndexTypeQuals);
277577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
278577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new incomplete array type given the element type, size
279577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// modifier, and index type qualifiers.
280577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
281577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
282577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
283577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildIncompleteArrayType(QualType ElementType,
284577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      ArrayType::ArraySizeModifier SizeMod,
285577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      unsigned IndexTypeQuals);
286577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
287577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new variable-length array type given the element type,
288577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// size modifier, size expression, and index type qualifiers.
289577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
290577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
291577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
292577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildVariableArrayType(QualType ElementType,
293577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    ArrayType::ArraySizeModifier SizeMod,
294577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    Sema::ExprArg SizeExpr,
295577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    unsigned IndexTypeQuals,
296577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    SourceRange BracketsRange);
297577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
298577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new dependent-sized array type given the element type,
299577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// size modifier, size expression, and index type qualifiers.
300577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
301577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the array type.
302577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
303577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildDependentSizedArrayType(QualType ElementType,
304577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
305577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          Sema::ExprArg SizeExpr,
306577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          unsigned IndexTypeQuals,
307577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          SourceRange BracketsRange);
308577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
309577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new vector type given the element type and
310577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// number of elements.
311577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
312577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the vector type.
313577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
314577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
315577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
316577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new extended vector type given the element type and
317577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// number of elements.
318577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
319577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the vector type.
320577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
321577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
322577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                SourceLocation AttributeLoc);
323577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
324577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new potentially dependently-sized extended vector type
325577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// given the element type and number of elements.
326577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
327577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the vector type.
328577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
329577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildDependentSizedExtVectorType(QualType ElementType,
330577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              Sema::ExprArg SizeExpr,
331577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              SourceLocation AttributeLoc);
332577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
333577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new function type.
334577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
335577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the function type.
336577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
337577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildFunctionProtoType(QualType T,
338577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    QualType *ParamTypes,
339577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    unsigned NumParamTypes,
340577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    bool Variadic, unsigned Quals);
341577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
342577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typedef type.
343577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypedefType(TypedefDecl *Typedef) {
344577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getTypeDeclType(Typedef);
345577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
346577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
347577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new class/struct/union type.
348577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildRecordType(RecordDecl *Record) {
349577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getTypeDeclType(Record);
350577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
351577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
352577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new Enum type.
353577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildEnumType(EnumDecl *Enum) {
354577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getTypeDeclType(Enum);
355577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
356577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
357577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typeof(expr) type.
358577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
359577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the typeof type.
360577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
361577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypeOfExprType(Sema::ExprArg Underlying);
362577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
363577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typeof(type) type.
364577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
365577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, builds a new TypeOfType with the given underlying type.
366577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypeOfType(QualType Underlying);
367577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
368577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new C++0x decltype type.
369577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
370577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the decltype type.
371577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// Subclasses may override this routine to provide different behavior.
372577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildDecltypeType(Sema::ExprArg Underlying);
373577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
374577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new template specialization type.
375577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
376577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the template
377577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// specialization type. Subclasses may override this routine to provide
378577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// different behavior.
379577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTemplateSpecializationType(TemplateName Template,
380577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                             const TemplateArgument *Args,
381577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                             unsigned NumArgs);
382577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
383577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new qualified name type.
384577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
385577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, builds a new QualifiedNameType type from the
386577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// nested-name-specifier and the named type. Subclasses may override
387577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// this routine to provide different behavior.
388577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
389577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getQualifiedNameType(NNS, Named);
390577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
391577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
392577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typename type that refers to a template-id.
393577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
394577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, builds a new TypenameType type from the nested-name-specifier
395577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// and the given type. Subclasses may override this routine to provide
396577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// different behavior.
397577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
398577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (NNS->isDependent())
399577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return SemaRef.Context.getTypenameType(NNS,
400577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          cast<TemplateSpecializationType>(T));
401577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
402577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.Context.getQualifiedNameType(NNS, T);
403577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
404577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
405577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// \brief Build a new typename type that refers to an identifier.
406577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  ///
407577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// By default, performs semantic analysis when building the typename type
408577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// (or qualified name type). Subclasses may override this routine to provide
409577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  /// different behavior.
410577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType RebuildTypenameType(NestedNameSpecifier *NNS,
411577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                               const IdentifierInfo *Id) {
412577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.CheckTypenameType(NNS, *Id,
413577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  SourceRange(getDerived().getBaseLocation()));
414dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
415dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
416dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// \brief Build a new nested-name-specifier given the prefix and an
417dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// identifier that names 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                                                  IdentifierInfo &II);
425dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
426dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// \brief Build a new nested-name-specifier given the prefix and the
427dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// namespace 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                                                  NamespaceDecl *NS);
435dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
436dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// \brief Build a new nested-name-specifier given the prefix and the
437dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// type named in the next step in the nested-name-specifier.
438dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  ///
439dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// By default, performs semantic analysis when building the new
440dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// nested-name-specifier. Subclasses may override this routine to provide
441dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  /// different behavior.
442dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
443dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  SourceRange Range,
444dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  bool TemplateKW,
445dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                  QualType T);
446d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
447d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// \brief Build a new template name given a nested name specifier, a flag
448d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// indicating whether the "template" keyword was provided, and the template
449d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// that the template name refers to.
450d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  ///
451d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// By default, builds the new template name directly. Subclasses may override
452d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// this routine to provide different behavior.
453d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
454d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                   bool TemplateKW,
455d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                   TemplateDecl *Template);
456d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
457d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// \brief Build a new template name given a nested name specifier, a flag
458d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// indicating whether the "template" keyword was provided, and a set of
459d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// overloaded function templates.
460d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  ///
461d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// By default, builds the new template name directly. Subclasses may override
462d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// this routine to provide different behavior.
463d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
464d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                   bool TemplateKW,
465d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                   OverloadedFunctionDecl *Ovl);
466d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
467d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// \brief Build a new template name given a nested name specifier and the
468d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// name that is referred to as a template.
469d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  ///
470d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// By default, performs semantic analysis to determine whether the name can
471d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// be resolved to a specific template, then builds the appropriate kind of
472d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// template name. Subclasses may override this routine to provide different
473d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  /// behavior.
474d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
475d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                   const IdentifierInfo &II);
476577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor};
477577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
478670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregortemplate<typename Derived>
479657c1acfc47d5c315ce864f2089b692262532a17Douglas GregorSema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
480657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  Sema::OwningStmtResult Result = getDerived().TransformStmt(E);
481657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  if (Result.isInvalid())
482657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor    return SemaRef.ExprError();
483657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor
484657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor  return SemaRef.Owned(cast_or_null<Stmt>(Result.takeAs<Stmt>()));
485657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor}
486657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregor
487657c1acfc47d5c315ce864f2089b692262532a17Douglas Gregortemplate<typename Derived>
488dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
489dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
490dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                     SourceRange Range) {
491dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  // Instantiate the prefix of this nested name specifier.
492dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  NestedNameSpecifier *Prefix = NNS->getPrefix();
493dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  if (Prefix) {
494dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
495dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!Prefix)
496dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return 0;
497dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
498dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
499dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  switch (NNS->getKind()) {
500dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::Identifier:
501dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    assert(Prefix &&
502dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor           "Can't have an identifier nested-name-specifier with no prefix");
503dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
504dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return NNS;
505dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
506dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
507dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   *NNS->getAsIdentifier());
508dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
509dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::Namespace: {
510dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    NamespaceDecl *NS
511dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      = cast_or_null<NamespaceDecl>(
512dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                            getDerived().TransformDecl(NNS->getAsNamespace()));
513dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!getDerived().AlwaysRebuild() &&
514dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        Prefix == NNS->getPrefix() &&
515dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        NS == NNS->getAsNamespace())
516dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return NNS;
517dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
518dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
519dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
520dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
521dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::Global:
522dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    // There is no meaningful transformation that one could perform on the
523dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    // global scope.
524dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return NNS;
525dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
526dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::TypeSpecWithTemplate:
527dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  case NestedNameSpecifier::TypeSpec: {
528dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
529d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (T.isNull())
530d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return 0;
531d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
532dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    if (!getDerived().AlwaysRebuild() &&
533dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        Prefix == NNS->getPrefix() &&
534dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor        T == QualType(NNS->getAsType(), 0))
535dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      return NNS;
536dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
537dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
538dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                  NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
539dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   T);
540dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
541dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
542dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
543dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  // Required to silence a GCC warning
544dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return 0;
545dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
546dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
547dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
548d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTemplateName
549d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTreeTransform<Derived>::TransformTemplateName(TemplateName Name) {
550d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
551d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    NestedNameSpecifier *NNS
552d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
553d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                      /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
554d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!NNS)
555d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return TemplateName();
556d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
557d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (TemplateDecl *Template = QTN->getTemplateDecl()) {
558d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      TemplateDecl *TransTemplate
559d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
560d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      if (!TransTemplate)
561d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        return TemplateName();
562d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
563d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      if (!getDerived().AlwaysRebuild() &&
564d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor          NNS == QTN->getQualifier() &&
565d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor          TransTemplate == Template)
566d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        return Name;
567d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
568d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
569d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                              TransTemplate);
570d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    }
571d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
572d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
573d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    assert(Ovl && "Not a template name or an overload set?");
574d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    OverloadedFunctionDecl *TransOvl
575d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
576d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!TransOvl)
577d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return TemplateName();
578d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
579d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!getDerived().AlwaysRebuild() &&
580d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        NNS == QTN->getQualifier() &&
581d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        TransOvl == Ovl)
582d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return Name;
583d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
584d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
585d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                            TransOvl);
586d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  }
587d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
588d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
589d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    NestedNameSpecifier *NNS
590d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
591d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                        /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
592d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!NNS)
593d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return TemplateName();
594d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
595d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!getDerived().AlwaysRebuild() &&
596d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        NNS == DTN->getQualifier())
597d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return Name;
598d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
599d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return getDerived().RebuildTemplateName(NNS, *DTN->getName());
600d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  }
601d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
602d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
603d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    TemplateDecl *TransTemplate
604d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
605d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!TransTemplate)
606d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return TemplateName();
607d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
608d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    if (!getDerived().AlwaysRebuild() &&
609d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor        TransTemplate == Template)
610d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      return Name;
611d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
612d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return TemplateName(TransTemplate);
613d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  }
614d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
615d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
616d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  assert(Ovl && "Not a template name or an overload set?");
617d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  OverloadedFunctionDecl *TransOvl
618d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
619d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (!TransOvl)
620d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return TemplateName();
621d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
622d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
623d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      TransOvl == Ovl)
624d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return Name;
625d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
626d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  return TemplateName(TransOvl);
627d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor}
628d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
629d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregortemplate<typename Derived>
630670444ed30cc8ff66eb4847d921d9af0291a7111Douglas GregorTemplateArgument
631670444ed30cc8ff66eb4847d921d9af0291a7111Douglas GregorTreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
632670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  switch (Arg.getKind()) {
633670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Null:
634670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Integral:
635670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return Arg;
636670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
637670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Type: {
638670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    QualType T = getDerived().TransformType(Arg.getAsType());
639670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    if (T.isNull())
640670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      return TemplateArgument();
641670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return TemplateArgument(Arg.getLocation(), T);
642670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
643670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
644670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Declaration: {
645670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
646670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    if (!D)
647670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      return TemplateArgument();
648670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return TemplateArgument(Arg.getLocation(), D);
649670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
650670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
651670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Expression: {
652670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    // Template argument expressions are not potentially evaluated.
653670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    EnterExpressionEvaluationContext Unevaluated(getSema(),
654670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                                                 Action::Unevaluated);
655670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
656670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
657670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    if (E.isInvalid())
658670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      return TemplateArgument();
659670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return TemplateArgument(E.takeAs<Expr>());
660670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
661670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
662670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  case TemplateArgument::Pack: {
663670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
664670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    TransformedArgs.reserve(Arg.pack_size());
665670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
666670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                                      AEnd = Arg.pack_end();
667670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor         A != AEnd; ++A) {
668670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
669670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      if (TA.isNull())
670670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor        return TA;
671670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
672670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      TransformedArgs.push_back(TA);
673670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    }
674670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    TemplateArgument Result;
675670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
676670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                           true);
677670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return Result;
678670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
679670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  }
680670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
681670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Work around bogus GCC warning
682670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  return TemplateArgument();
683670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor}
684670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
685577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
686577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor// Type transformation
687577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
688577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
689577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
690577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformType(QualType T) {
691577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (getDerived().AlreadyTransformed(T))
692577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return T;
693577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
694577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Result;
695577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  switch (T->getTypeClass()) {
696577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT)
697577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#define TYPE(CLASS, PARENT)                                                  \
698577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    case Type::CLASS:                                                        \
699577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Result = getDerived().Transform##CLASS##Type(                          \
700577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  static_cast<CLASS##Type*>(T.getTypePtr())); \
701577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      break;
702577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#include "clang/AST/TypeNodes.def"
703577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
704577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
705577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Result.isNull() || T == Result)
706577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return Result;
707577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
708577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().AddTypeQualifiers(Result, T.getCVRQualifiers());
709577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
710577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
711577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
712577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
713577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) {
714577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (CVRQualifiers && !T->isFunctionType() && !T->isReferenceType())
715577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return T.getWithAdditionalQualifiers(CVRQualifiers);
716577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
717577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return T;
718577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
719577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
720577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
721577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformExtQualType(const ExtQualType *T) {
722577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
723577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
724577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
725577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
726577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
727577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
728577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // Nothing to do
729577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
730577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
731577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
732577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
733577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformFixedWidthIntType(
734577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const FixedWidthIntType *T) {
735577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
736577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
737577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
738577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
739577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
740577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
741577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
742577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
743577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
744577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
745577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
746577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
747577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
748577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
749577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
750577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
751577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
752577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
753577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
754577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
755577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildPointerType(PointeeType);
756577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
757577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
758577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
759577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
760577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
761577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
762577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
763577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
764577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
765577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
766577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
767577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
768577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
769577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildBlockPointerType(PointeeType);
770577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
771577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
772577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
773577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
774577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformLValueReferenceType(
775577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               const LValueReferenceType *T) {
776577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
777577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
778577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
779577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
780577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
781577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
782577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
783577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
784577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildLValueReferenceType(PointeeType);
785577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
786577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
787577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
788577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
789577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformRValueReferenceType(
790577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              const RValueReferenceType *T) {
791577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
792577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
793577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
794577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
795577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
796577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType())
797577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
798577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
799577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildRValueReferenceType(PointeeType);
800577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
801577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
802577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
803577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
804577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
805577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType PointeeType = getDerived().TransformType(T->getPointeeType());
806577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (PointeeType.isNull())
807577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
808577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
809577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
810577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ClassType.isNull())
811577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
812577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
813577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
814577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      PointeeType == T->getPointeeType() &&
815577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ClassType == QualType(T->getClass(), 0))
816577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
817577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
818577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
819577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
820577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
821577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
822577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
823577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
824577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
825577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
826577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
827577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
828577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
829577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
830577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
831577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
832577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildConstantArrayType(ElementType,
833577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getSizeModifier(),
834577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getSize(),
835577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getIndexTypeQualifier());
836577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
837577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
838577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
839577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
840577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformConstantArrayWithExprType(
841577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      const ConstantArrayWithExprType *T) {
842577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
843577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
844577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
845577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
846670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Array bounds are not potentially evaluated contexts
847670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
848670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
849670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
850670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  if (Size.isInvalid())
851670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor    return QualType();
852670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
853577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
854670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      ElementType == T->getElementType() &&
855670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor      Size.get() == T->getSizeExpr())
856577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
857577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
858577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildConstantArrayWithExprType(ElementType,
859577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSizeModifier(),
860577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSize(),
861670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor                                                       Size.takeAs<Expr>(),
862577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                   T->getIndexTypeQualifier(),
863577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getBracketsRange());
864577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
865577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
866577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
867577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
868577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformConstantArrayWithoutExprType(
869577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      const ConstantArrayWithoutExprType *T) {
870577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
871577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
872577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
873577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
874577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
875577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
876577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
877577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
878577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
879577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSizeModifier(),
880577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       T->getSize(),
881577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    T->getIndexTypeQualifier());
882577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
883577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
884577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
885577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformIncompleteArrayType(
886577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              const IncompleteArrayType *T) {
887577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
888577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
889577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
890577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
891577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
892577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
893577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
894577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
895577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildIncompleteArrayType(ElementType,
896577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 T->getSizeModifier(),
897577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 T->getIndexTypeQualifier());
898577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
899577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
900577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
901577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformVariableArrayType(
902577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const VariableArrayType *T) {
903577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
904577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
905577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
906577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
907670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Array bounds are not potentially evaluated contexts
908670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
909670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
910577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
911577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Size.isInvalid())
912577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
913577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
914577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
915577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType() &&
916577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Size.get() == T->getSizeExpr()) {
917577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    Size.take();
918577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
919577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
920577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
921577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildVariableArrayType(ElementType,
922577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getSizeModifier(),
923577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               move(Size),
924577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getIndexTypeQualifier(),
925577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getBracketsRange());
926577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
927577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
928577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
929577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformDependentSizedArrayType(
930577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          const DependentSizedArrayType *T) {
931577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
932577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
933577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
934577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
935670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Array bounds are not potentially evaluated contexts
936670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
937670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
938577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
939577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Size.isInvalid())
940577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
941577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
942577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
943577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType() &&
944577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Size.get() == T->getSizeExpr()) {
945577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    Size.take();
946577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
947577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
948577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
949577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildDependentSizedArrayType(ElementType,
950577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     T->getSizeModifier(),
951577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     move(Size),
952577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     T->getIndexTypeQualifier(),
953577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     T->getBracketsRange());
954577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
955577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
956577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
957577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
958577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                      const DependentSizedExtVectorType *T) {
959577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
960577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
961577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
962577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
963670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // Vector sizes are not potentially evaluated contexts
964670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
965670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
966577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
967577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Size.isInvalid())
968577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
969577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
970577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
971577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType() &&
972577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Size.get() == T->getSizeExpr()) {
973577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    Size.take();
974577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
975577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
976577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
977577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildDependentSizedExtVectorType(ElementType,
978577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         move(Size),
979577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         T->getAttributeLoc());
980577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
981577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
982577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
983577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
984577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
985577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
986577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
987577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
988577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
989577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
990577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
991577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
992577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildVectorType(ElementType, T->getNumElements());
993577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
994577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
995577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
996577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
997577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
998577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ElementType = getDerived().TransformType(T->getElementType());
999577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ElementType.isNull())
1000577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1001577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1002577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1003577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ElementType == T->getElementType())
1004577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1005577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1006577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
1007577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                           /*FIXME*/SourceLocation());
1008577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1009577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1010577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1011577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformFunctionProtoType(
1012577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const FunctionProtoType *T) {
1013577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType ResultType = getDerived().TransformType(T->getResultType());
1014577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (ResultType.isNull())
1015577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1016577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1017577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  llvm::SmallVector<QualType, 4> ParamTypes;
1018577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
1019577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         ParamEnd = T->arg_type_end();
1020577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor       Param != ParamEnd; ++Param) {
1021577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    QualType P = getDerived().TransformType(*Param);
1022577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (P.isNull())
1023577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType();
1024577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1025577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    ParamTypes.push_back(P);
1026577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1027577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1028577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1029577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      ResultType == T->getResultType() &&
1030577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
1031577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1032577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1033577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
1034577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               ParamTypes.size(), T->isVariadic(),
1035577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                               T->getTypeQuals());
1036577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1037577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1038577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1039577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformFunctionNoProtoType(
1040577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                const FunctionNoProtoType *T) {
1041577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
1042577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1043577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1044577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1045577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1046577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
1047577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TypedefDecl *Typedef
1048577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
1049577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!Typedef)
1050577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1051577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1052577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1053577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Typedef == T->getDecl())
1054577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1055577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1056577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypedefType(Typedef);
1057577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1058577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1059577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1060577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypeOfExprType(
1061577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    const TypeOfExprType *T) {
1062670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // typeof expressions are not potentially evaluated contexts
1063670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
1064670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
1065577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
1066577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (E.isInvalid())
1067577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1068577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1069577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1070577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      E.get() == T->getUnderlyingExpr()) {
1071577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    E.take();
1072577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1073577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1074577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1075577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypeOfExprType(move(E));
1076577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1077577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1078577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1079577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
1080577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
1081577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Underlying.isNull())
1082577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1083577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1084577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1085577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Underlying == T->getUnderlyingType())
1086577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1087577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1088577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypeOfType(Underlying);
1089577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1090577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1091577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1092577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
1093670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  // decltype expressions are not potentially evaluated contexts
1094670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
1095670444ed30cc8ff66eb4847d921d9af0291a7111Douglas Gregor
1096577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
1097577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (E.isInvalid())
1098577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1099577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1100577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1101577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      E.get() == T->getUnderlyingExpr()) {
1102577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    E.take();
1103577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1104577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1105577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1106577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildDecltypeType(move(E));
1107577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1108577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1109577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1110577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
1111577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  RecordDecl *Record
1112577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
1113577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!Record)
1114577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1115577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1116577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1117577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Record == T->getDecl())
1118577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1119577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1120577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildRecordType(Record);
1121577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1122577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1123577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1124577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
1125577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  EnumDecl *Enum
1126577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
1127577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!Enum)
1128577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1129577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1130577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1131577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Enum == T->getDecl())
1132577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1133577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1134577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildEnumType(Enum);
1135577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1136577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1137577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1138577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTemplateTypeParmType(
1139577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                              const TemplateTypeParmType *T) {
1140577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // Nothing to do
1141577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1142577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1143577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1144577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1145577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTemplateSpecializationType(
1146577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        const TemplateSpecializationType *T) {
1147577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  TemplateName Template
1148577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = getDerived().TransformTemplateName(T->getTemplateName());
1149577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Template.isNull())
1150577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1151577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1152577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
1153577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NewTemplateArgs.reserve(T->getNumArgs());
1154577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
1155577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor       Arg != ArgEnd; ++Arg) {
1156577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
1157577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (NewArg.isNull())
1158577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType();
1159577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1160577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    NewTemplateArgs.push_back(NewArg);
1161577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1162577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1163577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: early abort if all of the template arguments and such are the
1164577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // same.
1165577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1166577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: We're missing the locations of the template name, '<', and '>'.
1167577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTemplateSpecializationType(Template,
1168577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        NewTemplateArgs.data(),
1169577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        NewTemplateArgs.size());
1170577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1171577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1172577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1173577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformQualifiedNameType(
1174577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const QualifiedNameType *T) {
1175577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NestedNameSpecifier *NNS
1176577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
1177577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                SourceRange());
1178577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!NNS)
1179577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1180577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1181577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Named = getDerived().TransformType(T->getNamedType());
1182577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (Named.isNull())
1183577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1184577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1185577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!getDerived().AlwaysRebuild() &&
1186577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      NNS == T->getQualifier() &&
1187577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      Named == T->getNamedType())
1188577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType(T, 0);
1189577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1190577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildQualifiedNameType(NNS, Named);
1191577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1192577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1193577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1194577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
1195577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  NestedNameSpecifier *NNS
1196577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
11974a959d8788179d654df6b213b08d2b064989211dDouglas Gregor                        SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
1198577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (!NNS)
1199577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return QualType();
1200577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1201577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
1202577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    QualType NewTemplateId
1203577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      = getDerived().TransformType(QualType(TemplateId, 0));
1204577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (NewTemplateId.isNull())
1205577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType();
1206577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1207577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (!getDerived().AlwaysRebuild() &&
1208577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor        NNS == T->getQualifier() &&
1209577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor        NewTemplateId == QualType(TemplateId, 0))
1210577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      return QualType(T, 0);
1211577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1212577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return getDerived().RebuildTypenameType(NNS, NewTemplateId);
1213577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  }
1214577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1215577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
1216577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1217577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1218577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1219577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformObjCInterfaceType(
1220577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  const ObjCInterfaceType *T) {
1221577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
1222577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1223577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1224577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1225577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1226577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::TransformObjCObjectPointerType(
1227577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                             const ObjCObjectPointerType *T) {
1228577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Implement
1229577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return QualType(T, 0);
1230577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1231577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1232577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
1233577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor// Type reconstruction
1234577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor//===----------------------------------------------------------------------===//
1235577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1236577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1237577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
1238577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildPointerType(PointeeType, 0,
1239577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  getDerived().getBaseLocation(),
1240577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  getDerived().getBaseEntity());
1241577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1242577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1243577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1244577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
1245577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildBlockPointerType(PointeeType, 0,
1246577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       getDerived().getBaseLocation(),
1247577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       getDerived().getBaseEntity());
1248577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1249577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1250577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1251577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1252577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
1253577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildReferenceType(ReferentType, true, 0,
1254577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseLocation(),
1255577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseEntity());
1256577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1257577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1258577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1259577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1260577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
1261577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildReferenceType(ReferentType, false, 0,
1262577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseLocation(),
1263577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    getDerived().getBaseEntity());
1264577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1265577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1266577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1267577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
1268577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          QualType ClassType) {
1269577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 0,
1270577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        getDerived().getBaseLocation(),
1271577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        getDerived().getBaseEntity());
1272577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1273577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1274577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1275577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1276577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildArrayType(QualType ElementType,
1277577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         ArrayType::ArraySizeModifier SizeMod,
1278577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         const llvm::APInt *Size,
1279577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         Expr *SizeExpr,
1280577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         unsigned IndexTypeQuals,
1281577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                         SourceRange BracketsRange) {
1282577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (SizeExpr || !Size)
1283577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
1284577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  IndexTypeQuals, BracketsRange,
1285577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                  getDerived().getBaseEntity());
1286577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1287577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType Types[] = {
1288577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
1289577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
1290577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
1291577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  };
1292577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
1293577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  QualType SizeType;
1294577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  for (unsigned I = 0; I != NumTypes; ++I)
1295577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
1296577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      SizeType = Types[I];
1297577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor      break;
1298577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    }
1299577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1300577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  if (SizeType.isNull())
1301577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
1302577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1303577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
1304577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
1305577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                IndexTypeQuals, BracketsRange,
1306577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                getDerived().getBaseEntity());
1307577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1308577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1309577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1310577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1311577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
1312577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 ArrayType::ArraySizeModifier SizeMod,
1313577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 const llvm::APInt &Size,
1314577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 unsigned IndexTypeQuals) {
1315577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1316577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                        IndexTypeQuals, SourceRange());
1317577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1318577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1319577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1320577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1321577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
1322577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1323577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                      const llvm::APInt &Size,
1324577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         Expr *SizeExpr,
1325577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                      unsigned IndexTypeQuals,
1326577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                    SourceRange BracketsRange) {
1327577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
1328577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, BracketsRange);
1329577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1330577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1331577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1332577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1333577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
1334577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        QualType ElementType,
1335577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1336577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       const llvm::APInt &Size,
1337577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                     unsigned IndexTypeQuals) {
1338577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
1339577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, SourceRange());
1340577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1341577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1342577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1343577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1344577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
1345577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1346577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 unsigned IndexTypeQuals) {
1347577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
1348577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, SourceRange());
1349577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1350577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1351577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1352577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1353577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
1354577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1355577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 Sema::ExprArg SizeExpr,
1356577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 unsigned IndexTypeQuals,
1357577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 SourceRange BracketsRange) {
1358577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1359577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       SizeExpr.takeAs<Expr>(),
1360577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, BracketsRange);
1361577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1362577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1363577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1364577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1365577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
1366577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                          ArrayType::ArraySizeModifier SizeMod,
1367577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       Sema::ExprArg SizeExpr,
1368577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                       unsigned IndexTypeQuals,
1369577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                   SourceRange BracketsRange) {
1370577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
1371577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       SizeExpr.takeAs<Expr>(),
1372577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                       IndexTypeQuals, BracketsRange);
1373577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1374577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1375577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1376577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
1377577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                   unsigned NumElements) {
1378577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: semantic checking!
1379577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.Context.getVectorType(ElementType, NumElements);
1380577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1381577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1382577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1383577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
1384577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                      unsigned NumElements,
1385577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 SourceLocation AttributeLoc) {
1386577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
1387577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                          NumElements, true);
1388577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  IntegerLiteral *VectorSize
1389577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor    = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
1390577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                           AttributeLoc);
1391577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
1392577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                    AttributeLoc);
1393577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1394577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1395577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1396577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType
1397577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorTreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
1398577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                         Sema::ExprArg SizeExpr,
1399577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                  SourceLocation AttributeLoc) {
1400577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
1401577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1402577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1403577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1404577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
1405577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          QualType *ParamTypes,
1406577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        unsigned NumParamTypes,
1407577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          bool Variadic,
1408577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                          unsigned Quals) {
1409577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
1410577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                   Quals,
1411577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                   getDerived().getBaseLocation(),
1412577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                   getDerived().getBaseEntity());
1413577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1414577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1415577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1416577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildTypeOfExprType(Sema::ExprArg E) {
1417577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
1418577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1419577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1420577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1421577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
1422577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.Context.getTypeOfType(Underlying);
1423577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1424577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1425577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1426577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildDecltypeType(Sema::ExprArg E) {
1427577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
1428577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1429577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1430577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregortemplate<typename Derived>
1431577f75a7498e9e2536434da0ef0da0eea390d18bDouglas GregorQualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
1432577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                        TemplateName Template,
1433577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                 const TemplateArgument *Args,
1434577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                                           unsigned NumArgs) {
1435577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  // FIXME: Missing source locations for the template name, <, >.
1436577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor  return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
1437577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                     SourceLocation(), Args, NumArgs,
1438577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor                                     SourceLocation());
1439577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor}
1440577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1441dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
1442dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
1443dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1444dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   SourceRange Range,
1445dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   IdentifierInfo &II) {
1446dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  CXXScopeSpec SS;
1447dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  // FIXME: The source location information is all wrong.
1448dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  SS.setRange(Range);
1449dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  SS.setScopeRep(Prefix);
1450dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return static_cast<NestedNameSpecifier *>(
1451dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                    SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(),
1452dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                        Range.getEnd(), II));
1453dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
1454dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1455dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
1456dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
1457dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1458dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   SourceRange Range,
1459dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   NamespaceDecl *NS) {
1460dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
1461dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
1462dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1463dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregortemplate<typename Derived>
1464dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorNestedNameSpecifier *
1465dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas GregorTreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
1466dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   SourceRange Range,
1467dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   bool TemplateKW,
1468dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                                   QualType T) {
1469dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  if (T->isDependentType() || T->isRecordType() ||
1470dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor      (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
1471dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
1472dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor    return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
1473dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor                                       T.getTypePtr());
1474dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  }
1475dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1476dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
1477dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor  return 0;
1478dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor}
1479dcee1a12c83a6cbc9b5bf42df5d4efbc502664e7Douglas Gregor
1480d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregortemplate<typename Derived>
1481d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTemplateName
1482d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
1483d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                            bool TemplateKW,
1484d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                            TemplateDecl *Template) {
1485d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
1486d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                                  Template);
1487d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor}
1488d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
1489d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregortemplate<typename Derived>
1490d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTemplateName
1491d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
1492d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                            bool TemplateKW,
1493d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                            OverloadedFunctionDecl *Ovl) {
1494d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
1495d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor}
1496d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
1497d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregortemplate<typename Derived>
1498d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTemplateName
1499d1067e5a0a6e2aee7260c392452df9553034c92bDouglas GregorTreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
1500d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                                            const IdentifierInfo &II) {
1501d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (Qualifier->isDependent())
1502d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return SemaRef.Context.getDependentTemplateName(Qualifier, &II);
1503d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
1504d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  // Somewhat redundant with ActOnDependentTemplateName.
1505d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  CXXScopeSpec SS;
1506d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  SS.setRange(SourceRange(getDerived().getBaseLocation()));
1507d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  SS.setScopeRep(Qualifier);
1508d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  Sema::TemplateTy Template;
1509d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  TemplateNameKind TNK = SemaRef.isTemplateName(II, 0, Template, &SS);
1510d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  if (TNK == TNK_Non_template) {
1511d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    SemaRef.Diag(getDerived().getBaseLocation(),
1512d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                 diag::err_template_kw_refers_to_non_template)
1513d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      << &II;
1514d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return TemplateName();
1515d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  } else if (TNK == TNK_Function_template) {
1516d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    SemaRef.Diag(getDerived().getBaseLocation(),
1517d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor                 diag::err_template_kw_refers_to_non_template)
1518d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor      << &II;
1519d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor    return TemplateName();
1520d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  }
1521d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
1522d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor  return Template.getAsVal<TemplateName>();
1523d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor}
1524d1067e5a0a6e2aee7260c392452df9553034c92bDouglas Gregor
1525577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor} // end namespace clang
1526577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor
1527577f75a7498e9e2536434da0ef0da0eea390d18bDouglas Gregor#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
1528