Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 7536dd5

Browse files
committed
Introduce a new type, PackExpansionType, to capture types that are
pack expansions, e.g. given template<typename... Types> struct tuple; template<typename... Types> struct tuple_of_refs { typedef tuple<Types&...> types; }; the type of the "types" typedef is a PackExpansionType whose pattern is Types&. This commit introduces support for creating pack expansions for template type arguments, as above, but not for any other kind of pack expansion, nor for any form of instantiation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122223 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d3d3be9 commit 7536dd5

23 files changed

+316
-7
lines changed

include/clang/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class ASTContext {
106106
llvm::FoldingSet<DependentNameType> DependentNameTypes;
107107
llvm::ContextualFoldingSet<DependentTemplateSpecializationType, ASTContext&>
108108
DependentTemplateSpecializationTypes;
109+
llvm::FoldingSet<PackExpansionType> PackExpansionTypes;
109110
llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
110111
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
111112

@@ -697,6 +698,8 @@ class ASTContext {
697698
unsigned NumArgs,
698699
const TemplateArgument *Args);
699700

701+
QualType getPackExpansionType(QualType Pattern);
702+
700703
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
701704

702705
QualType getObjCObjectType(QualType Base,

include/clang/AST/RecursiveASTVisitor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,10 @@ DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
738738
TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
739739
})
740740

741+
DEF_TRAVERSE_TYPE(PackExpansionType, {
742+
TRY_TO(TraverseType(T->getPattern()));
743+
})
744+
741745
DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
742746

743747
DEF_TRAVERSE_TYPE(ObjCObjectType, {
@@ -943,6 +947,10 @@ DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
943947
}
944948
})
945949

950+
DEF_TRAVERSE_TYPELOC(PackExpansionType, {
951+
TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
952+
})
953+
946954
DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
947955

948956
DEF_TRAVERSE_TYPELOC(ObjCObjectType, {

include/clang/AST/Type.h

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ namespace clang {
9292
class TemplateArgument;
9393
class TemplateArgumentLoc;
9494
class TemplateArgumentListInfo;
95-
class Type;
9695
class ElaboratedType;
9796
struct PrintingPolicy;
9897

@@ -3191,6 +3190,65 @@ class DependentTemplateSpecializationType :
31913190
}
31923191
};
31933192

3193+
/// \brief Represents a pack expansion of types.
3194+
///
3195+
/// Pack expansions are part of C++0x variadic templates. A pack
3196+
/// expansion contains a pattern, which itself contains one or more
3197+
/// "unexpanded" parameter packs. When instantiated, a pack expansion
3198+
/// produces a series of types, each instantiated from the pattern of
3199+
/// the expansion, where the Ith instantiation of the pattern uses the
3200+
/// Ith arguments bound to each of the unexpanded parameter packs. The
3201+
/// pack expansion is considered to "expand" these unexpanded
3202+
/// parameter packs.
3203+
///
3204+
/// \code
3205+
/// template<typename ...Types> struct tuple;
3206+
///
3207+
/// template<typename ...Types>
3208+
/// struct tuple_of_references {
3209+
/// typedef tuple<Types&...> type;
3210+
/// };
3211+
/// \endcode
3212+
///
3213+
/// Here, the pack expansion \c Types&... is represented via a
3214+
/// PackExpansionType whose pattern is Types&.
3215+
class PackExpansionType : public Type, public llvm::FoldingSetNode {
3216+
/// \brief The pattern of the pack expansion.
3217+
QualType Pattern;
3218+
3219+
PackExpansionType(QualType Pattern, QualType Canon)
3220+
: Type(PackExpansion, Canon, /*Dependent=*/true,
3221+
/*VariableModified=*/Pattern->isVariablyModifiedType(),
3222+
/*ContainsUnexpandedParameterPack=*/false),
3223+
Pattern(Pattern) { }
3224+
3225+
friend class ASTContext; // ASTContext creates these
3226+
3227+
public:
3228+
/// \brief Retrieve the pattern of this pack expansion, which is the
3229+
/// type that will be repeatedly instantiated when instantiating the
3230+
/// pack expansion itself.
3231+
QualType getPattern() const { return Pattern; }
3232+
3233+
bool isSugared() const { return false; }
3234+
QualType desugar() const { return QualType(this, 0); }
3235+
3236+
void Profile(llvm::FoldingSetNodeID &ID) {
3237+
Profile(ID, getPattern());
3238+
}
3239+
3240+
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern) {
3241+
ID.AddPointer(Pattern.getAsOpaquePtr());
3242+
}
3243+
3244+
static bool classof(const Type *T) {
3245+
return T->getTypeClass() == PackExpansion;
3246+
}
3247+
static bool classof(const PackExpansionType *T) {
3248+
return true;
3249+
}
3250+
};
3251+
31943252
/// ObjCObjectType - Represents a class type in Objective C.
31953253
/// Every Objective C type is a combination of a base type and a
31963254
/// list of protocols.

include/clang/AST/TypeLoc.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,40 @@ class DependentTemplateSpecializationTypeLoc :
14461446
}
14471447
};
14481448

