#include "llvm/ADT/STLExtras.h"
using namespace clang;
+Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
+ IdentifierInfo &II,
+ SourceLocation NameLoc,
+ Scope *S, const CXXScopeSpec &SS,
+ TypeTy *ObjectTypePtr,
+ bool EnteringContext) {
+ // Determine where to perform name lookup.
+
+ // FIXME: This area of the standard is very messy, and the current
+ // wording is rather unclear about which scopes we search for the
+ // destructor name; see core issues 399 and 555. Issue 399 in
+ // particular shows where the current description of destructor name
+ // lookup is completely out of line with existing practice, e.g.,
+ // this appears to be ill-formed:
+ //
+ // namespace N {
+ // template <typename T> struct S {
+ // ~S();
+ // };
+ // }
+ //
+ // void f(N::S<int>* s) {
+ // s->N::S<int>::~S();
+ // }
+ //
+ //
+ QualType SearchType;
+ DeclContext *LookupCtx = 0;
+ bool isDependent = false;
+ bool LookInScope = false;
+
+ // If we have an object type, it's because we are in a
+ // pseudo-destructor-expression or a member access expression, and
+ // we know what type we're looking for.
+ if (ObjectTypePtr)
+ SearchType = GetTypeFromParser(ObjectTypePtr);
+
+ if (SS.isSet()) {
+ // C++ [basic.lookup.qual]p6:
+ // If a pseudo-destructor-name (5.2.4) contains a
+ // nested-name-specifier, the type-names are looked up as types
+ // in the scope designated by the nested-name-specifier. Similarly, in
+ // a qualified-id of theform:
+ //
+ // :: [opt] nested-name-specifier[opt] class-name :: ~class-name
+ //
+ // the second class-name is looked up in the same scope as the first.
+ //
+ // To implement this, we look at the prefix of the
+ // nested-name-specifier we were given, and determine the lookup
+ // context from that.
+ NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+ if (NestedNameSpecifier *Prefix = NNS->getPrefix()) {
+ CXXScopeSpec PrefixSS;
+ PrefixSS.setScopeRep(Prefix);
+ LookupCtx = computeDeclContext(PrefixSS, EnteringContext);
+ isDependent = isDependentScopeSpecifier(PrefixSS);
+ } else if (ObjectTypePtr) {
+ LookupCtx = computeDeclContext(SearchType);
+ isDependent = SearchType->isDependentType();
+ } else {
+ LookupCtx = computeDeclContext(SS, EnteringContext);
+ if (LookupCtx && !LookupCtx->isTranslationUnit()) {
+ LookupCtx = LookupCtx->getParent();
+ isDependent = LookupCtx->isDependentContext();
+ } else {
+ isDependent = false;
+ }
+ }
+
+ LookInScope = false;
+ } else if (ObjectTypePtr) {
+ // C++ [basic.lookup.classref]p3:
+ // If the unqualified-id is ~type-name, the type-name is looked up
+ // in the context of the entire postfix-expression. If the type T
+ // of the object expression is of a class type C, the type-name is
+ // also looked up in the scope of class C. At least one of the
+ // lookups shall find a name that refers to (possibly
+ // cv-qualified) T.
+ LookupCtx = computeDeclContext(SearchType);
+ isDependent = SearchType->isDependentType();
+ assert((isDependent || !SearchType->isIncompleteType()) &&
+ "Caller should have completed object type");
+
+ LookInScope = true;
+ } else {
+ // Perform lookup into the current scope (only).
+ LookInScope = true;
+ }
+
+ LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName);
+ for (unsigned Step = 0; Step != 2; ++Step) {
+ // Look for the name first in the computed lookup context (if we
+ // have one) and, if that fails to find a match, in the sope (if
+ // we're allowed to look there).
+ Found.clear();
+ if (Step == 0 && LookupCtx)
+ LookupQualifiedName(Found, LookupCtx);
+ else if (Step == 1 && LookInScope)
+ LookupName(Found, S);
+ else
+ continue;
+
+ // FIXME: Should we be suppressing ambiguities here?
+ if (Found.isAmbiguous())
+ return 0;
+
+ if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
+ QualType T = Context.getTypeDeclType(Type);
+ // If we found the injected-class-name of a class template, retrieve the
+ // type of that template.
+ // FIXME: We really shouldn't need to do this.
+ if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Type))
+ if (Record->isInjectedClassName())
+ if (Record->getDescribedClassTemplate())
+ T = Record->getDescribedClassTemplate()
+ ->getInjectedClassNameType(Context);
+
+ if (SearchType.isNull() || SearchType->isDependentType() ||
+ Context.hasSameUnqualifiedType(T, SearchType)) {
+ // We found our type!
+
+ return T.getAsOpaquePtr();
+ }
+ }
+
+ // If the name that we found is a class template name, and it is
+ // the same name as the template name in the last part of the
+ // nested-name-specifier (if present) or the object type, then
+ // this is the destructor for that class.
+ // FIXME: This is a workaround until we get real drafting for core
+ // issue 399, for which there isn't even an obvious direction.
+ if (ClassTemplateDecl *Template = Found.getAsSingle<ClassTemplateDecl>()) {
+ QualType MemberOfType;
+ if (SS.isSet()) {
+ if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) {
+ // Figure out the type of the context, if it has one.
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Ctx))
+ MemberOfType = Context.getTypeDeclType(Spec);
+ else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
+ if (Record->getDescribedClassTemplate())
+ MemberOfType = Record->getDescribedClassTemplate()
+ ->getInjectedClassNameType(Context);
+ else
+ MemberOfType = Context.getTypeDeclType(Record);
+ }
+ }
+ }
+ if (MemberOfType.isNull())
+ MemberOfType = SearchType;
+
+ if (MemberOfType.isNull())
+ continue;
+
+ // We're referring into a class template specialization. If the
+ // class template we found is the same as the template being
+ // specialized, we found what we are looking for.
+ if (const RecordType *Record = MemberOfType->getAs<RecordType>()) {
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
+ if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
+ Template->getCanonicalDecl())
+ return MemberOfType.getAsOpaquePtr();
+ }
+
+ continue;
+ }
+
+ // We're referring to an unresolved class template
+ // specialization. Determine whether we class template we found
+ // is the same as the template being specialized or, if we don't
+ // know which template is being specialized, that it at least
+ // has the same name.
+ if (const TemplateSpecializationType *SpecType
+ = MemberOfType->getAs<TemplateSpecializationType>()) {
+ TemplateName SpecName = SpecType->getTemplateName();
+
+ // The class template we found is the same template being
+ // specialized.
+ if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
+ if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
+ return MemberOfType.getAsOpaquePtr();
+
+ continue;
+ }
+
+ // The class template we found has the same name as the
+ // (dependent) template name being specialized.
+ if (DependentTemplateName *DepTemplate
+ = SpecName.getAsDependentTemplateName()) {
+ if (DepTemplate->isIdentifier() &&
+ DepTemplate->getIdentifier() == Template->getIdentifier())
+ return MemberOfType.getAsOpaquePtr();
+
+ continue;
+ }
+ }
+ }
+ }
+
+ if (isDependent) {
+ // We didn't find our type, but that's okay: it's dependent
+ // anyway.
+ NestedNameSpecifier *NNS = 0;
+ SourceRange Range;
+ if (SS.isSet()) {
+ NNS = (NestedNameSpecifier *)SS.getScopeRep();
+ Range = SourceRange(SS.getRange().getBegin(), NameLoc);
+ } else {
+ NNS = NestedNameSpecifier::Create(Context, &II);
+ Range = SourceRange(NameLoc);
+ }
+
+ return CheckTypenameType(NNS, II, Range).getAsOpaquePtr();
+ }
+
+ if (ObjectTypePtr)
+ Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+ << &II;
+ else
+ Diag(NameLoc, diag::err_destructor_class_name);
+
+ return 0;
+}
+
/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
Action::OwningExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
/// switched to storing TypeSourceInfos.
///
/// \returns the transformed type.
- QualType TransformType(QualType T);
+ QualType TransformType(QualType T, QualType ObjectType = QualType());
/// \brief Transforms the given type-with-location into a new
/// type-with-location.
/// may override this function (to take over all type
/// transformations) or some set of the TransformXXXType functions
/// 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
/// type, collecting location information in the given builder
/// as necessary.
///
- QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
+ QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL,
+ QualType ObjectType = QualType());
/// \brief Transform the given statement.
///
#define ABSTRACT_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"
- QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
+ QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL,
+ QualType ObjectType);
QualType
TransformTemplateSpecializationType(const TemplateSpecializationType *T,
QualType ObjectType);
- QualType
- TransformTemplateSpecializationType(TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL,
- QualType ObjectType);
-
OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
#define STMT(Node, Parent) \
case NestedNameSpecifier::TypeSpecWithTemplate:
case NestedNameSpecifier::TypeSpec: {
TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
- QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
+ QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0),
+ ObjectType);
if (T.isNull())
return 0;
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName: {
TemporaryBase Rebase(*this, Loc, Name);
- 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());
+ QualType T = getDerived().TransformType(Name.getCXXNameType(),
+ ObjectType);
if (T.isNull())
return DeclarationName();
if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
- /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
+ /*FIXME:*/SourceRange(getDerived().getBaseLocation()),
+ ObjectType);
if (!NNS)
return TemplateName();
if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
- /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
+ /*FIXME:*/SourceRange(getDerived().getBaseLocation()),
+ ObjectType);
if (!NNS && DTN->getQualifier())
return TemplateName();
//===----------------------------------------------------------------------===//
template<typename Derived>
-QualType TreeTransform<Derived>::TransformType(QualType T) {
+QualType TreeTransform<Derived>::TransformType(QualType T,
+ QualType ObjectType) {
if (getDerived().AlreadyTransformed(T))
return T;
TypeSourceInfo *DI = getSema().Context.CreateTypeSourceInfo(T);
DI->getTypeLoc().initialize(getDerived().getBaseLocation());
- TypeSourceInfo *NewDI = getDerived().TransformType(DI);
+ TypeSourceInfo *NewDI = getDerived().TransformType(DI, ObjectType);
if (!NewDI)
return QualType();
}
template<typename Derived>
-TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
+TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI,
+ QualType ObjectType) {
if (getDerived().AlreadyTransformed(DI->getType()))
return DI;
TypeLoc TL = DI->getTypeLoc();
TLB.reserve(TL.getFullDataSize());
- QualType Result = getDerived().TransformType(TLB, TL);
+ QualType Result = getDerived().TransformType(TLB, TL, ObjectType);
if (Result.isNull())
return 0;
template<typename Derived>
QualType
-TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
+TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T,
+ QualType ObjectType) {
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));
+ return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T), \
+ ObjectType);
#include "clang/AST/TypeLocNodes.def"
}
template<typename Derived>
QualType
TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
- QualifiedTypeLoc T) {
+ QualifiedTypeLoc T,
+ QualType ObjectType) {
Qualifiers Quals = T.getType().getLocalQualifiers();
- QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
+ QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc(),
+ ObjectType);
if (Result.isNull())
return QualType();
template<typename Derived>
QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
- BuiltinTypeLoc T) {
+ BuiltinTypeLoc T,
+ QualType ObjectType) {
BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
NewT.setBuiltinLoc(T.getBuiltinLoc());
if (T.needsExtraLocalData())
template<typename Derived>
QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
- ComplexTypeLoc T) {
+ ComplexTypeLoc T,
+ QualType ObjectType) {
// FIXME: recurse?
return TransformTypeSpecType(TLB, T);
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
- PointerTypeLoc TL) {
+ PointerTypeLoc TL,
+ QualType ObjectType) {
TransformPointerLikeType(PointerType);
}
template<typename Derived>
QualType
TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
- BlockPointerTypeLoc TL) {
+ BlockPointerTypeLoc TL,
+ QualType ObjectType) {
TransformPointerLikeType(BlockPointerType);
}
template<typename Derived>
QualType
TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
- ReferenceTypeLoc TL) {
+ ReferenceTypeLoc TL,
+ QualType ObjectType) {
const ReferenceType *T = TL.getTypePtr();
// Note that this works with the pointee-as-written.
template<typename Derived>
QualType
TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
- LValueReferenceTypeLoc TL) {
- return TransformReferenceType(TLB, TL);
+ LValueReferenceTypeLoc TL,
+ QualType ObjectType) {
+ return TransformReferenceType(TLB, TL, ObjectType);
}
template<typename Derived>
QualType
TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
- RValueReferenceTypeLoc TL) {
- return TransformReferenceType(TLB, TL);
+ RValueReferenceTypeLoc TL,
+ QualType ObjectType) {
+ return TransformReferenceType(TLB, TL, ObjectType);
}
template<typename Derived>
QualType
TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
- MemberPointerTypeLoc TL) {
+ MemberPointerTypeLoc TL,
+ QualType ObjectType) {
MemberPointerType *T = TL.getTypePtr();
QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
template<typename Derived>
QualType
TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
- ConstantArrayTypeLoc TL) {
+ ConstantArrayTypeLoc TL,
+ QualType ObjectType) {
ConstantArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
template<typename Derived>
QualType TreeTransform<Derived>::TransformIncompleteArrayType(
TypeLocBuilder &TLB,
- IncompleteArrayTypeLoc TL) {
+ IncompleteArrayTypeLoc TL,
+ QualType ObjectType) {
IncompleteArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
template<typename Derived>
QualType
TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
- VariableArrayTypeLoc TL) {
+ VariableArrayTypeLoc TL,
+ QualType ObjectType) {
VariableArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
template<typename Derived>
QualType
TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
- DependentSizedArrayTypeLoc TL) {
+ DependentSizedArrayTypeLoc TL,
+ QualType ObjectType) {
DependentSizedArrayType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
if (ElementType.isNull())
template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
TypeLocBuilder &TLB,
- DependentSizedExtVectorTypeLoc TL) {
+ DependentSizedExtVectorTypeLoc TL,
+ QualType ObjectType) {
DependentSizedExtVectorType *T = TL.getTypePtr();
// FIXME: ext vector locs should be nested
template<typename Derived>
QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
- VectorTypeLoc TL) {
+ VectorTypeLoc TL,
+ QualType ObjectType) {
VectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull())
template<typename Derived>
QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
- ExtVectorTypeLoc TL) {
+ ExtVectorTypeLoc TL,
+ QualType ObjectType) {
VectorType *T = TL.getTypePtr();
QualType ElementType = getDerived().TransformType(T->getElementType());
if (ElementType.isNull())
template<typename Derived>
QualType
TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
- FunctionProtoTypeLoc TL) {
+ FunctionProtoTypeLoc TL,
+ QualType ObjectType) {
FunctionProtoType *T = TL.getTypePtr();
QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
if (ResultType.isNull())
template<typename Derived>
QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
TypeLocBuilder &TLB,
- FunctionNoProtoTypeLoc TL) {
+ FunctionNoProtoTypeLoc TL,
+ QualType ObjectType) {
FunctionNoProtoType *T = TL.getTypePtr();
QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
if (ResultType.isNull())
template<typename Derived> QualType
TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB,
- UnresolvedUsingTypeLoc TL) {
+ UnresolvedUsingTypeLoc TL,
+ QualType ObjectType) {
UnresolvedUsingType *T = TL.getTypePtr();
Decl *D = getDerived().TransformDecl(T->getDecl());
if (!D)
template<typename Derived>
QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
- TypedefTypeLoc TL) {
+ TypedefTypeLoc TL,
+ QualType ObjectType) {
TypedefType *T = TL.getTypePtr();
TypedefDecl *Typedef
= cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
template<typename Derived>
QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
- TypeOfExprTypeLoc TL) {
+ TypeOfExprTypeLoc TL,
+ QualType ObjectType) {
// typeof expressions are not potentially evaluated contexts
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
template<typename Derived>
QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
- TypeOfTypeLoc TL) {
+ TypeOfTypeLoc TL,
+ QualType ObjectType) {
TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo();
TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
if (!New_Under_TI)
template<typename Derived>
QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
- DecltypeTypeLoc TL) {
+ DecltypeTypeLoc TL,
+ QualType ObjectType) {
DecltypeType *T = TL.getTypePtr();
// decltype expressions are not potentially evaluated contexts
template<typename Derived>
QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
- RecordTypeLoc TL) {
+ RecordTypeLoc TL,
+ QualType ObjectType) {
RecordType *T = TL.getTypePtr();
RecordDecl *Record
= cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
template<typename Derived>
QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
- EnumTypeLoc TL) {
+ EnumTypeLoc TL,
+ QualType ObjectType) {
EnumType *T = TL.getTypePtr();
EnumDecl *Enum
= cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
template <typename Derived>
QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
- ElaboratedTypeLoc TL) {
+ ElaboratedTypeLoc TL,
+ QualType ObjectType) {
ElaboratedType *T = TL.getTypePtr();
// FIXME: this should be a nested type.
template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
TypeLocBuilder &TLB,
- TemplateTypeParmTypeLoc TL) {
+ TemplateTypeParmTypeLoc TL,
+ QualType ObjectType) {
return TransformTypeSpecType(TLB, TL);
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
TypeLocBuilder &TLB,
- SubstTemplateTypeParmTypeLoc TL) {
+ SubstTemplateTypeParmTypeLoc TL,
+ QualType ObjectType) {
return TransformTypeSpecType(TLB, TL);
}
-template<typename Derived>
-inline QualType
-TreeTransform<Derived>::TransformTemplateSpecializationType(
- TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL) {
- return TransformTemplateSpecializationType(TLB, TL, QualType());
-}
-
template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
const TemplateSpecializationType *TST,
template<typename Derived>
QualType
TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
- QualifiedNameTypeLoc TL) {
+ QualifiedNameTypeLoc TL,
+ QualType ObjectType) {
QualifiedNameType *T = TL.getTypePtr();
NestedNameSpecifier *NNS
= getDerived().TransformNestedNameSpecifier(T->getQualifier(),
- SourceRange());
+ SourceRange(),
+ ObjectType);
if (!NNS)
return QualType();
template<typename Derived>
QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
- TypenameTypeLoc TL) {
+ TypenameTypeLoc TL,
+ QualType ObjectType) {
TypenameType *T = TL.getTypePtr();
/* FIXME: preserve source information better than this */
SourceRange SR(TL.getNameLoc());
NestedNameSpecifier *NNS
- = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
+ = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR,
+ ObjectType);
if (!NNS)
return QualType();
template<typename Derived>
QualType
TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
- ObjCInterfaceTypeLoc TL) {
+ ObjCInterfaceTypeLoc TL,
+ QualType ObjectType) {
assert(false && "TransformObjCInterfaceType unimplemented");
return QualType();
}
template<typename Derived>
QualType
TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
- ObjCObjectPointerTypeLoc TL) {
+ ObjCObjectPointerTypeLoc TL,
+ QualType ObjectType) {
assert(false && "TransformObjCObjectPointerType unimplemented");
return QualType();
}