Skip to content

Commit c392f37

Browse files
committed
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. llvm-svn: 105801
1 parent d85248b commit c392f37

20 files changed

+607
-238
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class ASTContext {
9898
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
9999
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
100100
llvm::FoldingSet<DependentNameType> DependentNameTypes;
101+
llvm::FoldingSet<DependentTemplateSpecializationType>
102+
DependentTemplateSpecializationTypes;
101103
llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
102104
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
103105

@@ -621,10 +623,16 @@ class ASTContext {
621623
NestedNameSpecifier *NNS,
622624
const IdentifierInfo *Name,
623625
QualType Canon = QualType());
624-
QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
625-
NestedNameSpecifier *NNS,
626-
const TemplateSpecializationType *TemplateId,
627-
QualType Canon = QualType());
626+
627+
QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
628+
NestedNameSpecifier *NNS,
629+
const IdentifierInfo *Name,
630+
const TemplateArgumentListInfo &Args);
631+
QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
632+
NestedNameSpecifier *NNS,
633+
const IdentifierInfo *Name,
634+
unsigned NumArgs,
635+
const TemplateArgument *Args);
628636

629637
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
630638

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,12 @@ DEF_TRAVERSE_TYPE(ElaboratedType, {
586586
})
587587

588588
DEF_TRAVERSE_TYPE(DependentNameType, {
589-
if (T->getQualifier()) {
590-
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
591-
}
589+
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
590+
})
592591

593-
if (T->getTemplateId()) {
594-
TRY_TO(VisitTemplateSpecializationType(
595-
const_cast<TemplateSpecializationType *>(T->getTemplateId())));
596-
}
592+
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
593+
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
594+
TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
597595
})
598596

599597
DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })

clang/include/clang/AST/TemplateBase.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ class TemplateArgument {
256256
return Args.NumArgs;
257257
}
258258

259+
/// Determines whether two template arguments are superficially the
260+
/// same.
261+
bool structurallyEquals(const TemplateArgument &Other) const;
262+
259263
/// \brief Construct a template argument pack.
260264
void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
261265

@@ -476,6 +480,28 @@ class TemplateArgumentListInfo {
476480

477481
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
478482
const TemplateArgument &Arg);
483+
484+
inline TemplateSpecializationType::iterator
485+
TemplateSpecializationType::end() const {
486+
return getArgs() + getNumArgs();
487+
}
488+
489+
inline DependentTemplateSpecializationType::iterator
490+
DependentTemplateSpecializationType::end() const {
491+
return getArgs() + getNumArgs();
492+
}
493+
494+
inline const TemplateArgument &
495+
TemplateSpecializationType::getArg(unsigned Idx) const {
496+
assert(Idx < getNumArgs() && "Template argument out of range");
497+
return getArgs()[Idx];
498+
}
499+
500+
inline const TemplateArgument &
501+
DependentTemplateSpecializationType::getArg(unsigned Idx) const {
502+
assert(Idx < getNumArgs() && "Template argument out of range");
503+
return getArgs()[Idx];
504+
}
479505

480506
} // end namespace clang
481507

clang/include/clang/AST/Type.h

Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,7 +2426,7 @@ class TemplateSpecializationType
24262426
// The bool is whether this is a current instantiation.
24272427
llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
24282428

2429-
/// \brief The name of the template being specialized.
2429+
/// \brief The name of the template being specialized.
24302430
TemplateName Template;
24312431

24322432
/// \brief - The number of template arguments named in this class
@@ -2476,7 +2476,7 @@ class TemplateSpecializationType
24762476
typedef const TemplateArgument * iterator;
24772477

24782478
iterator begin() const { return getArgs(); }
2479-
iterator end() const;
2479+
iterator end() const; // defined inline in TemplateBase.h
24802480

24812481
/// \brief Retrieve the name of the template that we are specializing.
24822482
TemplateName getTemplateName() const { return Template; }
@@ -2491,7 +2491,7 @@ class TemplateSpecializationType
24912491

24922492
/// \brief Retrieve a specific template argument as a type.
24932493
/// \precondition @c isArgType(Arg)
2494-
const TemplateArgument &getArg(unsigned Idx) const;
2494+
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
24952495

24962496
bool isSugared() const {
24972497
return !isDependentType() || isCurrentInstantiation();
@@ -2682,6 +2682,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
26822682
friend class ASTContext; // ASTContext creates these
26832683

26842684
public:
2685+
~ElaboratedType();
26852686

26862687
/// \brief Retrieve the qualification on this type.
26872688
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2726,11 +2727,8 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
27262727
/// \brief The nested name specifier containing the qualifier.
27272728
NestedNameSpecifier *NNS;
27282729

2729-
typedef llvm::PointerUnion<const IdentifierInfo *,
2730-
const TemplateSpecializationType *> NameType;
2731-
27322730
/// \brief The type that this typename specifier refers to.
2733-
NameType Name;
2731+
const IdentifierInfo *Name;
27342732

27352733
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
27362734
const IdentifierInfo *Name, QualType CanonType)
@@ -2740,17 +2738,10 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
27402738
"DependentNameType requires a dependent nested-name-specifier");
27412739
}
27422740