1449+
1450+
struct PackExpansionTypeLocInfo {
1451+
SourceLocation EllipsisLoc;
1452+
};
1453+
1454+
class PackExpansionTypeLoc
1455+
: public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1456+
PackExpansionType, PackExpansionTypeLocInfo> {
1457+
public:
1458+
SourceLocation getEllipsisLoc() const {
1459+
return this->getLocalData()->EllipsisLoc;
1460+
}
1461+
1462+
void setEllipsisLoc(SourceLocation Loc) {
1463+
this->getLocalData()->EllipsisLoc = Loc;
1464+
}
1465+
1466+
SourceRange getLocalSourceRange() const {
1467+
return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1468+
}
1469+
1470+
void initializeLocal(SourceLocation Loc) {
1471+
setEllipsisLoc(Loc);
1472+
}
1473+
1474+
TypeLoc getPatternLoc() const {
1475+
return getInnerTypeLoc();
1476+
}
1477+
1478+
QualType getInnerType() const {
1479+
return this->getTypePtr()->getPattern();
1480+
}
1481+
};
1482+
14491483
}
14501484

14511485
#endif

include/clang/AST/TypeNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
9494
DEPENDENT_TYPE(InjectedClassName, Type)
9595
DEPENDENT_TYPE(DependentName, Type)
9696
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
97+
DEPENDENT_TYPE(PackExpansion, Type)
9798
TYPE(ObjCObject, Type)
9899
TYPE(ObjCInterface, ObjCObjectType)
99100
TYPE(ObjCObjectPointer, Type)

include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,13 @@ def err_unexpanded_parameter_pack_3_or_more : Error<
18531853
"non-type template parameter type|exception type}0 "
18541854
"contains unexpanded parameter packs %1, %2, ...">;
18551855

1856+
def err_pack_expansion_without_parameter_packs : Error<
1857+
"pack expansion does not contain any unexpanded parameter packs">;
1858+
def err_pack_expansion_unsupported : Error<
1859+
"clang does not yet support %select{non-type|template}0 pack expansions">;
1860+
def err_pack_expansion_instantiation_unsupported : Error<
1861+
"clang cannot yet instantiate pack expansions">;
1862+
18561863
def err_unexpected_typedef : Error<
18571864
"unexpected type name %0: expected expression">;
18581865
def err_unexpected_namespace : Error<

include/clang/Sema/ParsedTemplate.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ namespace clang {
3232
Template
3333
};
3434

35-
/// \brief Build an empty template argument. This template argument
35+
/// \brief Build an empty template argument.
36+
///
37+
/// This template argument is invalid.
3638
ParsedTemplateArgument() : Kind(Type), Arg(0) { }
3739

3840
/// \brief Create a template type argument or non-type template argument.

include/clang/Sema/Sema.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3236,6 +3236,25 @@ class Sema {
32363236
TemplateName Template,
32373237
UnexpandedParameterPackContext UPPC);
32383238

3239+
/// \brief Invoked when parsing a template argument followed by an
3240+
/// ellipsis, which creates a pack expansion.
3241+
///
3242+
/// \param Arg The template argument preceding the ellipsis, which
3243+
/// may already be invalid.
3244+
///
3245+
/// \param EllipsisLoc The location of the ellipsis.
3246+
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg,
3247+
SourceLocation EllipsisLoc);
3248+
3249+
/// \brief Invoked when parsing a type follows by an ellipsis, which
3250+
/// creates a pack expansion.
3251+
///
3252+
/// \param Type The type preceding the ellipsis, which will become
3253+
/// the pattern of the pack expansion.
3254+
///
3255+
/// \param EllipsisLoc The location of the ellipsis.
3256+
TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc);
3257+
32393258
/// \brief Describes the result of template argument deduction.
32403259
///
32413260
/// The TemplateDeductionResult enumeration describes the result of

include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,9 @@ namespace clang {
551551
/// \brief A DependentSizedArrayType record.
552552
TYPE_DEPENDENT_SIZED_ARRAY = 33,
553553
/// \brief A ParenType record.
554-
TYPE_PAREN = 34
554+
TYPE_PAREN = 34,
555+
/// \brief A PackExpansionType record.
556+
TYPE_PACK_EXPANSION = 35
555557
};
556558

557559
/// \brief The type IDs for special types constructed by semantic

lib/AST/ASTContext.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,32 @@ ASTContext::getDependentTemplateSpecializationType(
22162216
return QualType(T, 0);
22172217
}
22182218

2219+
QualType ASTContext::getPackExpansionType(QualType Pattern) {
2220+
llvm::FoldingSetNodeID ID;
2221+
PackExpansionType::Profile(ID, Pattern);
2222+
2223+
assert(Pattern->containsUnexpandedParameterPack() &&
2224+
"Pack expansions must expand one or more parameter packs");
2225+
void *InsertPos = 0;
2226+
PackExpansionType *T
2227+
= PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
2228+
if (T)
2229+
return QualType(T, 0);
2230+
2231+
QualType Canon;
2232+
if (!Pattern.isCanonical()) {
2233+
Canon = getPackExpansionType(getCanonicalType(Pattern));
2234+
2235+
// Find the insert position again.
2236+
PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
2237+
}
2238+
2239+
T = new (*this) PackExpansionType(Pattern, Canon);
2240+
Types.push_back(T);
2241+
PackExpansionTypes.InsertNode(T, InsertPos);
2242+
return QualType(T, 0);
2243+
}
2244+
22192245
/// CmpProtocolNames - Comparison predicate for sorting protocols
22202246
/// alphabetically.
22212247
static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,

0 commit comments

Comments
 (0)