aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
commit73490b890977362d28dd6326843a1ecae413921d (patch)
tree3fdd91eae574e32453a4baf462961c742df2691a /lib/Sema/TreeTransform.h
parenta5f348eb914e67b51914117fac117c18c1f8d650 (diff)
downloadsrc-73490b890977362d28dd6326843a1ecae413921d.tar.gz
src-73490b890977362d28dd6326843a1ecae413921d.zip
Update clang to r84949.vendor/clang/clang-r84949
Notes
Notes: svn path=/vendor/clang/dist/; revision=198398 svn path=/vendor/clang/clang-r84949/; revision=198399; tag=vendor/clang/clang-r84949
Diffstat (limited to 'lib/Sema/TreeTransform.h')
-rw-r--r--lib/Sema/TreeTransform.h1038
1 files changed, 679 insertions, 359 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index ec5c6676f5d2..7e0972fe03c4 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1,4 +1,4 @@
-//===------- TreeTransform.h - Semantic Tree Transformation ---------------===/
+//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
//
// The LLVM Compiler Infrastructure
//
@@ -22,9 +22,11 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
+#include "clang/AST/TypeLocBuilder.h"
#include "clang/Parse/Ownership.h"
#include "clang/Parse/Designator.h"
#include "clang/Lex/Preprocessor.h"
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
namespace clang {
@@ -170,25 +172,30 @@ public:
/// \brief Transforms the given type into another type.
///
- /// By default, this routine transforms a type by delegating to the
- /// appropriate TransformXXXType to build a new type, then applying
- /// the qualifiers on \p T to the resulting type with AddTypeQualifiers.
- /// Subclasses may override this function (to take over all type
- /// transformations), some set of the TransformXXXType functions, or
- /// the AddTypeQualifiers function to alter the transformation.
+ /// By default, this routine transforms a type by creating a
+ /// DeclaratorInfo for it and delegating to the appropriate
+ /// function. This is expensive, but we don't mind, because
+ /// this method is deprecated anyway; all users should be
+ /// switched to storing DeclaratorInfos.
///
/// \returns the transformed type.
QualType TransformType(QualType T);
- /// \brief Transform the given type by adding the given set of qualifiers
- /// and returning the result.
+ /// \brief Transforms the given type-with-location into a new
+ /// type-with-location.
+ ///
+ /// By default, this routine transforms a type by delegating to the
+ /// appropriate TransformXXXType to build a new type. Subclasses
+ /// may override this function (to take over all type
+ /// transformations) or some set of the TransformXXXType functions
+ /// to alter the transformation.
+ DeclaratorInfo *TransformType(DeclaratorInfo *DI);
+
+ /// \brief Transform the given type-with-location into a new
+ /// type, collecting location information in the given builder
+ /// as necessary.
///
- /// FIXME: By default, this routine adds type qualifiers only to types that
- /// can have qualifiers, and silently suppresses those qualifiers that are
- /// not permitted (e.g., qualifiers on reference or function types). This
- /// is the right thing for template instantiation, but probably not for
- /// other clients.
- QualType AddTypeQualifiers(QualType T, Qualifiers Qs);
+ QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
/// \brief Transform the given statement.
///
@@ -236,6 +243,19 @@ public:
/// Subclasses may override this function to provide alternate behavior.
Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
+ /// \brief Transform the given declaration, which was the first part of a
+ /// nested-name-specifier in a member access expression.
+ ///
+ /// This specific declaration transformation only applies to the first
+ /// identifier in a nested-name-specifier of a member access expression, e.g.,
+ /// the \c T in \c x->T::member
+ ///
+ /// By default, invokes TransformDecl() to transform the declaration.
+ /// Subclasses may override this function to provide alternate behavior.
+ NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
+ return cast_or_null<NamedDecl>(getDerived().TransformDecl(D));
+ }
+
/// \brief Transform the given nested-name-specifier.
///
/// By default, transforms all of the types and declarations within the
@@ -253,7 +273,8 @@ public:
/// Identifiers and selectors are returned unmodified. Sublcasses may
/// override this function to provide alternate behavior.
DeclarationName TransformDeclarationName(DeclarationName Name,
- SourceLocation Loc);
+ SourceLocation Loc,
+ QualType ObjectType = QualType());
/// \brief Transform the given template name.
///
@@ -271,11 +292,15 @@ public:
/// override this function to provide alternate behavior.
TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) \
- QualType Transform##CLASS##Type(const CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
+#include "clang/AST/TypeLocNodes.def"
+ QualType
+ TransformTemplateSpecializationType(const TemplateSpecializationType *T,
+ QualType ObjectType);
+
OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
#define STMT(Node, Parent) \
@@ -316,6 +341,9 @@ public:
/// type. Subclasses may override this routine to provide different behavior.
QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
+ /// \brief Build a new Objective C object pointer type.
+ QualType RebuildObjCObjectPointerType(QualType PointeeType);
+
/// \brief Build a new array type given the element type, size
/// modifier, size of the array (if known), size expression, and index type
/// qualifiers.
@@ -340,29 +368,6 @@ public:
const llvm::APInt &Size,
unsigned IndexTypeQuals);
- /// \brief Build a new constant array type given the element type, size
- /// modifier, (known) size of the array, size expression, and index type
- /// qualifiers.
- ///
- /// By default, performs semantic analysis when building the array type.
- /// Subclasses may override this routine to provide different behavior.
- QualType RebuildConstantArrayWithExprType(QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- Expr *SizeExpr,
- unsigned IndexTypeQuals,
- SourceRange BracketsRange);
-
- /// \brief Build a new constant array type given the element type, size
- /// modifier, (known) size of the array, and index type qualifiers.
- ///
- /// By default, performs semantic analysis when building the array type.
- /// Subclasses may override this routine to provide different behavior.
- QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- unsigned IndexTypeQuals);
-
/// \brief Build a new incomplete array type given the element type, size
/// modifier, and index type qualifiers.
///
@@ -427,6 +432,9 @@ public:
unsigned NumParamTypes,
bool Variadic, unsigned Quals);
+ /// \brief Build a new unprototyped function type.
+ QualType RebuildFunctionNoProtoType(QualType ResultType);
+
/// \brief Build a new typedef type.
QualType RebuildTypedefType(TypedefDecl *Typedef) {
return SemaRef.Context.getTypeDeclType(Typedef);
@@ -1429,13 +1437,16 @@ public:
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildTemplateIdExpr(TemplateName Template,
+ OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TemplateName Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
- return getSema().BuildTemplateIdExpr(Template, TemplateLoc,
+ return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
+ Template, TemplateLoc,
LAngleLoc,
TemplateArgs, NumTemplateArgs,
RAngleLoc);
@@ -1757,7 +1768,8 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
template<typename Derived>
DeclarationName
TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
- SourceLocation Loc) {
+ SourceLocation Loc,
+ QualType ObjectType) {
if (!Name)
return Name;
@@ -1774,7 +1786,14 @@ TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName: {
TemporaryBase Rebase(*this, Loc, Name);
- QualType T = getDerived().TransformType(Name.getCXXNameType());
+ QualType T;
+ if (!ObjectType.isNull() &&
+ isa<TemplateSpecializationType>(Name.getCXXNameType())) {
+ TemplateSpecializationType *SpecType
+ = cast<TemplateSpecializationType>(Name.getCXXNameType());
+ T = TransformTemplateSpecializationType(SpecType, ObjectType);
+ } else
+ T = getDerived().TransformType(Name.getCXXNameType());
if (T.isNull())
return DeclarationName();
@@ -1837,7 +1856,8 @@ TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
return TemplateName();
if (!getDerived().AlwaysRebuild() &&
- NNS == DTN->getQualifier())
+ NNS == DTN->getQualifier() &&
+ ObjectType.isNull())
return Name;
return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
@@ -1935,268 +1955,369 @@ QualType TreeTransform<Derived>::TransformType(QualType T) {
if (getDerived().AlreadyTransformed(T))
return T;
- QualifierCollector Qs;
- const Type *Ty = Qs.strip(T);
+ // Temporary workaround. All of these transformations should
+ // eventually turn into transformations on TypeLocs.
+ DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
+ DI->getTypeLoc().initialize(getDerived().getBaseLocation());
+
+ DeclaratorInfo *NewDI = getDerived().TransformType(DI);
- QualType Result;
- switch (Ty->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) \
- case Type::CLASS: \
- Result = getDerived().Transform##CLASS##Type( \
- static_cast<const CLASS##Type*>(Ty)); \
- break;
-#include "clang/AST/TypeNodes.def"
- }
-
- if (Result.isNull() || T == Result)
- return Result;
+ if (!NewDI)
+ return QualType();
- return getDerived().AddTypeQualifiers(Result, Qs);
+ return NewDI->getType();
}
template<typename Derived>
-QualType
-TreeTransform<Derived>::AddTypeQualifiers(QualType T, Qualifiers Quals) {
- if (!Quals.empty() && !T->isFunctionType() && !T->isReferenceType())
- return SemaRef.Context.getQualifiedType(T, Quals);
+DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
+ if (getDerived().AlreadyTransformed(DI->getType()))
+ return DI;
- return T;
-}
+ TypeLocBuilder TLB;
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformBuiltinType(const BuiltinType *T) {
- // Nothing to do
- return QualType(T, 0);
-}
+ TypeLoc TL = DI->getTypeLoc();
+ TLB.reserve(TL.getFullDataSize());
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformFixedWidthIntType(
- const FixedWidthIntType *T) {
- // FIXME: Implement
- return QualType(T, 0);
-}
+ QualType Result = getDerived().TransformType(TLB, TL);
+ if (Result.isNull())
+ return 0;
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformComplexType(const ComplexType *T) {
- // FIXME: Implement
- return QualType(T, 0);
+ return TLB.getDeclaratorInfo(SemaRef.Context, Result);
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformPointerType(const PointerType *T) {
- QualType PointeeType = getDerived().TransformType(T->getPointeeType());
- if (PointeeType.isNull())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- PointeeType == T->getPointeeType())
- return QualType(T, 0);
+QualType
+TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
+ switch (T.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ case TypeLoc::CLASS: \
+ return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
+#include "clang/AST/TypeLocNodes.def"
+ }
- return getDerived().RebuildPointerType(PointeeType);
+ llvm::llvm_unreachable("unhandled type loc!");
+ return QualType();
}
+/// FIXME: By default, this routine adds type qualifiers only to types
+/// that can have qualifiers, and silently suppresses those qualifiers
+/// that are not permitted (e.g., qualifiers on reference or function
+/// types). This is the right thing for template instantiation, but
+/// probably not for other clients.
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformBlockPointerType(const BlockPointerType *T) {
- QualType PointeeType = getDerived().TransformType(T->getPointeeType());
- if (PointeeType.isNull())
+TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
+ QualifiedTypeLoc T) {
+ Qualifiers Quals = T.getType().getQualifiers();
+
+ QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
+ if (Result.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- PointeeType == T->getPointeeType())
- return QualType(T, 0);
+ // Silently suppress qualifiers if the result type can't be qualified.
+ // FIXME: this is the right thing for template instantiation, but
+ // probably not for other clients.
+ if (Result->isFunctionType() || Result->isReferenceType())
+ return Result;
- return getDerived().RebuildBlockPointerType(PointeeType);
+ Result = SemaRef.Context.getQualifiedType(Result, Quals);
+
+ TLB.push<QualifiedTypeLoc>(Result);
+
+ // No location information to preserve.
+
+ return Result;
+}
+
+template <class TyLoc> static inline
+QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
+ TyLoc NewT = TLB.push<TyLoc>(T.getType());
+ NewT.setNameLoc(T.getNameLoc());
+ return T.getType();
+}
+
+// Ugly metaprogramming macros because I couldn't be bothered to make
+// the equivalent template version work.
+#define TransformPointerLikeType(TypeClass) do { \
+ QualType PointeeType \
+ = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
+ if (PointeeType.isNull()) \
+ return QualType(); \
+ \
+ QualType Result = TL.getType(); \
+ if (getDerived().AlwaysRebuild() || \
+ PointeeType != TL.getPointeeLoc().getType()) { \
+ Result = getDerived().Rebuild##TypeClass(PointeeType); \
+ if (Result.isNull()) \
+ return QualType(); \
+ } \
+ \
+ TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
+ NewT.setSigilLoc(TL.getSigilLoc()); \
+ \
+ return Result; \
+} while(0)
+
+// Reference collapsing forces us to transform reference types
+// differently from the other pointer-like types.
+#define TransformReferenceType(TypeClass) do { \
+ QualType PointeeType \
+ = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
+ if (PointeeType.isNull()) \
+ return QualType(); \
+ \
+ QualType Result = TL.getType(); \
+ if (getDerived().AlwaysRebuild() || \
+ PointeeType != TL.getPointeeLoc().getType()) { \
+ Result = getDerived().Rebuild##TypeClass(PointeeType); \
+ if (Result.isNull()) \
+ return QualType(); \
+ } \
+ \
+ /* Workaround: rebuild doesn't always change the type */ \
+ /* FIXME: avoid losing this location information. */ \
+ if (Result == PointeeType) \
+ return Result; \
+ ReferenceTypeLoc NewTL; \
+ if (isa<LValueReferenceType>(Result)) \
+ NewTL = TLB.push<LValueReferenceTypeLoc>(Result); \
+ else \
+ NewTL = TLB.push<RValueReferenceTypeLoc>(Result); \
+ NewTL.setSigilLoc(TL.getSigilLoc()); \
+ return Result; \
+} while (0)
+
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
+ BuiltinTypeLoc T) {
+ return TransformTypeSpecType(TLB, T);
}
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformLValueReferenceType(
- const LValueReferenceType *T) {
- QualType PointeeType = getDerived().TransformType(T->getPointeeType());
- if (PointeeType.isNull())
- return QualType();
+TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
+ FixedWidthIntTypeLoc T) {
+ return TransformTypeSpecType(TLB, T);
+}
- if (!getDerived().AlwaysRebuild() &&
- PointeeType == T->getPointeeType())
- return QualType(T, 0);
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
+ ComplexTypeLoc T) {
+ // FIXME: recurse?
+ return TransformTypeSpecType(TLB, T);
+}
- return getDerived().RebuildLValueReferenceType(PointeeType);
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
+ PointerTypeLoc TL) {
+ TransformPointerLikeType(PointerType);
}
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformRValueReferenceType(
- const RValueReferenceType *T) {
- QualType PointeeType = getDerived().TransformType(T->getPointeeType());
- if (PointeeType.isNull())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- PointeeType == T->getPointeeType())
- return QualType(T, 0);
-
- return getDerived().RebuildRValueReferenceType(PointeeType);
+TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
+ BlockPointerTypeLoc TL) {
+ TransformPointerLikeType(BlockPointerType);
}
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformMemberPointerType(const MemberPointerType *T) {
- QualType PointeeType = getDerived().TransformType(T->getPointeeType());
- if (PointeeType.isNull())
- return QualType();
-
- QualType ClassType = getDerived().TransformType(QualType(T->getClass(), 0));
- if (ClassType.isNull())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- PointeeType == T->getPointeeType() &&
- ClassType == QualType(T->getClass(), 0))
- return QualType(T, 0);
-
- return getDerived().RebuildMemberPointerType(PointeeType, ClassType);
+TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
+ LValueReferenceTypeLoc TL) {
+ TransformReferenceType(LValueReferenceType);
}
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformConstantArrayType(const ConstantArrayType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
- if (ElementType.isNull())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType())
- return QualType(T, 0);
-
- return getDerived().RebuildConstantArrayType(ElementType,
- T->getSizeModifier(),
- T->getSize(),
- T->getIndexTypeCVRQualifiers());
+TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
+ RValueReferenceTypeLoc TL) {
+ TransformReferenceType(RValueReferenceType);
}
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformConstantArrayWithExprType(
- const ConstantArrayWithExprType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
- if (ElementType.isNull())
- return QualType();
+TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
+ MemberPointerTypeLoc TL) {
+ MemberPointerType *T = TL.getTypePtr();
- // Array bounds are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
+ if (PointeeType.isNull())
+ return QualType();
- Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
- if (Size.isInvalid())
+ // TODO: preserve source information for this.
+ QualType ClassType
+ = getDerived().TransformType(QualType(T->getClass(), 0));
+ if (ClassType.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType() &&
- Size.get() == T->getSizeExpr())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ PointeeType != T->getPointeeType() ||
+ ClassType != QualType(T->getClass(), 0)) {
+ Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType);
+ if (Result.isNull())
+ return QualType();
+ }
- return getDerived().RebuildConstantArrayWithExprType(ElementType,
- T->getSizeModifier(),
- T->getSize(),
- Size.takeAs<Expr>(),
- T->getIndexTypeCVRQualifiers(),
- T->getBracketsRange());
+ MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
+ NewTL.setSigilLoc(TL.getSigilLoc());
+
+ return Result;
}
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
- const ConstantArrayWithoutExprType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
+TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
+ ConstantArrayTypeLoc TL) {
+ ConstantArrayType *T = TL.getTypePtr();
+ QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType())
- return QualType(T, 0);
-
- return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
- T->getSizeModifier(),
- T->getSize(),
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ElementType != T->getElementType()) {
+ Result = getDerived().RebuildConstantArrayType(ElementType,
+ T->getSizeModifier(),
+ T->getSize(),
T->getIndexTypeCVRQualifiers());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
+ NewTL.setLBracketLoc(TL.getLBracketLoc());
+ NewTL.setRBracketLoc(TL.getRBracketLoc());
+
+ Expr *Size = TL.getSizeExpr();
+ if (Size) {
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
+ }
+ NewTL.setSizeExpr(Size);
+
+ return Result;
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformIncompleteArrayType(
- const IncompleteArrayType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
+ TypeLocBuilder &TLB,
+ IncompleteArrayTypeLoc TL) {
+ IncompleteArrayType *T = TL.getTypePtr();
+ QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ElementType != T->getElementType()) {
+ Result = getDerived().RebuildIncompleteArrayType(ElementType,
+ T->getSizeModifier(),
+ T->getIndexTypeCVRQualifiers());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
+ NewTL.setLBracketLoc(TL.getLBracketLoc());
+ NewTL.setRBracketLoc(TL.getRBracketLoc());
+ NewTL.setSizeExpr(0);
- return getDerived().RebuildIncompleteArrayType(ElementType,
- T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers());
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformVariableArrayType(
- const VariableArrayType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
+QualType
+TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
+ VariableArrayTypeLoc TL) {
+ VariableArrayType *T = TL.getTypePtr();
+ QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
return QualType();
// Array bounds are not potentially evaluated contexts
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
- Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
- if (Size.isInvalid())
+ Sema::OwningExprResult SizeResult
+ = getDerived().TransformExpr(T->getSizeExpr());
+ if (SizeResult.isInvalid())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType() &&
- Size.get() == T->getSizeExpr()) {
- Size.take();
- return QualType(T, 0);
+ Expr *Size = static_cast<Expr*>(SizeResult.get());
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ElementType != T->getElementType() ||
+ Size != T->getSizeExpr()) {
+ Result = getDerived().RebuildVariableArrayType(ElementType,
+ T->getSizeModifier(),
+ move(SizeResult),
+ T->getIndexTypeCVRQualifiers(),
+ T->getBracketsRange());
+ if (Result.isNull())
+ return QualType();
}
+ else SizeResult.take();
+
+ VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
+ NewTL.setLBracketLoc(TL.getLBracketLoc());
+ NewTL.setRBracketLoc(TL.getRBracketLoc());
+ NewTL.setSizeExpr(Size);
- return getDerived().RebuildVariableArrayType(ElementType,
- T->getSizeModifier(),
- move(Size),
- T->getIndexTypeCVRQualifiers(),
- T->getBracketsRange());
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformDependentSizedArrayType(
- const DependentSizedArrayType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
+QualType
+TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
+ DependentSizedArrayTypeLoc TL) {
+ DependentSizedArrayType *T = TL.getTypePtr();
+ QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
return QualType();
// Array bounds are not potentially evaluated contexts
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
- Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
- if (Size.isInvalid())
+ Sema::OwningExprResult SizeResult
+ = getDerived().TransformExpr(T->getSizeExpr());
+ if (SizeResult.isInvalid())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType() &&
- Size.get() == T->getSizeExpr()) {
- Size.take();
- return QualType(T, 0);
+ Expr *Size = static_cast<Expr*>(SizeResult.get());
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ElementType != T->getElementType() ||
+ Size != T->getSizeExpr()) {
+ Result = getDerived().RebuildDependentSizedArrayType(ElementType,
+ T->getSizeModifier(),
+ move(SizeResult),
+ T->getIndexTypeCVRQualifiers(),
+ T->getBracketsRange());
+ if (Result.isNull())
+ return QualType();
}
+ else SizeResult.take();
- return getDerived().RebuildDependentSizedArrayType(ElementType,
- T->getSizeModifier(),
- move(Size),
- T->getIndexTypeCVRQualifiers(),
- T->getBracketsRange());
+ // We might have any sort of array type now, but fortunately they
+ // all have the same location layout.
+ ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
+ NewTL.setLBracketLoc(TL.getLBracketLoc());
+ NewTL.setRBracketLoc(TL.getRBracketLoc());
+ NewTL.setSizeExpr(Size);
+
+ return Result;
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
- const DependentSizedExtVectorType *T) {
+ TypeLocBuilder &TLB,
+ DependentSizedExtVectorTypeLoc TL) {
+ DependentSizedExtVectorType *T = TL.getTypePtr();
+
+ // FIXME: ext vector locs should be nested
QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull())
return QualType();
@@ -2208,98 +2329,201 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
if (Size.isInvalid())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType() &&
- Size.get() == T->getSizeExpr()) {
- Size.take();
- return QualType(T, 0);
- }
-
- return getDerived().RebuildDependentSizedExtVectorType(ElementType,
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ (ElementType != T->getElementType() && Size.get() != T->getSizeExpr())) {
+ Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
move(Size),
T->getAttributeLoc());
+ if (Result.isNull())
+ return QualType();
+ }
+ else Size.take();
+
+ // Result might be dependent or not.
+ if (isa<DependentSizedExtVectorType>(Result)) {
+ DependentSizedExtVectorTypeLoc NewTL
+ = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+ } else {
+ ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+ }
+
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformVectorType(const VectorType *T) {
+QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
+ VectorTypeLoc TL) {
+ VectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ElementType != T->getElementType()) {
+ Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildVectorType(ElementType, T->getNumElements());
+ return Result;
}
template<typename Derived>
-QualType
-TreeTransform<Derived>::TransformExtVectorType(const ExtVectorType *T) {
+QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
+ ExtVectorTypeLoc TL) {
+ VectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ElementType != T->getElementType()) {
+ Result = getDerived().RebuildExtVectorType(ElementType,
+ T->getNumElements(),
+ /*FIXME*/ SourceLocation());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildExtVectorType(ElementType, T->getNumElements(),
- /*FIXME*/SourceLocation());
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformFunctionProtoType(
- const FunctionProtoType *T) {
- QualType ResultType = getDerived().TransformType(T->getResultType());
+QualType
+TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
+ FunctionProtoTypeLoc TL) {
+ FunctionProtoType *T = TL.getTypePtr();
+ QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
if (ResultType.isNull())
return QualType();
+ // Transform the parameters.
llvm::SmallVector<QualType, 4> ParamTypes;
- for (FunctionProtoType::arg_type_iterator Param = T->arg_type_begin(),
- ParamEnd = T->arg_type_end();
- Param != ParamEnd; ++Param) {
- QualType P = getDerived().TransformType(*Param);
- if (P.isNull())
- return QualType();
+ llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+ ParmVarDecl *OldParm = TL.getArg(i);
+
+ QualType NewType;
+ ParmVarDecl *NewParm;
+
+ if (OldParm) {
+ DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
+ assert(OldDI->getType() == T->getArgType(i));
+
+ DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
+ if (!NewDI)
+ return QualType();
+
+ if (NewDI == OldDI)
+ NewParm = OldParm;
+ else
+ NewParm = ParmVarDecl::Create(SemaRef.Context,
+ OldParm->getDeclContext(),
+ OldParm->getLocation(),
+ OldParm->getIdentifier(),
+ NewDI->getType(),
+ NewDI,
+ OldParm->getStorageClass(),
+ /* DefArg */ NULL);
+ NewType = NewParm->getType();
+
+ // Deal with the possibility that we don't have a parameter
+ // declaration for this parameter.
+ } else {
+ NewParm = 0;
+
+ QualType OldType = T->getArgType(i);
+ NewType = getDerived().TransformType(OldType);
+ if (NewType.isNull())
+ return QualType();
+ }
- ParamTypes.push_back(P);
+ ParamTypes.push_back(NewType);
+ ParamDecls.push_back(NewParm);
}
- if (!getDerived().AlwaysRebuild() &&
- ResultType == T->getResultType() &&
- std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin()))
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ResultType != T->getResultType() ||
+ !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
+ Result = getDerived().RebuildFunctionProtoType(ResultType,
+ ParamTypes.data(),
+ ParamTypes.size(),
+ T->isVariadic(),
+ T->getTypeQuals());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
+ NewTL.setLParenLoc(TL.getLParenLoc());
+ NewTL.setRParenLoc(TL.getRParenLoc());
+ for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
+ NewTL.setArg(i, ParamDecls[i]);
- return getDerived().RebuildFunctionProtoType(ResultType, ParamTypes.data(),
- ParamTypes.size(), T->isVariadic(),
- T->getTypeQuals());
+ return Result;
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
- const FunctionNoProtoType *T) {
- // FIXME: Implement
- return QualType(T, 0);
+ TypeLocBuilder &TLB,
+ FunctionNoProtoTypeLoc TL) {
+ FunctionNoProtoType *T = TL.getTypePtr();
+ QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
+ if (ResultType.isNull())
+ return QualType();
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ ResultType != T->getResultType())
+ Result = getDerived().RebuildFunctionNoProtoType(ResultType);
+
+ FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
+ NewTL.setLParenLoc(TL.getLParenLoc());
+ NewTL.setRParenLoc(TL.getRParenLoc());
+
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformTypedefType(const TypedefType *T) {
+QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
+ TypedefTypeLoc TL) {
+ TypedefType *T = TL.getTypePtr();
TypedefDecl *Typedef
= cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
if (!Typedef)
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- Typedef == T->getDecl())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Typedef != T->getDecl()) {
+ Result = getDerived().RebuildTypedefType(Typedef);
+ if (Result.isNull())
+ return QualType();
+ }
+
+ TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildTypedefType(Typedef);
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformTypeOfExprType(
- const TypeOfExprType *T) {
+QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
+ TypeOfExprTypeLoc TL) {
+ TypeOfExprType *T = TL.getTypePtr();
+
// typeof expressions are not potentially evaluated contexts
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
@@ -2307,30 +2531,50 @@ QualType TreeTransform<Derived>::TransformTypeOfExprType(
if (E.isInvalid())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- E.get() == T->getUnderlyingExpr()) {
- E.take();
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ E.get() != T->getUnderlyingExpr()) {
+ Result = getDerived().RebuildTypeOfExprType(move(E));
+ if (Result.isNull())
+ return QualType();
}
+ else E.take();
- return getDerived().RebuildTypeOfExprType(move(E));
+ TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformTypeOfType(const TypeOfType *T) {
+QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
+ TypeOfTypeLoc TL) {
+ TypeOfType *T = TL.getTypePtr();
+
+ // FIXME: should be an inner type, or at least have a DeclaratorInfo.
QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
if (Underlying.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- Underlying == T->getUnderlyingType())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Underlying != T->getUnderlyingType()) {
+ Result = getDerived().RebuildTypeOfType(Underlying);
+ if (Result.isNull())
+ return QualType();
+ }
- return getDerived().RebuildTypeOfType(Underlying);
+ TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
+QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
+ DecltypeTypeLoc TL) {
+ DecltypeType *T = TL.getTypePtr();
+
// decltype expressions are not potentially evaluated contexts
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
@@ -2338,70 +2582,130 @@ QualType TreeTransform<Derived>::TransformDecltypeType(const DecltypeType *T) {
if (E.isInvalid())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- E.get() == T->getUnderlyingExpr()) {
- E.take();
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ E.get() != T->getUnderlyingExpr()) {
+ Result = getDerived().RebuildDecltypeType(move(E));
+ if (Result.isNull())
+ return QualType();
}
+ else E.take();
- return getDerived().RebuildDecltypeType(move(E));
+ DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformRecordType(const RecordType *T) {
+QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
+ RecordTypeLoc TL) {
+ RecordType *T = TL.getTypePtr();
RecordDecl *Record
- = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
+ = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
if (!Record)
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- Record == T->getDecl())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Record != T->getDecl()) {
+ Result = getDerived().RebuildRecordType(Record);
+ if (Result.isNull())
+ return QualType();
+ }
+
+ RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildRecordType(Record);
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) {
+QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
+ EnumTypeLoc TL) {
+ EnumType *T = TL.getTypePtr();
EnumDecl *Enum
- = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
+ = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
if (!Enum)
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- Enum == T->getDecl())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Enum != T->getDecl()) {
+ Result = getDerived().RebuildEnumType(Enum);
+ if (Result.isNull())
+ return QualType();
+ }
+
+ EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildEnumType(Enum);
+ return Result;
}
template <typename Derived>
-QualType TreeTransform<Derived>::TransformElaboratedType(
- const ElaboratedType *T) {
+QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
+ ElaboratedTypeLoc TL) {
+ ElaboratedType *T = TL.getTypePtr();
+
+ // FIXME: this should be a nested type.
QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
if (Underlying.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- Underlying == T->getUnderlyingType())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ Underlying != T->getUnderlyingType()) {
+ Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
+ return Result;
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
- const TemplateTypeParmType *T) {
- // Nothing to do
- return QualType(T, 0);
+ TypeLocBuilder &TLB,
+ TemplateTypeParmTypeLoc TL) {
+ return TransformTypeSpecType(TLB, TL);
}
template<typename Derived>
+QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
+ TypeLocBuilder &TLB,
+ SubstTemplateTypeParmTypeLoc TL) {
+ return TransformTypeSpecType(TLB, TL);
+}
+
+template<typename Derived>
+inline QualType
+TreeTransform<Derived>::TransformTemplateSpecializationType(
+ TypeLocBuilder &TLB,
+ TemplateSpecializationTypeLoc TL) {
+ // TODO: figure out how make this work with an ObjectType.
+ QualType Result
+ = TransformTemplateSpecializationType(TL.getTypePtr(), QualType());
+ if (Result.isNull())
+ return QualType();
+
+ TemplateSpecializationTypeLoc NewTL
+ = TLB.push<TemplateSpecializationTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+
+ return Result;
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
- const TemplateSpecializationType *T) {
+ const TemplateSpecializationType *T,
+ QualType ObjectType) {
TemplateName Template
- = getDerived().TransformTemplateName(T->getTemplateName());
+ = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
if (Template.isNull())
return QualType();
@@ -2426,8 +2730,10 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformQualifiedNameType(
- const QualifiedNameType *T) {
+QualType
+TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
+ QualifiedNameTypeLoc TL) {
+ QualifiedNameType *T = TL.getTypePtr();
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(),
SourceRange());
@@ -2438,22 +2744,33 @@ QualType TreeTransform<Derived>::TransformQualifiedNameType(
if (Named.isNull())
return QualType();
- if (!getDerived().AlwaysRebuild() &&
- NNS == T->getQualifier() &&
- Named == T->getNamedType())
- return QualType(T, 0);
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ NNS != T->getQualifier() ||
+ Named != T->getNamedType()) {
+ Result = getDerived().RebuildQualifiedNameType(NNS, Named);
+ if (Result.isNull())
+ return QualType();
+ }
+
+ QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
- return getDerived().RebuildQualifiedNameType(NNS, Named);
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
+QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
+ TypenameTypeLoc TL) {
+ TypenameType *T = TL.getTypePtr();
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(),
SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
if (!NNS)
return QualType();
+ QualType Result;
+
if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
QualType NewTemplateId
= getDerived().TransformType(QualType(TemplateId, 0));
@@ -2465,31 +2782,33 @@ QualType TreeTransform<Derived>::TransformTypenameType(const TypenameType *T) {
NewTemplateId == QualType(TemplateId, 0))
return QualType(T, 0);
- return getDerived().RebuildTypenameType(NNS, NewTemplateId);
+ Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
+ } else {
+ Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier());
}
+ if (Result.isNull())
+ return QualType();
- return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
-}
+ TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformObjCInterfaceType(
- const ObjCInterfaceType *T) {
- // FIXME: Implement
- return QualType(T, 0);
+ return Result;
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
- const ObjCObjectPointerType *T) {
- // FIXME: Implement
- return QualType(T, 0);
+QualType
+TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
+ ObjCInterfaceTypeLoc TL) {
+ assert(false && "TransformObjCInterfaceType unimplemented");
+ return QualType();
}
template<typename Derived>
-QualType TreeTransform<Derived>::TransformObjCProtocolListType(
- const ObjCProtocolListType *T) {
- assert(false && "Should not see ObjCProtocolList types");
- return QualType(T, 0);
+QualType
+TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
+ ObjCObjectPointerTypeLoc TL) {
+ assert(false && "TransformObjCObjectPointerType unimplemented");
+ return QualType();
}
//===----------------------------------------------------------------------===//
@@ -4010,8 +4329,8 @@ Sema::OwningExprResult
TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
UnresolvedDeclRefExpr *E) {
NestedNameSpecifier *NNS
- = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
- E->getQualifierRange());
+ = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
if (!NNS)
return SemaRef.ExprError();
@@ -4040,6 +4359,14 @@ TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
if (Template.isNull())
return SemaRef.ExprError();
+ NestedNameSpecifier *Qualifier = 0;
+ if (E->getQualifier()) {
+ Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (!Qualifier)
+ return SemaRef.ExprError();
+ }
+
llvm::SmallVector<TemplateArgument, 4> TransArgs;
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
TemplateArgument TransArg
@@ -4056,7 +4383,8 @@ TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
// FIXME: It's possible that we'll find out now that the template name
// actually refers to a type, in which case the caller is actually dealing
// with a functional cast. Give a reasonable error message!
- return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
+ return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
+ Template, E->getTemplateNameLoc(),
E->getLAngleLoc(),
TransArgs.data(),
TransArgs.size(),
@@ -4235,6 +4563,7 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
if (Base.isInvalid())
return SemaRef.ExprError();
+ // Start the member reference and compute the object's type.
Sema::TypeTy *ObjectType = 0;
Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
E->getOperatorLoc(),
@@ -4243,12 +4572,12 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
if (Base.isInvalid())
return SemaRef.ExprError();
- // FIXME: The first qualifier found might be a template type parameter,
- // in which case there is no transformed declaration to refer to (it might
- // refer to a built-in type!).
+ // Transform the first part of the nested-name-specifier that qualifies
+ // the member name.
NamedDecl *FirstQualifierInScope
- = cast_or_null<NamedDecl>(
- getDerived().TransformDecl(E->getFirstQualifierFoundInScope()));
+ = getDerived().TransformFirstQualifierInScope(
+ E->getFirstQualifierFoundInScope(),
+ E->getQualifierRange().getBegin());
NestedNameSpecifier *Qualifier = 0;
if (E->getQualifier()) {
@@ -4261,7 +4590,8 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
}
DeclarationName Name
- = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc());
+ = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
+ QualType::getFromOpaquePtr(ObjectType));
if (!Name)
return SemaRef.ExprError();
@@ -4504,6 +4834,14 @@ QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
template<typename Derived>
QualType
+TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType) {
+ return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
+ getDerived().getBaseLocation(),
+ getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType
TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
const llvm::APInt *Size,
@@ -4549,29 +4887,6 @@ TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
template<typename Derived>
QualType
-TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- Expr *SizeExpr,
- unsigned IndexTypeQuals,
- SourceRange BracketsRange) {
- return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
- IndexTypeQuals, BracketsRange);
-}
-
-template<typename Derived>
-QualType
-TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
- QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- unsigned IndexTypeQuals) {
- return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
- IndexTypeQuals, SourceRange());
-}
-
-template<typename Derived>
-QualType
TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
unsigned IndexTypeQuals) {
@@ -4644,6 +4959,11 @@ QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
}
template<typename Derived>
+QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
+ return SemaRef.Context.getFunctionNoProtoType(T);
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
}