summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp3
-rw-r--r--lib/AST/ASTContext.cpp19
-rw-r--r--lib/AST/ASTDiagnostic.cpp5
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp7
-rw-r--r--lib/AST/ItaniumMangle.cpp1
-rw-r--r--lib/AST/Type.cpp19
-rw-r--r--lib/AST/TypePrinter.cpp16
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp4
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp1
-rw-r--r--lib/Parse/ParseDecl.cpp40
-rw-r--r--lib/Sema/SemaExpr.cpp5
-rw-r--r--lib/Sema/SemaStmt.cpp8
-rw-r--r--lib/Sema/SemaType.cpp27
-rw-r--r--lib/Sema/TreeTransform.h27
-rw-r--r--lib/Serialization/ASTReader.cpp14
-rw-r--r--lib/Serialization/ASTWriter.cpp11
16 files changed, 12 insertions, 195 deletions
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index fdbe1d119a..a73b526ca8 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -68,9 +68,6 @@ public:
if (handleAttr(Attr, D))
break;
TL = Attr.getModifiedLoc();
- } else if (MacroQualifiedTypeLoc MDTL =
- TL.getAs<MacroQualifiedTypeLoc>()) {
- TL = MDTL.getInnerLoc();
} else if (ArrayTypeLoc Arr = TL.getAs<ArrayTypeLoc>()) {
TL = Arr.getElementLoc();
} else if (PointerTypeLoc PT = TL.getAs<PointerTypeLoc>()) {
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 6348885375..d0a790cad4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2047,10 +2047,6 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Paren:
return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
- case Type::MacroQualified:
- return getTypeInfo(
- cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr());
-
case Type::ObjCTypeParam:
return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
@@ -3933,7 +3929,7 @@ QualType ASTContext::getAttributedType(attr::Kind attrKind,
QualType canon = getCanonicalType(equivalentType);
type = new (*this, TypeAlignment)
- AttributedType(canon, attrKind, modifiedType, equivalentType);
+ AttributedType(canon, attrKind, modifiedType, equivalentType);
Types.push_back(type);
AttributedTypes.InsertNode(type, insertPos);
@@ -4214,19 +4210,6 @@ ASTContext::getParenType(QualType InnerType) const {
return QualType(T, 0);
}
-QualType
-ASTContext::getMacroQualifiedType(QualType UnderlyingTy,
- const IdentifierInfo *MacroII) const {
- QualType Canon = UnderlyingTy;
- if (!Canon.isCanonical())
- Canon = getCanonicalType(UnderlyingTy);
-
- auto *newType = new (*this, TypeAlignment)
- MacroQualifiedType(UnderlyingTy, Canon, MacroII);
- Types.push_back(newType);
- return QualType(newType, 0);
-}
-
QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 15df865852..61900aa4ac 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -41,11 +41,6 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = PT->desugar();
continue;
}
- // ... or a macro defined type ...
- if (const MacroQualifiedType *MDT = dyn_cast<MacroQualifiedType>(Ty)) {
- QT = MDT->desugar();
- continue;
- }
// ...or a substituted template type parameter ...
if (const SubstTemplateTypeParmType *ST =
dyn_cast<SubstTemplateTypeParmType>(Ty)) {
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index 567945c16c..71bbd82481 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -595,13 +595,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
- case Type::MacroQualified:
- if (!IsStructurallyEquivalent(
- Context, cast<MacroQualifiedType>(T1)->getUnderlyingType(),
- cast<MacroQualifiedType>(T2)->getUnderlyingType()))
- return false;
- break;
-
case Type::Typedef:
if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
cast<TypedefType>(T2)->getDecl()))
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 930537a934..3357756466 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1941,7 +1941,6 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::ObjCTypeParam:
case Type::Atomic:
case Type::Pipe:
- case Type::MacroQualified:
llvm_unreachable("type is illegal as a nested name specifier");
case Type::SubstTemplateTypeParmPack:
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 590e534fbd..adffe92f95 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -973,7 +973,6 @@ public:
SUGARED_TYPE_CLASS(Typedef)
SUGARED_TYPE_CLASS(ObjCTypeParam)
- SUGARED_TYPE_CLASS(MacroQualified)
QualType VisitAdjustedType(const AdjustedType *T) {
QualType originalType = recurse(T->getOriginalType());
@@ -1736,10 +1735,6 @@ namespace {
return Visit(T->getModifiedType());
}
- Type *VisitMacroQualifiedType(const MacroQualifiedType *T) {
- return Visit(T->getUnderlyingType());
- }
-
Type *VisitAdjustedType(const AdjustedType *T) {
return Visit(T->getOriginalType());
}
@@ -3165,20 +3160,6 @@ QualType TypedefType::desugar() const {
return getDecl()->getUnderlyingType();
}
-QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); }
-
-QualType MacroQualifiedType::getModifiedType() const {
- // Step over MacroQualifiedTypes from the same macro to find the type
- // ultimately qualified by the macro qualifier.
- QualType Inner = cast<AttributedType>(getUnderlyingType())->getModifiedType();
- while (auto *InnerMQT = dyn_cast<MacroQualifiedType>(Inner)) {
- if (InnerMQT->getMacroIdentifier() != getMacroIdentifier())
- break;
- Inner = InnerMQT->getModifiedType();
- }
- return Inner;
-}
-
TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
: Type(TypeOfExpr, can, E->isTypeDependent(),
E->isInstantiationDependent(),
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index fed39cadcb..82a2fa09c7 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -259,7 +259,6 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::Paren:
case Type::PackExpansion:
case Type::SubstTemplateTypeParm:
- case Type::MacroQualified:
CanPrefixQualifiers = false;
break;
@@ -964,21 +963,6 @@ void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
printTypeSpec(T->getDecl(), OS);
}
-void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
- raw_ostream &OS) {
- StringRef MacroName = T->getMacroIdentifier()->getName();
- OS << MacroName << " ";
-
- // Since this type is meant to print the macro instead of the whole attribute,
- // we trim any attributes and go directly to the original modified type.
- printBefore(T->getModifiedType(), OS);
-}
-
-void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,
- raw_ostream &OS) {
- printAfter(T->getModifiedType(), OS);
-}
-
void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}
void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 4c43c00cd5..3656602c3d 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2844,9 +2844,6 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
case Type::Paren:
T = cast<ParenType>(T)->getInnerType();
break;
- case Type::MacroQualified:
- T = cast<MacroQualifiedType>(T)->getUnderlyingType();
- break;
case Type::SubstTemplateTypeParm:
T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
break;
@@ -3026,7 +3023,6 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
case Type::DeducedTemplateSpecialization:
case Type::Elaborated:
case Type::Paren:
- case Type::MacroQualified:
case Type::SubstTemplateTypeParm:
case Type::TypeOfExpr:
case Type::TypeOf:
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index d7bb4a54c1..7a8d79ba3b 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -2149,7 +2149,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::Attributed:
case Type::SubstTemplateTypeParm:
case Type::PackExpansion:
- case Type::MacroQualified:
// Keep walking after single level desugaring.
type = type.getSingleStepDesugaredType(getContext());
break;
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 4e5ca2ee8f..130cd9f206 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -85,23 +85,6 @@ static bool isAttributeLateParsed(const IdentifierInfo &II) {
#undef CLANG_ATTR_LATE_PARSED_LIST
}
-/// Check if the a start and end source location expand to the same macro.
-bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc,
- SourceLocation EndLoc) {
- if (!StartLoc.isMacroID() || !EndLoc.isMacroID())
- return false;
-
- SourceManager &SM = PP.getSourceManager();
- if (SM.getFileID(StartLoc) != SM.getFileID(EndLoc))
- return false;
-
- bool AttrStartIsInMacro =
- Lexer::isAtStartOfMacroExpansion(StartLoc, SM, PP.getLangOpts());
- bool AttrEndIsInMacro =
- Lexer::isAtEndOfMacroExpansion(EndLoc, SM, PP.getLangOpts());
- return AttrStartIsInMacro && AttrEndIsInMacro;
-}
-
/// ParseGNUAttributes - Parse a non-empty attributes list.
///
/// [GNU] attributes:
@@ -150,10 +133,7 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
while (Tok.is(tok::kw___attribute)) {
- SourceLocation AttrTokLoc = ConsumeToken();
- unsigned OldNumAttrs = attrs.size();
- unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
-
+ ConsumeToken();
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"attribute")) {
SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
@@ -221,24 +201,6 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
SkipUntil(tok::r_paren, StopAtSemi);
if (endLoc)
*endLoc = Loc;
-
- // If this was declared in a macro, attach the macro IdentifierInfo to the
- // parsed attribute.
- if (FindLocsWithCommonFileID(PP, AttrTokLoc, Loc)) {
- auto &SM = PP.getSourceManager();
- CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc);
- StringRef FoundName =
- Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts());
- IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
-
- for (unsigned i = OldNumAttrs; i < attrs.size(); ++i)
- attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin());
-
- if (LateAttrs) {
- for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
- (*LateAttrs)[i]->MacroII = MacroII;
- }
- }
}
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3507361412..9564c8f0cb 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4096,7 +4096,6 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::Attributed:
case Type::SubstTemplateTypeParm:
case Type::PackExpansion:
- case Type::MacroQualified:
// Keep walking after single level desugaring.
T = T.getSingleStepDesugaredType(Context);
break;
@@ -13696,8 +13695,8 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
// Look for an explicit signature in that function type.
FunctionProtoTypeLoc ExplicitSignature;
- if ((ExplicitSignature = Sig->getTypeLoc()
- .getAsAdjusted<FunctionProtoTypeLoc>())) {
+ if ((ExplicitSignature =
+ Sig->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>())) {
// Check whether that explicit signature was synthesized by
// GetTypeForDeclarator. If so, don't save that as part of the
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index fe0cf74496..e9faba6e6b 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -3390,10 +3390,10 @@ bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) {
}
TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const {
- return FD->getTypeSourceInfo()
- ->getTypeLoc()
- .getAsAdjusted<FunctionProtoTypeLoc>()
- .getReturnLoc();
+ TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
+ while (auto ATL = TL.getAs<AttributedTypeLoc>())
+ TL = ATL.getModifiedLoc().IgnoreParens();
+ return TL.castAs<FunctionProtoTypeLoc>().getReturnLoc();
}
/// Deduce the return type for a function from a returned expression, per
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 65cf3f59b3..3b25595a33 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -5643,9 +5643,6 @@ namespace {
assert(Chunk.Kind == DeclaratorChunk::Pipe);
TL.setKWLoc(Chunk.Loc);
}
- void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
- TL.setExpansionLoc(Chunk.Loc);
- }
void VisitTypeLoc(TypeLoc TL) {
llvm_unreachable("unsupported TypeLoc kind in declarator!");
@@ -5724,9 +5721,6 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
CurrTL = ATL.getValueLoc().getUnqualifiedLoc();
}
- while (MacroQualifiedTypeLoc TL = CurrTL.getAs<MacroQualifiedTypeLoc>())
- CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
-
while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
fillAttributedTypeLoc(TL, State);
CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
@@ -6987,16 +6981,12 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
return true;
}
-bool Sema::hasExplicitCallingConv(QualType T) {
- const AttributedType *AT;
-
- // Stop if we'd be stripping off a typedef sugar node to reach the
- // AttributedType.
- while ((AT = T->getAs<AttributedType>()) &&
- AT->getAs<TypedefType>() == T->getAs<TypedefType>()) {
+bool Sema::hasExplicitCallingConv(QualType &T) {
+ QualType R = T.IgnoreParens();
+ while (const AttributedType *AT = dyn_cast<AttributedType>(R)) {
if (AT->isCallingConv())
return true;
- T = AT->getModifiedType();
+ R = AT->getModifiedType().IgnoreParens();
}
return false;
}
@@ -7581,15 +7571,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
distributeFunctionTypeAttr(state, attr, type);
break;
}
-
- // Handle attributes that are defined in a macro. We do not want this to be
- // applied to ObjC builtin attributes.
- if (isa<AttributedType>(type) && attr.hasMacroIdentifier() &&
- !type.getQualifiers().hasObjCLifetime() &&
- !type.getQualifiers().hasObjCGCAttr()) {
- const IdentifierInfo *MacroII = attr.getMacroIdentifier();
- type = state.getSema().Context.getMacroQualifiedType(type, MacroII);
- }
}
if (!state.getSema().getLangOpts().OpenCL ||
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index dddb2476c7..a8ea6b01d1 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -883,12 +883,6 @@ public:
return SemaRef.Context.getTypeDeclType(Typedef);
}
- /// Build a new MacroDefined type.
- QualType RebuildMacroQualifiedType(QualType T,
- const IdentifierInfo *MacroII) {
- return SemaRef.Context.getMacroQualifiedType(T, MacroII);
- }
-
/// Build a new class/struct/union type.
QualType RebuildRecordType(RecordDecl *Record) {
return SemaRef.Context.getTypeDeclType(Record);
@@ -6199,27 +6193,6 @@ TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
return Result;
}
-template <typename Derived>
-QualType
-TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
- MacroQualifiedTypeLoc TL) {
- QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
- if (Inner.isNull())
- return QualType();
-
- QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
- Result =
- getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
- if (Result.isNull())
- return QualType();
- }
-
- MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
- NewTL.setExpansionLoc(TL.getExpansionLoc());
- return Result;
-}
-
template<typename Derived>
QualType TreeTransform<Derived>::TransformDependentNameType(
TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 64af0fa8a1..a6ff54568d 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6200,16 +6200,6 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getParenType(InnerType);
}
- case TYPE_MACRO_QUALIFIED: {
- if (Record.size() != 2) {
- Error("incorrect encoding of macro defined type");
- return QualType();
- }
- QualType UnderlyingTy = readType(*Loc.F, Record, Idx);
- IdentifierInfo *MacroII = GetIdentifierInfo(*Loc.F, Record, Idx);
- return Context.getMacroQualifiedType(UnderlyingTy, MacroII);
- }
-
case TYPE_PACK_EXPANSION: {
if (Record.size() != 2) {
Error("incorrect encoding of pack expansion type");
@@ -6531,10 +6521,6 @@ void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
// nothing to do
}
-void TypeLocReader::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
- TL.setExpansionLoc(ReadSourceLocation());
-}
-
void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
TL.setCaretLoc(ReadSourceLocation());
}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index accd8ccdfa..756411a8c5 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -516,12 +516,6 @@ void ASTTypeWriter::VisitParenType(const ParenType *T) {
Code = TYPE_PAREN;
}
-void ASTTypeWriter::VisitMacroQualifiedType(const MacroQualifiedType *T) {
- Record.AddTypeRef(T->getUnderlyingType());
- Record.AddIdentifierRef(T->getMacroIdentifier());
- Code = TYPE_MACRO_QUALIFIED;
-}
-
void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
Record.push_back(T->getKeyword());
Record.AddNestedNameSpecifier(T->getQualifier());
@@ -808,10 +802,6 @@ void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
Record.AddSourceLocation(TL.getRParenLoc());
}
-void TypeLocWriter::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
- Record.AddSourceLocation(TL.getExpansionLoc());
-}
-
void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
@@ -1229,7 +1219,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION);
RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
RECORD(TYPE_PAREN);
- RECORD(TYPE_MACRO_QUALIFIED);
RECORD(TYPE_PACK_EXPANSION);
RECORD(TYPE_ATTRIBUTED);
RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);