[cfe-commits] r105801 - in /cfe/trunk: include/clang/AST/ include/clang/Frontend/ lib/AST/ lib/CodeGen/ lib/Frontend/ lib/Sema/
John McCall
rjmccall at apple.com
Thu Jun 10 17:33:02 PDT 2010
Author: rjmccall
Date: Thu Jun 10 19:33:02 2010
New Revision: 105801
URL: http://llvm.org/viewvc/llvm-project?rev=105801&view=rev
Log:
Split DependentNameType into two types. DependentNameType represents the
case of an elaborated-type-specifier like 'typename A<T>::foo', and
DependentTemplateSpecializationType represents the case of an
elaborated-type-specifier like 'typename A<T>::template B<T>'. The TypeLoc
representation of a DependentTST conveniently exactly matches that of an
ElaboratedType wrapping a TST.
Kill off the explicit rebuild methods for RebuildInCurrentInstantiation;
the standard implementations work fine because the nested name specifier
is computable in the newly-entered context.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/include/clang/AST/TemplateBase.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeLoc.h
cfe/trunk/include/clang/AST/TypeNodes.def
cfe/trunk/include/clang/Frontend/TypeXML.def
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/TemplateBase.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/CodeGen/Mangle.cpp
cfe/trunk/lib/Frontend/PCHReader.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/lib/Sema/TreeTransform.h
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jun 10 19:33:02 2010
@@ -98,6 +98,8 @@
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<DependentNameType> DependentNameTypes;
+ llvm::FoldingSet<DependentTemplateSpecializationType>
+ DependentTemplateSpecializationTypes;
llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
@@ -621,10 +623,16 @@
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
QualType Canon = QualType());
- QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const TemplateSpecializationType *TemplateId,
- QualType Canon = QualType());
+
+ QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ const TemplateArgumentListInfo &Args);
+ QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Jun 10 19:33:02 2010
@@ -586,14 +586,12 @@
})
DEF_TRAVERSE_TYPE(DependentNameType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ })
- if (T->getTemplateId()) {
- TRY_TO(VisitTemplateSpecializationType(
- const_cast<TemplateSpecializationType *>(T->getTemplateId())));
- }
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
})
DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
Modified: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Thu Jun 10 19:33:02 2010
@@ -256,6 +256,10 @@
return Args.NumArgs;
}
+ /// Determines whether two template arguments are superficially the
+ /// same.
+ bool structurallyEquals(const TemplateArgument &Other) const;
+
/// \brief Construct a template argument pack.
void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
@@ -476,6 +480,28 @@
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const TemplateArgument &Arg);
+
+inline TemplateSpecializationType::iterator
+ TemplateSpecializationType::end() const {
+ return getArgs() + getNumArgs();
+}
+
+inline DependentTemplateSpecializationType::iterator
+ DependentTemplateSpecializationType::end() const {
+ return getArgs() + getNumArgs();
+}
+
+inline const TemplateArgument &
+ TemplateSpecializationType::getArg(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Template argument out of range");
+ return getArgs()[Idx];
+}
+
+inline const TemplateArgument &
+ DependentTemplateSpecializationType::getArg(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Template argument out of range");
+ return getArgs()[Idx];
+}
} // end namespace clang
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Jun 10 19:33:02 2010
@@ -2426,7 +2426,7 @@
// The bool is whether this is a current instantiation.
llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
- /// \brief The name of the template being specialized.
+ /// \brief The name of the template being specialized.
TemplateName Template;
/// \brief - The number of template arguments named in this class
@@ -2476,7 +2476,7 @@
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
- iterator end() const;
+ iterator end() const; // defined inline in TemplateBase.h
/// \brief Retrieve the name of the template that we are specializing.
TemplateName getTemplateName() const { return Template; }
@@ -2491,7 +2491,7 @@
/// \brief Retrieve a specific template argument as a type.
/// \precondition @c isArgType(Arg)
- const TemplateArgument &getArg(unsigned Idx) const;
+ const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
bool isSugared() const {
return !isDependentType() || isCurrentInstantiation();
@@ -2682,6 +2682,7 @@
friend class ASTContext; // ASTContext creates these
public:
+ ~ElaboratedType();
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2726,11 +2727,8 @@
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
- typedef llvm::PointerUnion<const IdentifierInfo *,
- const TemplateSpecializationType *> NameType;
-
/// \brief The type that this typename specifier refers to.
- NameType Name;
+ const IdentifierInfo *Name;
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, QualType CanonType)
@@ -2740,17 +2738,10 @@
"DependentNameType requires a dependent nested-name-specifier");
}
- DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- const TemplateSpecializationType *Ty, QualType CanonType)
- : TypeWithKeyword(Keyword, DependentName, CanonType, true),
- NNS(NNS), Name(Ty) {
- assert(NNS->isDependent() &&
- "DependentNameType requires a dependent nested-name-specifier");
- }
-
friend class ASTContext; // ASTContext creates these
public:
+ virtual ~DependentNameType();
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2762,13 +2753,7 @@
/// form of the original typename was terminated by an identifier,
/// e.g., "typename T::type".
const IdentifierInfo *getIdentifier() const {
- return Name.dyn_cast<const IdentifierInfo *>();
- }
-
- /// \brief Retrieve the type named by the typename specifier as a
- /// type specialization.
- const TemplateSpecializationType *getTemplateId() const {
- return Name.dyn_cast<const TemplateSpecializationType *>();
+ return Name;
}
bool isSugared() const { return false; }
@@ -2779,10 +2764,10 @@
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, NameType Name) {
+ NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
ID.AddInteger(Keyword);
ID.AddPointer(NNS);
- ID.AddPointer(Name.getOpaqueValue());
+ ID.AddPointer(Name);
}
static bool classof(const Type *T) {
@@ -2791,6 +2776,88 @@
static bool classof(const DependentNameType *T) { return true; }
};
+/// DependentTemplateSpecializationType - Represents a template
+/// specialization type whose template cannot be resolved, e.g.
+/// A<T>::template B<T>
+class DependentTemplateSpecializationType :
+ public TypeWithKeyword, public llvm::FoldingSetNode {
+
+ /// The AST context. Unfortunately required in order to profile
+ /// template arguments.
+ ASTContext &Context;
+
+ /// \brief The nested name specifier containing the qualifier.
+ NestedNameSpecifier *NNS;
+
+ /// \brief The identifier of the template.
+ const IdentifierInfo *Name;
+
+ /// \brief - The number of template arguments named in this class
+ /// template specialization.
+ unsigned NumArgs;
+
+ const TemplateArgument *getArgBuffer() const {
+ return reinterpret_cast<const TemplateArgument*>(this+1);
+ }
+ TemplateArgument *getArgBuffer() {
+ return reinterpret_cast<TemplateArgument*>(this+1);
+ }
+
+ DependentTemplateSpecializationType(ASTContext &Context,
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args,
+ QualType Canon);
+
+ virtual void Destroy(ASTContext& C);
+
+ friend class ASTContext; // ASTContext creates these
+
+public:
+ virtual ~DependentTemplateSpecializationType();
+
+ NestedNameSpecifier *getQualifier() const { return NNS; }
+ const IdentifierInfo *getIdentifier() const { return Name; }
+
+ /// \brief Retrieve the template arguments.
+ const TemplateArgument *getArgs() const {
+ return getArgBuffer();
+ }
+
+ /// \brief Retrieve the number of template arguments.
+ unsigned getNumArgs() const { return NumArgs; }
+
+ const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
+
+ typedef const TemplateArgument * iterator;
+ iterator begin() const { return getArgs(); }
+ iterator end() const; // inline in TemplateBase.h
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ ASTContext &Context,
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *Qualifier,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args);
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == DependentTemplateSpecialization;
+ }
+ static bool classof(const DependentTemplateSpecializationType *T) {
+ return true;
+ }
+};
+
/// ObjCObjectType - Represents a class type in Objective C.
/// Every Objective C type is a combination of a base type and a
/// list of protocols.
Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Jun 10 19:33:02 2010
@@ -1033,13 +1033,20 @@
setLAngleLoc(Loc);
setRAngleLoc(Loc);
setTemplateNameLoc(Loc);
+ initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(),
+ getArgInfos(), Loc);
+ }
- for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+ static void initializeArgLocs(unsigned NumArgs,
+ const TemplateArgument *Args,
+ TemplateArgumentLocInfo *ArgInfos,
+ SourceLocation Loc) {
+ for (unsigned i = 0, e = NumArgs; i != e; ++i) {
TemplateArgumentLocInfo Info;
#ifndef NDEBUG
// If asserts are enabled, be sure to initialize the argument
// loc with the right kind of pointer.
- switch (getTypePtr()->getArg(i).getKind()) {
+ switch (Args[i].getKind()) {
case TemplateArgument::Expression:
case TemplateArgument::Declaration:
Info = TemplateArgumentLocInfo((Expr*) 0);
@@ -1050,7 +1057,7 @@
break;
case TemplateArgument::Template:
- Info = TemplateArgumentLocInfo(SourceRange(), SourceLocation());
+ Info = TemplateArgumentLocInfo(SourceRange(Loc), Loc);
break;
case TemplateArgument::Integral:
@@ -1060,7 +1067,7 @@
break;
}
#endif
- getArgInfos()[i] = Info;
+ ArgInfos[i] = Info;
}
}
@@ -1251,9 +1258,9 @@
}
};
-struct DependentNameLocInfo {
- SourceLocation KeywordLoc;
- SourceRange QualifierRange;
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TypeDeclTypeLoc.
+struct DependentNameLocInfo : ElaboratedLocInfo {
SourceLocation NameLoc;
};
@@ -1303,6 +1310,107 @@
}
};
+// This is exactly the structure of an ElaboratedTypeLoc whose inner
+// type is some sort of TemplateSpecializationTypeLoc.
+struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+ // followed by a TemplateArgumentLocInfo[]
+};
+
+class DependentTemplateSpecializationTypeLoc :
+ public ConcreteTypeLoc<UnqualTypeLoc,
+ DependentTemplateSpecializationTypeLoc,
+ DependentTemplateSpecializationType,
+ DependentTemplateSpecializationLocInfo> {
+public:
+ SourceLocation getKeywordLoc() const {
+ return this->getLocalData()->KeywordLoc;
+ }
+ void setKeywordLoc(SourceLocation Loc) {
+ this->getLocalData()->KeywordLoc = Loc;
+ }
+
+ SourceRange getQualifierRange() const {
+ return this->getLocalData()->QualifierRange;
+ }
+ void setQualifierRange(SourceRange Range) {
+ this->getLocalData()->QualifierRange = Range;
+ }
+
+ SourceLocation getNameLoc() const {
+ return this->getLocalData()->NameLoc;
+ }
+ void setNameLoc(SourceLocation Loc) {
+ this->getLocalData()->NameLoc = Loc;
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return this->getLocalData()->LAngleLoc;
+ }
+ void setLAngleLoc(SourceLocation Loc) {
+ this->getLocalData()->LAngleLoc = Loc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return this->getLocalData()->RAngleLoc;
+ }
+ void setRAngleLoc(SourceLocation Loc) {
+ this->getLocalData()->RAngleLoc = Loc;
+ }
+
+ unsigned getNumArgs() const {
+ return getTypePtr()->getNumArgs();
+ }
+
+ void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+#ifndef NDEBUG
+ AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+ getArgInfos()[i] = AI;
+ }
+ TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+ return getArgInfos()[i];
+ }
+
+ TemplateArgumentLoc getArgLoc(unsigned i) const {
+ return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ }
+
+ SourceRange getLocalSourceRange() const {
+ if (getKeywordLoc().isValid())
+ return SourceRange(getKeywordLoc(), getRAngleLoc());
+ else
+ return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
+ }
+
+ void copy(DependentTemplateSpecializationTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+ memcpy(Data, Loc.Data, size);
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ setQualifierRange(SourceRange(Loc));
+ setNameLoc(Loc);
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
+ getTypePtr()->getArgs(),
+ getArgInfos(), Loc);
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+ }
+
+private:
+ TemplateArgumentLocInfo *getArgInfos() const {
+ return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+ }
+};
+
}
#endif
Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Thu Jun 10 19:33:02 2010
@@ -92,6 +92,7 @@
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
+DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
TYPE(ObjCObject, Type)
TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)
Modified: cfe/trunk/include/clang/Frontend/TypeXML.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TypeXML.def?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TypeXML.def (original)
+++ cfe/trunk/include/clang/Frontend/TypeXML.def Thu Jun 10 19:33:02 2010
@@ -253,6 +253,11 @@
ID_ATTRIBUTE_XML
END_NODE_XML
+NODE_XML(DependentTemplateSpecializationType,
+ "DependentTemplateSpecializationType")
+ ID_ATTRIBUTE_XML
+END_NODE_XML
+
NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
ID_ATTRIBUTE_XML
END_NODE_XML
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jun 10 19:33:02 2010
@@ -1911,44 +1911,69 @@
}
QualType
-ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
+ASTContext::getDependentTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
- const TemplateSpecializationType *TemplateId,
- QualType Canon) {
+ const IdentifierInfo *Name,
+ const TemplateArgumentListInfo &Args) {
+ // TODO: avoid this copy
+ llvm::SmallVector<TemplateArgument, 16> ArgCopy;
+ for (unsigned I = 0, E = Args.size(); I != E; ++I)
+ ArgCopy.push_back(Args[I].getArgument());
+ return getDependentTemplateSpecializationType(Keyword, NNS, Name,
+ ArgCopy.size(),
+ ArgCopy.data());
+}
+
+QualType
+ASTContext::getDependentTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args) {
assert(NNS->isDependent() && "nested-name-specifier must be dependent");
llvm::FoldingSetNodeID ID;
- DependentNameType::Profile(ID, Keyword, NNS, TemplateId);
+ DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
+ Name, NumArgs, Args);
void *InsertPos = 0;
- DependentNameType *T
- = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
+ DependentTemplateSpecializationType *T
+ = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
- if (Canon.isNull()) {
- NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
- QualType CanonType = getCanonicalType(QualType(TemplateId, 0));
- ElaboratedTypeKeyword CanonKeyword = Keyword;
- if (Keyword == ETK_None)
- CanonKeyword = ETK_Typename;
- if (CanonNNS != NNS || CanonKeyword != Keyword ||
- CanonType != QualType(TemplateId, 0)) {
- const TemplateSpecializationType *CanonTemplateId
- = CanonType->getAs<TemplateSpecializationType>();
- assert(CanonTemplateId &&
- "Canonical type must also be a template specialization type");
- Canon = getDependentNameType(CanonKeyword, CanonNNS, CanonTemplateId);
- }
-
- DependentNameType *CheckT
- = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!CheckT && "Typename canonical type is broken"); (void)CheckT;
- }
+ NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+
+ ElaboratedTypeKeyword CanonKeyword = Keyword;
+ if (Keyword == ETK_None) CanonKeyword = ETK_Typename;
- T = new (*this) DependentNameType(Keyword, NNS, TemplateId, Canon);
+ bool AnyNonCanonArgs = false;
+ llvm::SmallVector<TemplateArgument, 16> CanonArgs(NumArgs);
+ for (unsigned I = 0; I != NumArgs; ++I) {
+ CanonArgs[I] = getCanonicalTemplateArgument(Args[I]);
+ if (!CanonArgs[I].structurallyEquals(Args[I]))
+ AnyNonCanonArgs = true;
+ }
+
+ QualType Canon;
+ if (AnyNonCanonArgs || CanonNNS != NNS || CanonKeyword != Keyword) {
+ Canon = getDependentTemplateSpecializationType(CanonKeyword, CanonNNS,
+ Name, NumArgs,
+ CanonArgs.data());
+
+ // Find the insert position again.
+ DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
+ }
+
+ void *Mem = Allocate((sizeof(DependentTemplateSpecializationType) +
+ sizeof(TemplateArgument) * NumArgs),
+ TypeAlignment);
+ T = new (Mem) DependentTemplateSpecializationType(*this, Keyword, NNS,
+ Name, NumArgs, Args, Canon);
Types.push_back(T);
- DependentNameTypes.InsertNode(T, InsertPos);
+ DependentTemplateSpecializationTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
}
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jun 10 19:33:02 2010
@@ -73,6 +73,7 @@
// FIXME: TemplateSpecializationType
QualType VisitElaboratedType(ElaboratedType *T);
// FIXME: DependentNameType
+ // FIXME: DependentTemplateSpecializationType
QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
QualType VisitObjCObjectType(ObjCObjectType *T);
QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
@@ -619,14 +620,32 @@
if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
Typename2->getIdentifier()))
return false;
- if (!IsStructurallyEquivalent(Context,
- QualType(Typename1->getTemplateId(), 0),
- QualType(Typename2->getTemplateId(), 0)))
- return false;
break;
}
+ case Type::DependentTemplateSpecialization: {
+ const DependentTemplateSpecializationType *Spec1 =
+ cast<DependentTemplateSpecializationType>(T1);
+ const DependentTemplateSpecializationType *Spec2 =
+ cast<DependentTemplateSpecializationType>(T2);
+ if (!IsStructurallyEquivalent(Context,
+ Spec1->getQualifier(),
+ Spec2->getQualifier()))
+ return false;
+ if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
+ Spec2->getIdentifier()))
+ return false;
+ if (Spec1->getNumArgs() != Spec2->getNumArgs())
+ return false;
+ for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context,
+ Spec1->getArg(I), Spec2->getArg(I)))
+ return false;
+ }
+ break;
+ }
+
case Type::ObjCInterface: {
const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Thu Jun 10 19:33:02 2010
@@ -90,6 +90,33 @@
}
}
+bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
+ if (getKind() != Other.getKind()) return false;
+
+ switch (getKind()) {
+ case Null:
+ case Type:
+ case Declaration:
+ case Template:
+ case Expression:
+ return TypeOrValue == Other.TypeOrValue;
+
+ case Integral:
+ return getIntegralType() == Other.getIntegralType() &&
+ *getAsIntegral() == *Other.getAsIntegral();
+
+ case Pack:
+ if (Args.NumArgs != Other.Args.NumArgs) return false;
+ for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
+ if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
+ return false;
+ return true;
+ }
+
+ // Suppress warnings.
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// TemplateArgumentLoc Implementation
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Jun 10 19:33:02 2010
@@ -768,6 +768,7 @@
case TemplateSpecialization:
case Elaborated:
case DependentName:
+ case DependentTemplateSpecialization:
case ObjCInterface:
case ObjCObject:
case ObjCObjectPointer: // FIXME: object pointers aren't really specifiers
@@ -856,12 +857,56 @@
}
}
+ElaboratedType::~ElaboratedType() {}
+DependentNameType::~DependentNameType() {}
+DependentTemplateSpecializationType::~DependentTemplateSpecializationType() {}
+
+void DependentTemplateSpecializationType::Destroy(ASTContext &C) {
+ for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+ // FIXME: Not all expressions get cloned, so we can't yet perform
+ // this destruction.
+ // if (Expr *E = getArg(Arg).getAsExpr())
+ // E->Destroy(C);
+ }
+}
+
+DependentTemplateSpecializationType::DependentTemplateSpecializationType(
+ ASTContext &Context, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS, const IdentifierInfo *Name,
+ unsigned NumArgs, const TemplateArgument *Args,
+ QualType Canon)
+ : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true),
+ Context(Context), NNS(NNS), Name(Name), NumArgs(NumArgs) {
+ assert(NNS && NNS->isDependent() &&
+ "DependentTemplateSpecializatonType requires dependent qualifier");
+ for (unsigned I = 0; I != NumArgs; ++I)
+ new (&getArgBuffer()[I]) TemplateArgument(Args[I]);
+}
+
+void
+DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+ ASTContext &Context,
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *Qualifier,
+ const IdentifierInfo *Name,
+ unsigned NumArgs,
+ const TemplateArgument *Args) {
+ ID.AddInteger(Keyword);
+ ID.AddPointer(Qualifier);
+ ID.AddPointer(Name);
+ for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
+ Args[Idx].Profile(ID, Context);
+}
+
bool Type::isElaboratedTypeSpecifier() const {
ElaboratedTypeKeyword Keyword;
if (const ElaboratedType *Elab = dyn_cast<ElaboratedType>(this))
Keyword = Elab->getKeyword();
else if (const DependentNameType *DepName = dyn_cast<DependentNameType>(this))
Keyword = DepName->getKeyword();
+ else if (const DependentTemplateSpecializationType *DepTST =
+ dyn_cast<DependentTemplateSpecializationType>(this))
+ Keyword = DepTST->getKeyword();
else
return false;
@@ -1113,17 +1158,6 @@
}
}
-TemplateSpecializationType::iterator
-TemplateSpecializationType::end() const {
- return begin() + getNumArgs();
-}
-
-const TemplateArgument &
-TemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
void
TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
TemplateName T,
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Jun 10 19:33:02 2010
@@ -580,15 +580,31 @@
T->getQualifier()->print(OS, Policy);
- if (const IdentifierInfo *Ident = T->getIdentifier())
- OS << Ident->getName();
- else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
- Spec->getTemplateName().print(OS, Policy, true);
- OS << TemplateSpecializationType::PrintTemplateArgumentList(
- Spec->getArgs(),
- Spec->getNumArgs(),
+ OS << T->getIdentifier()->getName();
+ }
+
+ if (S.empty())
+ S.swap(MyString);
+ else
+ S = MyString + ' ' + S;
+}
+
+void TypePrinter::PrintDependentTemplateSpecialization(
+ const DependentTemplateSpecializationType *T, std::string &S) {
+ std::string MyString;
+ {
+ llvm::raw_string_ostream OS(MyString);
+
+ OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+ if (T->getKeyword() != ETK_None)
+ OS << " ";
+
+ T->getQualifier()->print(OS, Policy);
+ OS << T->getIdentifier()->getName();
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ T->getArgs(),
+ T->getNumArgs(),
Policy);
- }
}
if (S.empty())
Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Thu Jun 10 19:33:02 2010
@@ -1369,21 +1369,25 @@
void CXXNameMangler::mangleType(const DependentNameType *T) {
// Typename types are always nested
Out << 'N';
- if (T->getIdentifier()) {
- mangleUnresolvedScope(T->getQualifier());
- mangleSourceName(T->getIdentifier());
- } else {
- const TemplateSpecializationType *TST = T->getTemplateId();
+ mangleUnresolvedScope(T->getQualifier());
+ mangleSourceName(T->getIdentifier());
+ Out << 'E';
+}
- mangleTemplatePrefix(TST->getTemplateName());
-
- // FIXME: GCC does not appear to mangle the template arguments when
- // the template in question is a dependent template name. Should we
- // emulate that badness?
- mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
- TST->getNumArgs());
- }
-
+void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
+ // Dependently-scoped template types are always nested
+ Out << 'N';
+
+ // TODO: avoid making this TemplateName.
+ TemplateName Prefix =
+ getASTContext().getDependentTemplateName(T->getQualifier(),
+ T->getIdentifier());
+ mangleTemplatePrefix(Prefix);
+
+ // FIXME: GCC does not appear to mangle the template arguments when
+ // the template in question is a dependent template name. Should we
+ // emulate that badness?
+ mangleTemplateArgs(Prefix, T->getArgs(), T->getNumArgs());
Out << 'E';
}
Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Jun 10 19:33:02 2010
@@ -2367,6 +2367,18 @@
TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
+void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc(
+ DependentTemplateSpecializationTypeLoc TL) {
+ TL.setKeywordLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ TL.setQualifierRange(Reader.ReadSourceRange(Record, Idx));
+ TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+ TL.setArgLocInfo(I,
+ Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(I).getKind(),
+ Record, Idx));
+}
void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Jun 10 19:33:02 2010
@@ -408,6 +408,16 @@
Writer.AddSourceRange(TL.getQualifierRange(), Record);
Writer.AddSourceLocation(TL.getNameLoc(), Record);
}
+void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
+ DependentTemplateSpecializationTypeLoc TL) {
+ Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
+ Writer.AddSourceRange(TL.getQualifierRange(), Record);
+ Writer.AddSourceLocation(TL.getNameLoc(), Record);
+ Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+ Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+ Writer.AddTemplateArgumentLoc(TL.getArgLoc(I), Record);
+}
void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record);
}
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jun 10 19:33:02 2010
@@ -87,8 +87,8 @@
if (!isClassName)
return 0;
- // We know from the grammar that this name refers to a type, so build a
- // DependentNameType node to describe the type.
+ // We know from the grammar that this name refers to a type,
+ // so build a dependent node to describe the type.
return CheckTypenameType(ETK_None,
(NestedNameSpecifier *)SS->getScopeRep(), II,
SourceLocation(), SS->getRange(), NameLoc
@@ -196,12 +196,6 @@
} else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
T = Context.getObjCInterfaceType(IDecl);
- } else if (UnresolvedUsingTypenameDecl *UUDecl =
- dyn_cast<UnresolvedUsingTypenameDecl>(IIDecl)) {
- // FIXME: preserve source structure information.
- T = Context.getDependentNameType(ETK_None,
- UUDecl->getTargetNestedNameSpecifier(),
- &II);
} else {
// If it's not plausibly a type, suppress diagnostics.
Result.suppressDiagnostics();
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jun 10 19:33:02 2010
@@ -5288,15 +5288,31 @@
return CreateLocInfoType(T, TSI).getAsOpaquePtr();
}
- T = Context.getDependentNameType(ETK_Typename, NNS,
- cast<TemplateSpecializationType>(T));
+ // TODO: it's really silly that we make a template specialization
+ // type earlier only to drop it again here.
+ TemplateSpecializationType *TST = cast<TemplateSpecializationType>(T);
+ DependentTemplateName *DTN =
+ TST->getTemplateName().getAsDependentTemplateName();
+ assert(DTN && "dependent template has non-dependent name?");
+ T = Context.getDependentTemplateSpecializationType(ETK_Typename, NNS,
+ DTN->getIdentifier(),
+ TST->getNumArgs(),
+ TST->getArgs());
TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
- DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc());
+ DependentTemplateSpecializationTypeLoc TL =
+ cast<DependentTemplateSpecializationTypeLoc>(TSI->getTypeLoc());
+ if (InnerTSI) {
+ TemplateSpecializationTypeLoc TSTL =
+ cast<TemplateSpecializationTypeLoc>(InnerTSI->getTypeLoc());
+ TL.setLAngleLoc(TSTL.getLAngleLoc());
+ TL.setRAngleLoc(TSTL.getRAngleLoc());
+ for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I)
+ TL.setArgLocInfo(I, TSTL.getArgLocInfo(I));
+ } else {
+ TL.initializeLocal(SourceLocation());
+ }
TL.setKeywordLoc(TypenameLoc);
TL.setQualifierRange(SS.getRange());
-
- // FIXME: the inner type is a template here; remember its full source info
- TL.setNameLoc(InnerTSI ? InnerTSI->getTypeLoc().getBeginLoc() : TemplateLoc);
return CreateLocInfoType(T, TSI).getAsOpaquePtr();
}
@@ -5425,87 +5441,9 @@
Sema::OwningExprResult TransformExpr(Expr *E) {
return getSema().Owned(E->Retain());
}
-
- /// \brief Transforms a typename type by determining whether the type now
- /// refers to a member of the current instantiation, and then
- /// type-checking and building an ElaboratedType (when possible).
- QualType TransformDependentNameType(TypeLocBuilder &TLB,
- DependentNameTypeLoc TL,
- QualType ObjectType);
};
}
-QualType
-CurrentInstantiationRebuilder::TransformDependentNameType(TypeLocBuilder &TLB,
- DependentNameTypeLoc TL,
- QualType ObjectType) {
- DependentNameType *T = TL.getTypePtr();
-
- NestedNameSpecifier *NNS
- = TransformNestedNameSpecifier(T->getQualifier(),
- TL.getQualifierRange(),
- ObjectType);
- if (!NNS)
- return QualType();
-
- // If the nested-name-specifier did not change, and we cannot compute the
- // context corresponding to the nested-name-specifier, then this
- // typename type will not change; exit early.
- CXXScopeSpec SS;
- SS.setRange(TL.getQualifierRange());
- SS.setScopeRep(NNS);
-
- QualType Result;
- if (NNS == T->getQualifier() && getSema().computeDeclContext(SS) == 0)
- Result = QualType(T, 0);
-
- // Rebuild the typename type, which will probably turn into a
- // ElaboratedType.
- else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
- QualType NewTemplateId
- = TransformType(QualType(TemplateId, 0));
- if (NewTemplateId.isNull())
- return QualType();
-
- if (NNS == T->getQualifier() &&
- NewTemplateId == QualType(TemplateId, 0))
- Result = QualType(T, 0);
- else
- Result = getDerived().RebuildDependentNameType(T->getKeyword(),
- NNS, NewTemplateId);
- } else
- Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
- T->getIdentifier(),
- TL.getKeywordLoc(),
- TL.getQualifierRange(),
- TL.getNameLoc());
-
- if (Result.isNull())
- return QualType();
-
- if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
- QualType NamedT = ElabT->getNamedType();
- if (isa<TemplateSpecializationType>(NamedT)) {
- TemplateSpecializationTypeLoc NamedTLoc
- = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
- // FIXME: fill locations
- NamedTLoc.initializeLocal(TL.getNameLoc());
- } else {
- TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
- }
- ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
- NewTL.setKeywordLoc(TL.getKeywordLoc());
- NewTL.setQualifierRange(TL.getQualifierRange());
- }
- else {
- DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
- NewTL.setKeywordLoc(TL.getKeywordLoc());
- NewTL.setQualifierRange(TL.getQualifierRange());
- NewTL.setNameLoc(TL.getNameLoc());
- }
- return Result;
-}
-
/// \brief Rebuilds a type within the context of the current instantiation.
///
/// The type \p T is part of the type of an out-of-line member definition of
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Jun 10 19:33:02 2010
@@ -2624,6 +2624,18 @@
OnlyDeduced, Depth, Used);
break;
+ case Type::DependentTemplateSpecialization: {
+ const DependentTemplateSpecializationType *Spec
+ = cast<DependentTemplateSpecializationType>(T);
+ if (!OnlyDeduced)
+ MarkUsedTemplateParameters(SemaRef, Spec->getQualifier(),
+ OnlyDeduced, Depth, Used);
+ for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
+ MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth,
+ Used);
+ break;
+ }
+
case Type::TypeOf:
if (!OnlyDeduced)
MarkUsedTemplateParameters(SemaRef,
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jun 10 19:33:02 2010
@@ -1492,6 +1492,28 @@
// FIXME: load appropriate source location.
TL.setNameLoc(DS.getTypeSpecTypeLoc());
}
+ void VisitDependentTemplateSpecializationTypeLoc(
+ DependentTemplateSpecializationTypeLoc TL) {
+ ElaboratedTypeKeyword Keyword
+ = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
+ if (Keyword == ETK_Typename) {
+ TypeSourceInfo *TInfo = 0;
+ Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+ if (TInfo) {
+ TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
+ TInfo->getTypeLoc()));
+ return;
+ }
+ }
+ TL.initializeLocal(SourceLocation());
+ TL.setKeywordLoc(Keyword != ETK_None
+ ? DS.getTypeSpecTypeLoc()
+ : SourceLocation());
+ const CXXScopeSpec& SS = DS.getTypeSpecScope();
+ TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
+ // FIXME: load appropriate source location.
+ TL.setNameLoc(DS.getTypeSpecTypeLoc());
+ }
void VisitTypeLoc(TypeLoc TL) {
// FIXME: add other typespec types and change this to an assert.
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=105801&r1=105800&r2=105801&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 10 19:33:02 2010
@@ -533,16 +533,27 @@
/// By default, builds a new DependentNameType type from the
/// nested-name-specifier and the given type. Subclasses may override
/// this routine to provide different behavior.
- QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType T) {
- if (NNS->isDependent()) {
- // If the name is still dependent, just build a new dependent name type.
- CXXScopeSpec SS;
- SS.setScopeRep(NNS);
- if (!SemaRef.computeDeclContext(SS))
- return SemaRef.Context.getDependentNameType(Keyword, NNS,
- cast<TemplateSpecializationType>(T));
- }
+ QualType RebuildDependentTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo &Args) {
+ // Rebuild the template name.
+ // TODO: avoid TemplateName abstraction
+ TemplateName InstName =
+ getDerived().RebuildTemplateName(NNS, *Name, QualType());
+
+ // If it's still dependent, make a dependent specialization.
+ if (InstName.getAsDependentTemplateName())
+ return SemaRef.Context.getDependentTemplateSpecializationType(
+ Keyword, NNS, Name, Args);
+
+ // Otherwise, make an elaborated type wrapping a non-dependent
+ // specialization.
+ QualType T =
+ getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
+ if (T.isNull()) return QualType();
return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
}
@@ -3298,46 +3309,23 @@
if (!NNS)
return QualType();
- QualType Result;
-
- if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
- QualType NewTemplateId
- = getDerived().TransformType(QualType(TemplateId, 0));
- if (NewTemplateId.isNull())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- NNS == T->getQualifier() &&
- NewTemplateId == QualType(TemplateId, 0))
- return QualType(T, 0);
-
- Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
- NewTemplateId);
- } else {
- Result = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
- T->getIdentifier(),
- TL.getKeywordLoc(),
- TL.getQualifierRange(),
- TL.getNameLoc());
- }
+ QualType Result
+ = getDerived().RebuildDependentNameType(T->getKeyword(), NNS,
+ T->getIdentifier(),
+ TL.getKeywordLoc(),
+ TL.getQualifierRange(),
+ TL.getNameLoc());
if (Result.isNull())
return QualType();
if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
QualType NamedT = ElabT->getNamedType();
- if (isa<TemplateSpecializationType>(NamedT)) {
- TemplateSpecializationTypeLoc NamedTLoc
- = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
- // FIXME: fill locations
- NamedTLoc.initializeLocal(TL.getNameLoc());
- } else {
- TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
- }
+ TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
+
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
- }
- else {
+ } else {
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
NewTL.setQualifierRange(TL.getQualifierRange());
@@ -3347,6 +3335,61 @@
}
template<typename Derived>
+QualType TreeTransform<Derived>::
+ TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+ DependentTemplateSpecializationTypeLoc TL,
+ QualType ObjectType) {
+ DependentTemplateSpecializationType *T = TL.getTypePtr();
+
+ NestedNameSpecifier *NNS
+ = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
+ TL.getQualifierRange(),
+ ObjectType);
+ if (!NNS)
+ return QualType();
+
+ TemplateArgumentListInfo NewTemplateArgs;
+ NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
+ NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
+
+ for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I) {
+ TemplateArgumentLoc Loc;
+ if (getDerived().TransformTemplateArgument(TL.getArgLoc(I), Loc))
+ return QualType();
+ NewTemplateArgs.addArgument(Loc);
+ }
+
+ QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
+ T->getKeyword(),
+ NNS,
+ T->getIdentifier(),
+ TL.getNameLoc(),
+ NewTemplateArgs);
+ if (Result.isNull())
+ return QualType();
+
+ if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
+ QualType NamedT = ElabT->getNamedType();
+
+ // Copy information relevant to the template specialization.
+ TemplateSpecializationTypeLoc NamedTL
+ = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
+ NamedTL.setLAngleLoc(TL.getLAngleLoc());
+ NamedTL.setRAngleLoc(TL.getRAngleLoc());
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+ NamedTL.setArgLocInfo(I, TL.getArgLocInfo(I));
+
+ // Copy information relevant to the elaborated type.
+ ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+ NewTL.setKeywordLoc(TL.getKeywordLoc());
+ NewTL.setQualifierRange(TL.getQualifierRange());
+ } else {
+ TLB.pushFullCopy(TL);
+ }
+ return Result;
+}
+
+template<typename Derived>
QualType
TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
ObjCInterfaceTypeLoc TL,
More information about the cfe-commits
mailing list