Replace one hack with a different hack: strip out the ObjectType

parameters to the Transform*Type functions and instead call out
the specific cases where an object type and the unqualified lookup
results are important.  Fixes an assert and failed compile on
a testcase from PR7248.

llvm-svn: 118887
This commit is contained in:
John McCall 2010-11-12 08:19:04 +00:00
parent d41071329d
commit 31f82720d0
3 changed files with 262 additions and 211 deletions

View File

@ -629,15 +629,13 @@ namespace {
NonTypeTemplateParmDecl *D); NonTypeTemplateParmDecl *D);
QualType TransformFunctionProtoType(TypeLocBuilder &TLB, QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL, FunctionProtoTypeLoc TL);
QualType ObjectType);
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm); ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm);
/// \brief Transforms a template type parameter type by performing /// \brief Transforms a template type parameter type by performing
/// substitution of the corresponding template type argument. /// substitution of the corresponding template type argument.
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB, QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
TemplateTypeParmTypeLoc TL, TemplateTypeParmTypeLoc TL);
QualType ObjectType);
ExprResult TransformCallExpr(CallExpr *CE) { ExprResult TransformCallExpr(CallExpr *CE) {
getSema().CallsUndergoingInstantiation.push_back(CE); getSema().CallsUndergoingInstantiation.push_back(CE);
@ -869,11 +867,10 @@ ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
} }
QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL, FunctionProtoTypeLoc TL) {
QualType ObjectType) {
// We need a local instantiation scope for this function prototype. // We need a local instantiation scope for this function prototype.
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
return inherited::TransformFunctionProtoType(TLB, TL, ObjectType); return inherited::TransformFunctionProtoType(TLB, TL);
} }
ParmVarDecl * ParmVarDecl *
@ -883,8 +880,7 @@ TemplateInstantiator::TransformFunctionTypeParam(ParmVarDecl *OldParm) {
QualType QualType
TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
TemplateTypeParmTypeLoc TL, TemplateTypeParmTypeLoc TL) {
QualType ObjectType) {
TemplateTypeParmType *T = TL.getTypePtr(); TemplateTypeParmType *T = TL.getTypePtr();
if (T->getDepth() < TemplateArgs.getNumLevels()) { if (T->getDepth() < TemplateArgs.getNumLevels()) {
// Replace the template type parameter with its corresponding // Replace the template type parameter with its corresponding
@ -1035,7 +1031,7 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
TypeLoc TL = T->getTypeLoc(); TypeLoc TL = T->getTypeLoc();
TLB.reserve(TL.getFullDataSize()); TLB.reserve(TL.getFullDataSize());
QualType Result = Instantiator.TransformType(TLB, TL, QualType()); QualType Result = Instantiator.TransformType(TLB, TL);
if (Result.isNull()) if (Result.isNull())
return 0; return 0;

View File

@ -189,7 +189,7 @@ public:
/// switched to storing TypeSourceInfos. /// switched to storing TypeSourceInfos.
/// ///
/// \returns the transformed type. /// \returns the transformed type.
QualType TransformType(QualType T, QualType ObjectType = QualType()); QualType TransformType(QualType T);
/// \brief Transforms the given type-with-location into a new /// \brief Transforms the given type-with-location into a new
/// type-with-location. /// type-with-location.
@ -199,15 +199,13 @@ public:
/// may override this function (to take over all type /// may override this function (to take over all type
/// transformations) or some set of the TransformXXXType functions /// transformations) or some set of the TransformXXXType functions
/// to alter the transformation. /// to alter the transformation.
TypeSourceInfo *TransformType(TypeSourceInfo *DI, TypeSourceInfo *TransformType(TypeSourceInfo *DI);
QualType ObjectType = QualType());
/// \brief Transform the given type-with-location into a new /// \brief Transform the given type-with-location into a new
/// type, collecting location information in the given builder /// type, collecting location information in the given builder
/// as necessary. /// as necessary.
/// ///
QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL, QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
QualType ObjectType = QualType());
/// \brief Transform the given statement. /// \brief Transform the given statement.
/// ///
@ -275,8 +273,7 @@ public:
/// Identifiers and selectors are returned unmodified. Sublcasses may /// Identifiers and selectors are returned unmodified. Sublcasses may
/// override this function to provide alternate behavior. /// override this function to provide alternate behavior.
DeclarationNameInfo DeclarationNameInfo
TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo, TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
QualType ObjectType = QualType());
/// \brief Transform the given template name. /// \brief Transform the given template name.
/// ///
@ -284,7 +281,8 @@ public:
/// and nested-name-specifiers that occur within the template name. /// and nested-name-specifiers that occur within the template name.
/// Subclasses may override this function to provide alternate behavior. /// Subclasses may override this function to provide alternate behavior.
TemplateName TransformTemplateName(TemplateName Name, TemplateName TransformTemplateName(TemplateName Name,
QualType ObjectType = QualType()); QualType ObjectType = QualType(),
NamedDecl *FirstQualifierInScope = 0);
/// \brief Transform the given template argument. /// \brief Transform the given template argument.
/// ///
@ -309,10 +307,19 @@ public:
#define ABSTRACT_TYPELOC(CLASS, PARENT) #define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \ #define TYPELOC(CLASS, PARENT) \
QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T, \ QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
QualType ObjectType = QualType());
#include "clang/AST/TypeLocNodes.def" #include "clang/AST/TypeLocNodes.def"
QualType
TransformTemplateSpecializationType(TypeLocBuilder &TLB,
TemplateSpecializationTypeLoc TL,
TemplateName Template);
QualType
TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
DependentTemplateSpecializationTypeLoc TL,
NestedNameSpecifier *Prefix);
/// \brief Transforms the parameters of a function type into the /// \brief Transforms the parameters of a function type into the
/// given vectors. /// given vectors.
/// ///
@ -328,12 +335,7 @@ public:
/// on error. /// on error.
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm); ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm);
QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL, QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
QualType ObjectType);
QualType
TransformTemplateSpecializationType(const TemplateSpecializationType *T,
QualType ObjectType);
StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr); StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E); ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
@ -544,7 +546,7 @@ public:
// TODO: avoid TemplateName abstraction // TODO: avoid TemplateName abstraction
TemplateName InstName = TemplateName InstName =
getDerived().RebuildTemplateName(Qualifier, QualifierRange, *Name, getDerived().RebuildTemplateName(Qualifier, QualifierRange, *Name,
QualType()); QualType(), 0);
if (InstName.isNull()) if (InstName.isNull())
return QualType(); return QualType();
@ -694,7 +696,8 @@ public:
TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier, TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, SourceRange QualifierRange,
const IdentifierInfo &II, const IdentifierInfo &II,
QualType ObjectType); QualType ObjectType,
NamedDecl *FirstQualifierInScope);
/// \brief Build a new template name given a nested name specifier and the /// \brief Build a new template name given a nested name specifier and the
/// overloaded operator name that is referred to as a template. /// overloaded operator name that is referred to as a template.
@ -1978,6 +1981,17 @@ public:
OwnedCall.release(); OwnedCall.release();
return move(Result); return move(Result);
} }
private:
QualType TransformTypeInObjectScope(QualType T,
QualType ObjectType,
NamedDecl *FirstQualifierInScope,
NestedNameSpecifier *Prefix);
TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *T,
QualType ObjectType,
NamedDecl *FirstQualifierInScope,
NestedNameSpecifier *Prefix);
}; };
template<typename Derived> template<typename Derived>
@ -2035,26 +2049,26 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range, SourceRange Range,
QualType ObjectType, QualType ObjectType,
NamedDecl *FirstQualifierInScope) { NamedDecl *FirstQualifierInScope) {
if (!NNS) NestedNameSpecifier *Prefix = NNS->getPrefix();
return 0;
// Transform the prefix of this nested name specifier. // Transform the prefix of this nested name specifier.
NestedNameSpecifier *Prefix = NNS->getPrefix();
if (Prefix) { if (Prefix) {
Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range, Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
ObjectType, ObjectType,
FirstQualifierInScope); FirstQualifierInScope);
if (!Prefix) if (!Prefix)
return 0; return 0;
// Clear out the object type and the first qualifier in scope; they only
// apply to the first element in the nested-name-specifier.
ObjectType = QualType();
FirstQualifierInScope = 0;
} }
switch (NNS->getKind()) { switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier: case NestedNameSpecifier::Identifier:
if (Prefix) {
// The object type and qualifier-in-scope really apply to the
// leftmost entity.
ObjectType = QualType();
FirstQualifierInScope = 0;
}
assert((Prefix || !ObjectType.isNull()) && assert((Prefix || !ObjectType.isNull()) &&
"Identifier nested-name-specifier with no prefix or object type"); "Identifier nested-name-specifier with no prefix or object type");
if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() && if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
@ -2087,8 +2101,10 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
case NestedNameSpecifier::TypeSpecWithTemplate: case NestedNameSpecifier::TypeSpecWithTemplate:
case NestedNameSpecifier::TypeSpec: { case NestedNameSpecifier::TypeSpec: {
TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName()); TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0), QualType T = TransformTypeInObjectScope(QualType(NNS->getAsType(), 0),
ObjectType); ObjectType,
FirstQualifierInScope,
Prefix);
if (T.isNull()) if (T.isNull())
return 0; return 0;
@ -2110,8 +2126,7 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
template<typename Derived> template<typename Derived>
DeclarationNameInfo DeclarationNameInfo
TreeTransform<Derived> TreeTransform<Derived>
::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo, ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
QualType ObjectType) {
DeclarationName Name = NameInfo.getName(); DeclarationName Name = NameInfo.getName();
if (!Name) if (!Name)
return DeclarationNameInfo(); return DeclarationNameInfo();
@ -2132,16 +2147,15 @@ TreeTransform<Derived>
TypeSourceInfo *NewTInfo; TypeSourceInfo *NewTInfo;
CanQualType NewCanTy; CanQualType NewCanTy;
if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) { if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
NewTInfo = getDerived().TransformType(OldTInfo, ObjectType); NewTInfo = getDerived().TransformType(OldTInfo);
if (!NewTInfo) if (!NewTInfo)
return DeclarationNameInfo(); return DeclarationNameInfo();
NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType()); NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
} }
else { else {
NewTInfo = 0; NewTInfo = 0;
TemporaryBase Rebase(*this, NameInfo.getLoc(), Name); TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
QualType NewT = getDerived().TransformType(Name.getCXXNameType(), QualType NewT = getDerived().TransformType(Name.getCXXNameType());
ObjectType);
if (NewT.isNull()) if (NewT.isNull())
return DeclarationNameInfo(); return DeclarationNameInfo();
NewCanTy = SemaRef.Context.getCanonicalType(NewT); NewCanTy = SemaRef.Context.getCanonicalType(NewT);
@ -2164,14 +2178,16 @@ TreeTransform<Derived>
template<typename Derived> template<typename Derived>
TemplateName TemplateName
TreeTransform<Derived>::TransformTemplateName(TemplateName Name, TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
QualType ObjectType) { QualType ObjectType,
NamedDecl *FirstQualifierInScope) {
SourceLocation Loc = getDerived().getBaseLocation(); SourceLocation Loc = getDerived().getBaseLocation();
if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(QTN->getQualifier(), = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
/*FIXME:*/SourceRange(getDerived().getBaseLocation()), /*FIXME*/ SourceRange(Loc),
ObjectType); ObjectType,
FirstQualifierInScope);
if (!NNS) if (!NNS)
return TemplateName(); return TemplateName();
@ -2191,16 +2207,22 @@ TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
} }
// These should be getting filtered out before they make it into the AST. // These should be getting filtered out before they make it into the AST.
assert(false && "overloaded template name survived to here"); llvm_unreachable("overloaded template name survived to here");
} }
if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
NestedNameSpecifier *NNS NestedNameSpecifier *NNS = DTN->getQualifier();
= getDerived().TransformNestedNameSpecifier(DTN->getQualifier(), if (NNS) {
/*FIXME:*/SourceRange(getDerived().getBaseLocation()), NNS = getDerived().TransformNestedNameSpecifier(NNS,
ObjectType); /*FIXME:*/SourceRange(Loc),
if (!NNS && DTN->getQualifier()) ObjectType,
return TemplateName(); FirstQualifierInScope);
if (!NNS) return TemplateName();
// These apply to the scope specifier, not the template.
ObjectType = QualType();
FirstQualifierInScope = 0;
}
if (!getDerived().AlwaysRebuild() && if (!getDerived().AlwaysRebuild() &&
NNS == DTN->getQualifier() && NNS == DTN->getQualifier() &&
@ -2212,7 +2234,8 @@ TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
SourceRange QualifierRange(getDerived().getBaseLocation()); SourceRange QualifierRange(getDerived().getBaseLocation());
return getDerived().RebuildTemplateName(NNS, QualifierRange, return getDerived().RebuildTemplateName(NNS, QualifierRange,
*DTN->getIdentifier(), *DTN->getIdentifier(),
ObjectType); ObjectType,
FirstQualifierInScope);
} }
return getDerived().RebuildTemplateName(NNS, DTN->getOperator(), return getDerived().RebuildTemplateName(NNS, DTN->getOperator(),
@ -2233,7 +2256,7 @@ TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
} }
// These should be getting filtered out before they reach the AST. // These should be getting filtered out before they reach the AST.
assert(false && "overloaded function decl survived to here"); llvm_unreachable("overloaded function decl survived to here");
return TemplateName(); return TemplateName();
} }
@ -2380,8 +2403,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformType(QualType T, QualType TreeTransform<Derived>::TransformType(QualType T) {
QualType ObjectType) {
if (getDerived().AlreadyTransformed(T)) if (getDerived().AlreadyTransformed(T))
return T; return T;
@ -2390,7 +2412,7 @@ QualType TreeTransform<Derived>::TransformType(QualType T,
TypeSourceInfo *DI = getSema().Context.CreateTypeSourceInfo(T); TypeSourceInfo *DI = getSema().Context.CreateTypeSourceInfo(T);
DI->getTypeLoc().initialize(getDerived().getBaseLocation()); DI->getTypeLoc().initialize(getDerived().getBaseLocation());
TypeSourceInfo *NewDI = getDerived().TransformType(DI, ObjectType); TypeSourceInfo *NewDI = getDerived().TransformType(DI);
if (!NewDI) if (!NewDI)
return QualType(); return QualType();
@ -2399,8 +2421,7 @@ QualType TreeTransform<Derived>::TransformType(QualType T,
} }
template<typename Derived> template<typename Derived>
TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI, TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
QualType ObjectType) {
if (getDerived().AlreadyTransformed(DI->getType())) if (getDerived().AlreadyTransformed(DI->getType()))
return DI; return DI;
@ -2409,7 +2430,7 @@ TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI,
TypeLoc TL = DI->getTypeLoc(); TypeLoc TL = DI->getTypeLoc();
TLB.reserve(TL.getFullDataSize()); TLB.reserve(TL.getFullDataSize());
QualType Result = getDerived().TransformType(TLB, TL, ObjectType); QualType Result = getDerived().TransformType(TLB, TL);
if (Result.isNull()) if (Result.isNull())
return 0; return 0;
@ -2418,14 +2439,12 @@ TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T, TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
QualType ObjectType) {
switch (T.getTypeLocClass()) { switch (T.getTypeLocClass()) {
#define ABSTRACT_TYPELOC(CLASS, PARENT) #define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \ #define TYPELOC(CLASS, PARENT) \
case TypeLoc::CLASS: \ case TypeLoc::CLASS: \
return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T), \ return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
ObjectType);
#include "clang/AST/TypeLocNodes.def" #include "clang/AST/TypeLocNodes.def"
} }
@ -2441,12 +2460,10 @@ TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
QualifiedTypeLoc T, QualifiedTypeLoc T) {
QualType ObjectType) {
Qualifiers Quals = T.getType().getLocalQualifiers(); Qualifiers Quals = T.getType().getLocalQualifiers();
QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc(), QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
ObjectType);
if (Result.isNull()) if (Result.isNull())
return QualType(); return QualType();
@ -2465,6 +2482,77 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
return Result; return Result;
} }
/// \brief Transforms a type that was written in a scope specifier,
/// given an object type, the results of unqualified lookup, and
/// an already-instantiated prefix.
///
/// The object type is provided iff the scope specifier qualifies the
/// member of a dependent member-access expression. The prefix is
/// provided iff the the scope specifier in which this appears has a
/// prefix.
///
/// This is private to TreeTransform.
template<typename Derived>
QualType
TreeTransform<Derived>::TransformTypeInObjectScope(QualType T,
QualType ObjectType,
NamedDecl *UnqualLookup,
NestedNameSpecifier *Prefix) {
if (getDerived().AlreadyTransformed(T))
return T;
TypeSourceInfo *TSI =
SemaRef.Context.getTrivialTypeSourceInfo(T, getBaseLocation());
TSI = getDerived().TransformTypeInObjectScope(TSI, ObjectType,
UnqualLookup, Prefix);
if (!TSI) return QualType();
return TSI->getType();
}
template<typename Derived>
TypeSourceInfo *
TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSI,
QualType ObjectType,
NamedDecl *UnqualLookup,
NestedNameSpecifier *Prefix) {
// TODO: in some cases, we might be some verification to do here.
if (ObjectType.isNull())
return getDerived().TransformType(TSI);
QualType T = TSI->getType();
if (getDerived().AlreadyTransformed(T))
return TSI;
TypeLocBuilder TLB;
QualType Result;
if (isa<TemplateSpecializationType>(T)) {
TemplateSpecializationTypeLoc TL
= cast<TemplateSpecializationTypeLoc>(TSI->getTypeLoc());
TemplateName Template =
getDerived().TransformTemplateName(TL.getTypePtr()->getTemplateName(),
ObjectType, UnqualLookup);
if (Template.isNull()) return 0;
Result = getDerived()
.TransformTemplateSpecializationType(TLB, TL, Template);
} else if (isa<DependentTemplateSpecializationType>(T)) {
DependentTemplateSpecializationTypeLoc TL
= cast<DependentTemplateSpecializationTypeLoc>(TSI->getTypeLoc());
Result = getDerived()
.TransformDependentTemplateSpecializationType(TLB, TL, Prefix);
} else {
// Nothing special needs to be done for these.
Result = getDerived().TransformType(TLB, TSI->getTypeLoc());
}
if (Result.isNull()) return 0;
return TLB.getTypeSourceInfo(SemaRef.Context, Result);
}
template <class TyLoc> static inline template <class TyLoc> static inline
QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) { QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
TyLoc NewT = TLB.push<TyLoc>(T.getType()); TyLoc NewT = TLB.push<TyLoc>(T.getType());
@ -2474,8 +2562,7 @@ QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
BuiltinTypeLoc T, BuiltinTypeLoc T) {
QualType ObjectType) {
BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType()); BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
NewT.setBuiltinLoc(T.getBuiltinLoc()); NewT.setBuiltinLoc(T.getBuiltinLoc());
if (T.needsExtraLocalData()) if (T.needsExtraLocalData())
@ -2485,16 +2572,14 @@ QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
ComplexTypeLoc T, ComplexTypeLoc T) {
QualType ObjectType) {
// FIXME: recurse? // FIXME: recurse?
return TransformTypeSpecType(TLB, T); return TransformTypeSpecType(TLB, T);
} }
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
PointerTypeLoc TL, PointerTypeLoc TL) {
QualType ObjectType) {
QualType PointeeType QualType PointeeType
= getDerived().TransformType(TLB, TL.getPointeeLoc()); = getDerived().TransformType(TLB, TL.getPointeeLoc());
if (PointeeType.isNull()) if (PointeeType.isNull())
@ -2512,7 +2597,7 @@ QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
NewT.setStarLoc(TL.getStarLoc()); NewT.setStarLoc(TL.getStarLoc());
return Result; return Result;
} }
if (getDerived().AlwaysRebuild() || if (getDerived().AlwaysRebuild() ||
PointeeType != TL.getPointeeLoc().getType()) { PointeeType != TL.getPointeeLoc().getType()) {
Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc()); Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
@ -2528,8 +2613,7 @@ QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
BlockPointerTypeLoc TL, BlockPointerTypeLoc TL) {
QualType ObjectType) {
QualType PointeeType QualType PointeeType
= getDerived().TransformType(TLB, TL.getPointeeLoc()); = getDerived().TransformType(TLB, TL.getPointeeLoc());
if (PointeeType.isNull()) if (PointeeType.isNull())
@ -2556,8 +2640,7 @@ TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
ReferenceTypeLoc TL, ReferenceTypeLoc TL) {
QualType ObjectType) {
const ReferenceType *T = TL.getTypePtr(); const ReferenceType *T = TL.getTypePtr();
// Note that this works with the pointee-as-written. // Note that this works with the pointee-as-written.
@ -2589,24 +2672,21 @@ TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
LValueReferenceTypeLoc TL, LValueReferenceTypeLoc TL) {
QualType ObjectType) { return TransformReferenceType(TLB, TL);
return TransformReferenceType(TLB, TL, ObjectType);
} }
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
RValueReferenceTypeLoc TL, RValueReferenceTypeLoc TL) {
QualType ObjectType) { return TransformReferenceType(TLB, TL);
return TransformReferenceType(TLB, TL, ObjectType);
} }
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
MemberPointerTypeLoc TL, MemberPointerTypeLoc TL) {
QualType ObjectType) {
MemberPointerType *T = TL.getTypePtr(); MemberPointerType *T = TL.getTypePtr();
QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
@ -2638,8 +2718,7 @@ TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
ConstantArrayTypeLoc TL, ConstantArrayTypeLoc TL) {
QualType ObjectType) {
ConstantArrayType *T = TL.getTypePtr(); ConstantArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull()) if (ElementType.isNull())
@ -2674,8 +2753,7 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformIncompleteArrayType( QualType TreeTransform<Derived>::TransformIncompleteArrayType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
IncompleteArrayTypeLoc TL, IncompleteArrayTypeLoc TL) {
QualType ObjectType) {
IncompleteArrayType *T = TL.getTypePtr(); IncompleteArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull()) if (ElementType.isNull())
@ -2703,8 +2781,7 @@ QualType TreeTransform<Derived>::TransformIncompleteArrayType(
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
VariableArrayTypeLoc TL, VariableArrayTypeLoc TL) {
QualType ObjectType) {
VariableArrayType *T = TL.getTypePtr(); VariableArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull()) if (ElementType.isNull())
@ -2744,8 +2821,7 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
DependentSizedArrayTypeLoc TL, DependentSizedArrayTypeLoc TL) {
QualType ObjectType) {
DependentSizedArrayType *T = TL.getTypePtr(); DependentSizedArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull()) if (ElementType.isNull())
@ -2788,8 +2864,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
DependentSizedExtVectorTypeLoc TL, DependentSizedExtVectorTypeLoc TL) {
QualType ObjectType) {
DependentSizedExtVectorType *T = TL.getTypePtr(); DependentSizedExtVectorType *T = TL.getTypePtr();
// FIXME: ext vector locs should be nested // FIXME: ext vector locs should be nested
@ -2830,8 +2905,7 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
VectorTypeLoc TL, VectorTypeLoc TL) {
QualType ObjectType) {
VectorType *T = TL.getTypePtr(); VectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType()); QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull()) if (ElementType.isNull())
@ -2854,8 +2928,7 @@ QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
ExtVectorTypeLoc TL, ExtVectorTypeLoc TL) {
QualType ObjectType) {
VectorType *T = TL.getTypePtr(); VectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType()); QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull()) if (ElementType.isNull())
@ -2939,8 +3012,7 @@ bool TreeTransform<Derived>::
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
FunctionProtoTypeLoc TL, FunctionProtoTypeLoc TL) {
QualType ObjectType) {
// Transform the parameters and return type. // Transform the parameters and return type.
// //
// We instantiate in source order, with the return type first followed by // We instantiate in source order, with the return type first followed by
@ -3001,8 +3073,7 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformFunctionNoProtoType( QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
FunctionNoProtoTypeLoc TL, FunctionNoProtoTypeLoc TL) {
QualType ObjectType) {
FunctionNoProtoType *T = TL.getTypePtr(); FunctionNoProtoType *T = TL.getTypePtr();
QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
if (ResultType.isNull()) if (ResultType.isNull())
@ -3023,8 +3094,7 @@ QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
template<typename Derived> QualType template<typename Derived> QualType
TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB,
UnresolvedUsingTypeLoc TL, UnresolvedUsingTypeLoc TL) {
QualType ObjectType) {
UnresolvedUsingType *T = TL.getTypePtr(); UnresolvedUsingType *T = TL.getTypePtr();
Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()); Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
if (!D) if (!D)
@ -3047,8 +3117,7 @@ TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
TypedefTypeLoc TL, TypedefTypeLoc TL) {
QualType ObjectType) {
TypedefType *T = TL.getTypePtr(); TypedefType *T = TL.getTypePtr();
TypedefDecl *Typedef TypedefDecl *Typedef
= cast_or_null<TypedefDecl>(getDerived().TransformDecl(TL.getNameLoc(), = cast_or_null<TypedefDecl>(getDerived().TransformDecl(TL.getNameLoc(),
@ -3072,8 +3141,7 @@ QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
TypeOfExprTypeLoc TL, TypeOfExprTypeLoc TL) {
QualType ObjectType) {
// typeof expressions are not potentially evaluated contexts // typeof expressions are not potentially evaluated contexts
EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
@ -3100,8 +3168,7 @@ QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
TypeOfTypeLoc TL, TypeOfTypeLoc TL) {
QualType ObjectType) {
TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo(); TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo();
TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI); TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
if (!New_Under_TI) if (!New_Under_TI)
@ -3125,8 +3192,7 @@ QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
DecltypeTypeLoc TL, DecltypeTypeLoc TL) {
QualType ObjectType) {
DecltypeType *T = TL.getTypePtr(); DecltypeType *T = TL.getTypePtr();
// decltype expressions are not potentially evaluated contexts // decltype expressions are not potentially evaluated contexts
@ -3153,8 +3219,7 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
RecordTypeLoc TL, RecordTypeLoc TL) {
QualType ObjectType) {
RecordType *T = TL.getTypePtr(); RecordType *T = TL.getTypePtr();
RecordDecl *Record RecordDecl *Record
= cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(), = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
@ -3178,8 +3243,7 @@ QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
EnumTypeLoc TL, EnumTypeLoc TL) {
QualType ObjectType) {
EnumType *T = TL.getTypePtr(); EnumType *T = TL.getTypePtr();
EnumDecl *Enum EnumDecl *Enum
= cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(), = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
@ -3204,8 +3268,7 @@ QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformInjectedClassNameType( QualType TreeTransform<Derived>::TransformInjectedClassNameType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
InjectedClassNameTypeLoc TL, InjectedClassNameTypeLoc TL) {
QualType ObjectType) {
Decl *D = getDerived().TransformDecl(TL.getNameLoc(), Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
TL.getTypePtr()->getDecl()); TL.getTypePtr()->getDecl());
if (!D) return QualType(); if (!D) return QualType();
@ -3219,59 +3282,38 @@ QualType TreeTransform<Derived>::TransformInjectedClassNameType(
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateTypeParmType( QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
TemplateTypeParmTypeLoc TL, TemplateTypeParmTypeLoc TL) {
QualType ObjectType) {
return TransformTypeSpecType(TLB, TL); return TransformTypeSpecType(TLB, TL);
} }
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType( QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
SubstTemplateTypeParmTypeLoc TL, SubstTemplateTypeParmTypeLoc TL) {
QualType ObjectType) {
return TransformTypeSpecType(TLB, TL); return TransformTypeSpecType(TLB, TL);
} }
template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
const TemplateSpecializationType *TST,
QualType ObjectType) {
// FIXME: this entire method is a temporary workaround; callers
// should be rewritten to provide real type locs.
// Fake up a TemplateSpecializationTypeLoc.
TypeLocBuilder TLB;
TemplateSpecializationTypeLoc TL
= TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
SourceLocation BaseLoc = getDerived().getBaseLocation();
TL.setTemplateNameLoc(BaseLoc);
TL.setLAngleLoc(BaseLoc);
TL.setRAngleLoc(BaseLoc);
for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
const TemplateArgument &TA = TST->getArg(i);
TemplateArgumentLoc TAL;
getDerived().InventTemplateArgumentLoc(TA, TAL);
TL.setArgLocInfo(i, TAL.getLocInfo());
}
TypeLocBuilder IgnoredTLB;
return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
}
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType( QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
TypeLocBuilder &TLB, TypeLocBuilder &TLB,
TemplateSpecializationTypeLoc TL, TemplateSpecializationTypeLoc TL) {
QualType ObjectType) {
const TemplateSpecializationType *T = TL.getTypePtr(); const TemplateSpecializationType *T = TL.getTypePtr();
TemplateName Template TemplateName Template
= getDerived().TransformTemplateName(T->getTemplateName(), ObjectType); = getDerived().TransformTemplateName(T->getTemplateName());
if (Template.isNull()) if (Template.isNull())
return QualType(); return QualType();
return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
}
template <typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
TypeLocBuilder &TLB,
TemplateSpecializationTypeLoc TL,
TemplateName Template) {
const TemplateSpecializationType *T = TL.getTypePtr();
TemplateArgumentListInfo NewTemplateArgs; TemplateArgumentListInfo NewTemplateArgs;
NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
@ -3306,40 +3348,21 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
ElaboratedTypeLoc TL, ElaboratedTypeLoc TL) {
QualType ObjectType) {
ElaboratedType *T = TL.getTypePtr(); ElaboratedType *T = TL.getTypePtr();
NestedNameSpecifier *NNS = 0; NestedNameSpecifier *NNS = 0;
// NOTE: the qualifier in an ElaboratedType is optional. // NOTE: the qualifier in an ElaboratedType is optional.
if (T->getQualifier() != 0) { if (T->getQualifier() != 0) {
NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(), NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
TL.getQualifierRange(), TL.getQualifierRange());
ObjectType);
if (!NNS) if (!NNS)
return QualType(); return QualType();
} }
QualType NamedT; QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
// FIXME: this test is meant to workaround a problem (failing assertion) if (NamedT.isNull())
// occurring if directly executing the code in the else branch. return QualType();
if (isa<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc())) {
TemplateSpecializationTypeLoc OldNamedTL
= cast<TemplateSpecializationTypeLoc>(TL.getNamedTypeLoc());
const TemplateSpecializationType* OldTST
= OldNamedTL.getType()->template getAs<TemplateSpecializationType>();
NamedT = TransformTemplateSpecializationType(OldTST, ObjectType);
if (NamedT.isNull())
return QualType();
TemplateSpecializationTypeLoc NewNamedTL
= TLB.push<TemplateSpecializationTypeLoc>(NamedT);
NewNamedTL.copy(OldNamedTL);
}
else {
NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
if (NamedT.isNull())
return QualType();
}
QualType Result = TL.getType(); QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || if (getDerived().AlwaysRebuild() ||
@ -3360,14 +3383,12 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
DependentNameTypeLoc TL, DependentNameTypeLoc TL) {
QualType ObjectType) {
DependentNameType *T = TL.getTypePtr(); DependentNameType *T = TL.getTypePtr();
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(), = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
TL.getQualifierRange(), TL.getQualifierRange());
ObjectType);
if (!NNS) if (!NNS)
return QualType(); return QualType();
@ -3399,17 +3420,26 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType TreeTransform<Derived>:: QualType TreeTransform<Derived>::
TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
DependentTemplateSpecializationTypeLoc TL, DependentTemplateSpecializationTypeLoc TL) {
QualType ObjectType) {
DependentTemplateSpecializationType *T = TL.getTypePtr(); DependentTemplateSpecializationType *T = TL.getTypePtr();
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(), = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
TL.getQualifierRange(), TL.getQualifierRange());
ObjectType);
if (!NNS) if (!NNS)
return QualType(); return QualType();
return getDerived()
.TransformDependentTemplateSpecializationType(TLB, TL, NNS);
}
template<typename Derived>
QualType TreeTransform<Derived>::
TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
DependentTemplateSpecializationTypeLoc TL,
NestedNameSpecifier *NNS) {
DependentTemplateSpecializationType *T = TL.getTypePtr();
TemplateArgumentListInfo NewTemplateArgs; TemplateArgumentListInfo NewTemplateArgs;
NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
@ -3456,8 +3486,7 @@ QualType TreeTransform<Derived>::
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
ObjCInterfaceTypeLoc TL, ObjCInterfaceTypeLoc TL) {
QualType ObjectType) {
// ObjCInterfaceType is never dependent. // ObjCInterfaceType is never dependent.
TLB.pushFullCopy(TL); TLB.pushFullCopy(TL);
return TL.getType(); return TL.getType();
@ -3466,8 +3495,7 @@ TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
ObjCObjectTypeLoc TL, ObjCObjectTypeLoc TL) {
QualType ObjectType) {
// ObjCObjectType is never dependent. // ObjCObjectType is never dependent.
TLB.pushFullCopy(TL); TLB.pushFullCopy(TL);
return TL.getType(); return TL.getType();
@ -3476,8 +3504,7 @@ TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
template<typename Derived> template<typename Derived>
QualType QualType
TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB, TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
ObjCObjectPointerTypeLoc TL, ObjCObjectPointerTypeLoc TL) {
QualType ObjectType) {
// ObjCObjectPointerType is never dependent. // ObjCObjectPointerType is never dependent.
TLB.pushFullCopy(TL); TLB.pushFullCopy(TL);
return TL.getType(); return TL.getType();
@ -5477,17 +5504,21 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
return ExprError(); return ExprError();
QualType ObjectType = ObjectTypePtr.get(); QualType ObjectType = ObjectTypePtr.get();
NestedNameSpecifier *Qualifier NestedNameSpecifier *Qualifier = E->getQualifier();
= getDerived().TransformNestedNameSpecifier(E->getQualifier(), if (Qualifier) {
E->getQualifierRange(), Qualifier
ObjectType); = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
if (E->getQualifier() && !Qualifier) E->getQualifierRange(),
return ExprError(); ObjectType);
if (!Qualifier)
return ExprError();
}
PseudoDestructorTypeStorage Destroyed; PseudoDestructorTypeStorage Destroyed;
if (E->getDestroyedTypeInfo()) { if (E->getDestroyedTypeInfo()) {
TypeSourceInfo *DestroyedTypeInfo TypeSourceInfo *DestroyedTypeInfo
= getDerived().TransformType(E->getDestroyedTypeInfo(), ObjectType); = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
ObjectType, 0, Qualifier);
if (!DestroyedTypeInfo) if (!DestroyedTypeInfo)
return ExprError(); return ExprError();
Destroyed = DestroyedTypeInfo; Destroyed = DestroyedTypeInfo;
@ -5520,8 +5551,7 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
TypeSourceInfo *ScopeTypeInfo = 0; TypeSourceInfo *ScopeTypeInfo = 0;
if (E->getScopeTypeInfo()) { if (E->getScopeTypeInfo()) {
ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo(), ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo());
ObjectType);
if (!ScopeTypeInfo) if (!ScopeTypeInfo)
return ExprError(); return ExprError();
} }
@ -5646,6 +5676,10 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
if (!NNS) if (!NNS)
return ExprError(); return ExprError();
// TODO: If this is a conversion-function-id, verify that the
// destination type name (if present) resolves the same way after
// instantiation as it did in the local scope.
DeclarationNameInfo NameInfo DeclarationNameInfo NameInfo
= getDerived().TransformDeclarationNameInfo(E->getNameInfo()); = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
if (!NameInfo.getName()) if (!NameInfo.getName())
@ -5892,9 +5926,12 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
return ExprError(); return ExprError();
} }
// TODO: If this is a conversion-function-id, verify that the
// destination type name (if present) resolves the same way after
// instantiation as it did in the local scope.
DeclarationNameInfo NameInfo DeclarationNameInfo NameInfo
= getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo(), = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
ObjectType);
if (!NameInfo.getName()) if (!NameInfo.getName())
return ExprError(); return ExprError();
@ -6611,7 +6648,8 @@ TemplateName
TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier, TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, SourceRange QualifierRange,
const IdentifierInfo &II, const IdentifierInfo &II,
QualType ObjectType) { QualType ObjectType,
NamedDecl *FirstQualifierInScope) {
CXXScopeSpec SS; CXXScopeSpec SS;
SS.setRange(QualifierRange); SS.setRange(QualifierRange);
SS.setScopeRep(Qualifier); SS.setScopeRep(Qualifier);
@ -6625,7 +6663,7 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
ParsedType::make(ObjectType), ParsedType::make(ObjectType),
/*EnteringContext=*/false, /*EnteringContext=*/false,
Template); Template);
return Template.template getAsVal<TemplateName>(); return Template.get();
} }
template<typename Derived> template<typename Derived>

View File

@ -49,3 +49,20 @@ namespace test1 {
}; };
template struct O::B<int>; // expected-note {{in instantiation}} template struct O::B<int>; // expected-note {{in instantiation}}
} }
// PR7248
namespace test2 {
template <class T> struct A {
void foo() {
T::bar(); // expected-error {{type 'int' cannot}}
}
};
template <class T> class B {
void foo(A<T> a) {
a.test2::template A<T>::foo(); // expected-note {{in instantiation}}
}
};
template class B<int>;
}