2743-
DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
2744-
const TemplateSpecializationType *Ty, QualType CanonType)
2745-
: TypeWithKeyword(Keyword, DependentName, CanonType, true),
2746-
NNS(NNS), Name(Ty) {
2747-
assert(NNS->isDependent() &&
2748-
"DependentNameType requires a dependent nested-name-specifier");
2749-
}
2750-
27512741
friend class ASTContext; // ASTContext creates these
27522742

27532743
public:
2744+
virtual ~DependentNameType();
27542745

27552746
/// \brief Retrieve the qualification on this type.
27562747
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2762,13 +2753,7 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
27622753
/// form of the original typename was terminated by an identifier,
27632754
/// e.g., "typename T::type".
27642755
const IdentifierInfo *getIdentifier() const {
2765-
return Name.dyn_cast<const IdentifierInfo *>();
2766-
}
2767-
2768-
/// \brief Retrieve the type named by the typename specifier as a
2769-
/// type specialization.
2770-
const TemplateSpecializationType *getTemplateId() const {
2771-
return Name.dyn_cast<const TemplateSpecializationType *>();
2756+
return Name;
27722757
}
27732758

27742759
bool isSugared() const { return false; }
@@ -2779,10 +2764,10 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
27792764
}
27802765

27812766
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
2782-
NestedNameSpecifier *NNS, NameType Name) {
2767+
NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
27832768
ID.AddInteger(Keyword);
27842769
ID.AddPointer(NNS);
2785-
ID.AddPointer(Name.getOpaqueValue());
2770+
ID.AddPointer(Name);
27862771
}
27872772

27882773
static bool classof(const Type *T) {
@@ -2791,6 +2776,88 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
27912776
static bool classof(const DependentNameType *T) { return true; }
27922777
};
27932778

2779+
/// DependentTemplateSpecializationType - Represents a template
2780+
/// specialization type whose template cannot be resolved, e.g.
2781+
/// A<T>::template B<T>
2782+
class DependentTemplateSpecializationType :
2783+
public TypeWithKeyword, public llvm::FoldingSetNode {
2784+
2785+
/// The AST context. Unfortunately required in order to profile
2786+
/// template arguments.
2787+
ASTContext &Context;
2788+
2789+
/// \brief The nested name specifier containing the qualifier.
2790+
NestedNameSpecifier *NNS;
2791+
2792+
/// \brief The identifier of the template.
2793+
const IdentifierInfo *Name;
2794+
2795+
/// \brief - The number of template arguments named in this class
2796+
/// template specialization.
2797+
unsigned NumArgs;
2798+
2799+
const TemplateArgument *getArgBuffer() const {
2800+
return reinterpret_cast<const TemplateArgument*>(this+1);
2801+
}
2802+
TemplateArgument *getArgBuffer() {
2803+
return reinterpret_cast<TemplateArgument*>(this+1);
2804+
}
2805+
2806+
DependentTemplateSpecializationType(ASTContext &Context,
2807+
ElaboratedTypeKeyword Keyword,
2808+
NestedNameSpecifier *NNS,
2809+
const IdentifierInfo *Name,
2810+
unsigned NumArgs,
2811+
const TemplateArgument *Args,
2812+
QualType Canon);
2813+
2814+
virtual void Destroy(ASTContext& C);
2815+
2816+
friend class ASTContext; // ASTContext creates these
2817+
2818+
public:
2819+
virtual ~DependentTemplateSpecializationType();
2820+
2821+
NestedNameSpecifier *getQualifier() const { return NNS; }
2822+
const IdentifierInfo *getIdentifier() const { return Name; }
2823+
2824+
/// \brief Retrieve the template arguments.
2825+
const TemplateArgument *getArgs() const {
2826+
return getArgBuffer();
2827+
}
2828+
2829+
/// \brief Retrieve the number of template arguments.
2830+
unsigned getNumArgs() const { return NumArgs; }
2831+
2832+
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
2833+
2834+
typedef const TemplateArgument * iterator;
2835+
iterator begin() const { return getArgs(); }
2836+
iterator end() const; // inline in TemplateBase.h
2837+
2838+
bool isSugared() const { return false; }
2839+
QualType desugar() const { return QualType(this, 0); }
2840+
2841+
void Profile(llvm::FoldingSetNodeID &ID) {
2842+
Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs());
2843+
}
2844+
2845+
static void Profile(llvm::FoldingSetNodeID &ID,
2846+
ASTContext &Context,
2847+
ElaboratedTypeKeyword Keyword,
2848+
NestedNameSpecifier *Qualifier,
2849+
const IdentifierInfo *Name,
2850+
unsigned NumArgs,
2851+
const TemplateArgument *Args);
2852+
2853+
static bool classof(const Type *T) {
2854+
return T->getTypeClass() == DependentTemplateSpecialization;
2855+
}
2856+
static bool classof(const DependentTemplateSpecializationType *T) {
2857+
return true;
2858+
}
2859+
};
2860+
27942861
/// ObjCObjectType - Represents a class type in Objective C.
27952862
/// Every Objective C type is a combination of a base type and a
27962863
/// list of protocols.

0 commit comments

Comments
 (0)