diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 139 | ||||
-rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 80 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 48 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 11 | ||||
-rw-r--r-- | clang/lib/AST/TemplateName.cpp | 10 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 14 |
7 files changed, 183 insertions, 123 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 1eea813..922d679 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -678,30 +678,6 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, return true; } -static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, - const CallExpr *Call) { - APSInt Val = popToAPSInt(S, Call->getArg(0)); - pushInteger(S, Val.popcount() % 2, Call->getType()); - return true; -} - -static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, - const CallExpr *Call) { - APSInt Val = popToAPSInt(S, Call->getArg(0)); - pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(), Call->getType()); - return true; -} - -static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, - const CallExpr *Call) { - APSInt Val = popToAPSInt(S, Call->getArg(0)); - pushInteger(S, Val.reverseBits(), Call->getType()); - return true; -} - static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call) { @@ -736,16 +712,6 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, return true; } -static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, - const CallExpr *Call) { - APSInt Value = popToAPSInt(S, Call->getArg(0)); - - uint64_t N = Value.countr_zero(); - pushInteger(S, N == Value.getBitWidth() ? 0 : N + 1, Call->getType()); - return true; -} - static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call) { @@ -2583,9 +2549,11 @@ static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC, return true; } -static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, - const CallExpr *Call, - unsigned BuiltinID) { +static bool interp__builtin_ia32_pmul( + InterpState &S, CodePtr OpPC, const CallExpr *Call, + llvm::function_ref<APInt(const APSInt &, const APSInt &, const APSInt &, + const APSInt &)> + Fn) { assert(Call->getArg(0)->getType()->isVectorType() && Call->getArg(1)->getType()->isVectorType()); const Pointer &RHS = S.Stk.pop<Pointer>(); @@ -2594,35 +2562,23 @@ static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>(); PrimType ElemT = *S.getContext().classify(VT->getElementType()); - unsigned SourceLen = VT->getNumElements(); + unsigned NumElems = VT->getNumElements(); + const auto *DestVT = Call->getType()->castAs<VectorType>(); + PrimType DestElemT = *S.getContext().classify(DestVT->getElementType()); + bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType(); - PrimType DstElemT = *S.getContext().classify( - Call->getType()->castAs<VectorType>()->getElementType()); unsigned DstElem = 0; - for (unsigned I = 0; I != SourceLen; I += 2) { - APSInt Elem1; - APSInt Elem2; + for (unsigned I = 0; I != NumElems; I += 2) { + APSInt Result; INT_TYPE_SWITCH_NO_BOOL(ElemT, { - Elem1 = LHS.elem<T>(I).toAPSInt(); - Elem2 = RHS.elem<T>(I).toAPSInt(); + APSInt LoLHS = LHS.elem<T>(I).toAPSInt(); + APSInt HiLHS = LHS.elem<T>(I + 1).toAPSInt(); + APSInt LoRHS = RHS.elem<T>(I).toAPSInt(); + APSInt HiRHS = RHS.elem<T>(I + 1).toAPSInt(); + Result = APSInt(Fn(LoLHS, HiLHS, LoRHS, HiRHS), DestUnsigned); }); - APSInt Result; - switch (BuiltinID) { - case clang::X86::BI__builtin_ia32_pmuludq128: - case clang::X86::BI__builtin_ia32_pmuludq256: - case clang::X86::BI__builtin_ia32_pmuludq512: - Result = APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2), - /*IsUnsigned=*/true); - break; - case clang::X86::BI__builtin_ia32_pmuldq128: - case clang::X86::BI__builtin_ia32_pmuldq256: - case clang::X86::BI__builtin_ia32_pmuldq512: - Result = APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2), - /*IsUnsigned=*/false); - break; - } - INT_TYPE_SWITCH_NO_BOOL(DstElemT, + INT_TYPE_SWITCH_NO_BOOL(DestElemT, { Dst.elem<T>(DstElem) = static_cast<T>(Result); }); ++DstElem; } @@ -3158,18 +3114,25 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case Builtin::BI__builtin_parity: case Builtin::BI__builtin_parityl: case Builtin::BI__builtin_parityll: - return interp__builtin_parity(S, OpPC, Frame, Call); - + return interp__builtin_elementwise_int_unaryop( + S, OpPC, Call, [](const APSInt &Val) -> APInt { + return APInt(Val.getBitWidth(), Val.popcount() % 2); + }); case Builtin::BI__builtin_clrsb: case Builtin::BI__builtin_clrsbl: case Builtin::BI__builtin_clrsbll: - return interp__builtin_clrsb(S, OpPC, Frame, Call); - + return interp__builtin_elementwise_int_unaryop( + S, OpPC, Call, [](const APSInt &Val) -> APInt { + return APInt(Val.getBitWidth(), + Val.getBitWidth() - Val.getSignificantBits()); + }); case Builtin::BI__builtin_bitreverse8: case Builtin::BI__builtin_bitreverse16: case Builtin::BI__builtin_bitreverse32: case Builtin::BI__builtin_bitreverse64: - return interp__builtin_bitreverse(S, OpPC, Frame, Call); + return interp__builtin_elementwise_int_unaryop( + S, OpPC, Call, + [](const APSInt &Val) -> APInt { return Val.reverseBits(); }); case Builtin::BI__builtin_classify_type: return interp__builtin_classify_type(S, OpPC, Frame, Call); @@ -3209,7 +3172,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case Builtin::BI__builtin_ffs: case Builtin::BI__builtin_ffsl: case Builtin::BI__builtin_ffsll: - return interp__builtin_ffs(S, OpPC, Frame, Call); + return interp__builtin_elementwise_int_unaryop( + S, OpPC, Call, [](const APSInt &Val) { + return APInt(Val.getBitWidth(), + Val.isZero() ? 0u : Val.countTrailingZeros() + 1u); + }); case Builtin::BIaddressof: case Builtin::BI__addressof: @@ -3494,6 +3461,30 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, return interp__builtin_elementwise_int_binop(S, OpPC, Call, llvm::APIntOps::avgCeilU); + case clang::X86::BI__builtin_ia32_pmaddubsw128: + case clang::X86::BI__builtin_ia32_pmaddubsw256: + case clang::X86::BI__builtin_ia32_pmaddubsw512: + return interp__builtin_ia32_pmul( + S, OpPC, Call, + [](const APSInt &LoLHS, const APSInt &HiLHS, const APSInt &LoRHS, + const APSInt &HiRHS) { + unsigned BitWidth = 2 * LoLHS.getBitWidth(); + return (LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth)) + .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))); + }); + + case clang::X86::BI__builtin_ia32_pmaddwd128: + case clang::X86::BI__builtin_ia32_pmaddwd256: + case clang::X86::BI__builtin_ia32_pmaddwd512: + return interp__builtin_ia32_pmul( + S, OpPC, Call, + [](const APSInt &LoLHS, const APSInt &HiLHS, const APSInt &LoRHS, + const APSInt &HiRHS) { + unsigned BitWidth = 2 * LoLHS.getBitWidth(); + return (LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) + + (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)); + }); + case clang::X86::BI__builtin_ia32_pmulhuw128: case clang::X86::BI__builtin_ia32_pmulhuw256: case clang::X86::BI__builtin_ia32_pmulhuw512: @@ -3638,10 +3629,22 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case clang::X86::BI__builtin_ia32_pmuldq128: case clang::X86::BI__builtin_ia32_pmuldq256: case clang::X86::BI__builtin_ia32_pmuldq512: + return interp__builtin_ia32_pmul( + S, OpPC, Call, + [](const APSInt &LoLHS, const APSInt &HiLHS, const APSInt &LoRHS, + const APSInt &HiRHS) { + return llvm::APIntOps::mulsExtended(LoLHS, LoRHS); + }); + case clang::X86::BI__builtin_ia32_pmuludq128: case clang::X86::BI__builtin_ia32_pmuludq256: case clang::X86::BI__builtin_ia32_pmuludq512: - return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID); + return interp__builtin_ia32_pmul( + S, OpPC, Call, + [](const APSInt &LoLHS, const APSInt &HiLHS, const APSInt &LoRHS, + const APSInt &HiRHS) { + return llvm::APIntOps::muluExtended(LoLHS, LoRHS); + }); case Builtin::BI__builtin_elementwise_fma: return interp__builtin_elementwise_triop_fp( diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index e5fba1b..c0be986 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1653,57 +1653,65 @@ void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS, getValue().printPretty(OS, Policy, getType(), &getASTContext()); } -TemplateParameterList *clang::getReplacedTemplateParameterList(const Decl *D) { +std::tuple<NamedDecl *, TemplateArgument> +clang::getReplacedTemplateParameter(Decl *D, unsigned Index) { switch (D->getKind()) { - case Decl::Kind::CXXRecord: - return cast<CXXRecordDecl>(D) - ->getDescribedTemplate() - ->getTemplateParameters(); + case Decl::Kind::BuiltinTemplate: case Decl::Kind::ClassTemplate: - return cast<ClassTemplateDecl>(D)->getTemplateParameters(); + case Decl::Kind::Concept: + case Decl::Kind::FunctionTemplate: + case Decl::Kind::TemplateTemplateParm: + case Decl::Kind::TypeAliasTemplate: + case Decl::Kind::VarTemplate: + return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index), + {}}; case Decl::Kind::ClassTemplateSpecialization: { const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D); auto P = CTSD->getSpecializedTemplateOrPartial(); + TemplateParameterList *TPL; if (const auto *CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) - return CTPSD->getTemplateParameters(); - return cast<ClassTemplateDecl *>(P)->getTemplateParameters(); + TPL = CTPSD->getTemplateParameters(); + else + TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters(); + return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]}; + } + case Decl::Kind::VarTemplateSpecialization: { + const auto *VTSD = cast<VarTemplateSpecializationDecl>(D); + auto P = VTSD->getSpecializedTemplateOrPartial(); + TemplateParameterList *TPL; + if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) + TPL = VTPSD->getTemplateParameters(); + else + TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters(); + return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]}; } case Decl::Kind::ClassTemplatePartialSpecialization: - return cast<ClassTemplatePartialSpecializationDecl>(D) - ->getTemplateParameters(); - case Decl::Kind::TypeAliasTemplate: - return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters(); - case Decl::Kind::BuiltinTemplate: - return cast<BuiltinTemplateDecl>(D)->getTemplateParameters(); + return {cast<ClassTemplatePartialSpecializationDecl>(D) + ->getTemplateParameters() + ->getParam(Index), + {}}; + case Decl::Kind::VarTemplatePartialSpecialization: + return {cast<VarTemplatePartialSpecializationDecl>(D) + ->getTemplateParameters() + ->getParam(Index), + {}}; + // This is used as the AssociatedDecl for placeholder type deduction. + case Decl::TemplateTypeParm: + return {cast<NamedDecl>(D), {}}; + // FIXME: Always use the template decl as the AssociatedDecl. + case Decl::Kind::CXXRecord: + return getReplacedTemplateParameter( + cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index); case Decl::Kind::CXXDeductionGuide: case Decl::Kind::CXXConversion: case Decl::Kind::CXXConstructor: case Decl::Kind::CXXDestructor: case Decl::Kind::CXXMethod: case Decl::Kind::Function: - return cast<FunctionDecl>(D) - ->getTemplateSpecializationInfo() - ->getTemplate() - ->getTemplateParameters(); - case Decl::Kind::FunctionTemplate: - return cast<FunctionTemplateDecl>(D)->getTemplateParameters(); - case Decl::Kind::VarTemplate: - return cast<VarTemplateDecl>(D)->getTemplateParameters(); - case Decl::Kind::VarTemplateSpecialization: { - const auto *VTSD = cast<VarTemplateSpecializationDecl>(D); - auto P = VTSD->getSpecializedTemplateOrPartial(); - if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) - return VTPSD->getTemplateParameters(); - return cast<VarTemplateDecl *>(P)->getTemplateParameters(); - } - case Decl::Kind::VarTemplatePartialSpecialization: - return cast<VarTemplatePartialSpecializationDecl>(D) - ->getTemplateParameters(); - case Decl::Kind::TemplateTemplateParm: - return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters(); - case Decl::Kind::Concept: - return cast<ConceptDecl>(D)->getTemplateParameters(); + return getReplacedTemplateParameter( + cast<FunctionDecl>(D)->getTemplateSpecializationInfo()->getTemplate(), + Index); default: llvm_unreachable("Unhandled templated declaration kind"); } diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 95de6a8..c7f0ff0 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1727,7 +1727,7 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context, NonTypeTemplateParmDecl *SubstNonTypeTemplateParmExpr::getParameter() const { return cast<NonTypeTemplateParmDecl>( - getReplacedTemplateParameterList(getAssociatedDecl())->asArray()[Index]); + std::get<0>(getReplacedTemplateParameter(getAssociatedDecl(), Index))); } PackIndexingExpr *PackIndexingExpr::Create( @@ -1793,7 +1793,7 @@ SubstNonTypeTemplateParmPackExpr::SubstNonTypeTemplateParmPackExpr( NonTypeTemplateParmDecl * SubstNonTypeTemplateParmPackExpr::getParameterPack() const { return cast<NonTypeTemplateParmDecl>( - getReplacedTemplateParameterList(getAssociatedDecl())->asArray()[Index]); + std::get<0>(getReplacedTemplateParameter(getAssociatedDecl(), Index))); } TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 618e163..35a866e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11778,6 +11778,54 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { case clang::X86::BI__builtin_ia32_pavgw512: return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU); + case clang::X86::BI__builtin_ia32_pmaddubsw128: + case clang::X86::BI__builtin_ia32_pmaddubsw256: + case clang::X86::BI__builtin_ia32_pmaddubsw512: + case clang::X86::BI__builtin_ia32_pmaddwd128: + case clang::X86::BI__builtin_ia32_pmaddwd256: + case clang::X86::BI__builtin_ia32_pmaddwd512: { + APValue SourceLHS, SourceRHS; + if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) || + !EvaluateAsRValue(Info, E->getArg(1), SourceRHS)) + return false; + + auto *DestTy = E->getType()->castAs<VectorType>(); + QualType DestEltTy = DestTy->getElementType(); + unsigned SourceLen = SourceLHS.getVectorLength(); + bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType(); + SmallVector<APValue, 4> ResultElements; + ResultElements.reserve(SourceLen / 2); + + for (unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) { + const APSInt &LoLHS = SourceLHS.getVectorElt(EltNum).getInt(); + const APSInt &HiLHS = SourceLHS.getVectorElt(EltNum + 1).getInt(); + const APSInt &LoRHS = SourceRHS.getVectorElt(EltNum).getInt(); + const APSInt &HiRHS = SourceRHS.getVectorElt(EltNum + 1).getInt(); + unsigned BitWidth = 2 * LoLHS.getBitWidth(); + + switch (E->getBuiltinCallee()) { + case clang::X86::BI__builtin_ia32_pmaddubsw128: + case clang::X86::BI__builtin_ia32_pmaddubsw256: + case clang::X86::BI__builtin_ia32_pmaddubsw512: + ResultElements.push_back(APValue( + APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth)) + .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))), + DestUnsigned))); + break; + case clang::X86::BI__builtin_ia32_pmaddwd128: + case clang::X86::BI__builtin_ia32_pmaddwd256: + case clang::X86::BI__builtin_ia32_pmaddwd512: + ResultElements.push_back( + APValue(APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) + + (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)), + DestUnsigned))); + break; + } + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); + } + case clang::X86::BI__builtin_ia32_pmulhuw128: case clang::X86::BI__builtin_ia32_pmulhuw256: case clang::X86::BI__builtin_ia32_pmulhuw512: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index f3b5478..3cd033e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2769,10 +2769,19 @@ void OpenACCClauseProfiler::VisitReductionClause( for (auto &Recipe : Clause.getRecipes()) { Profiler.VisitDecl(Recipe.AllocaDecl); + // TODO: OpenACC: Make sure we remember to update this when we figure out // what we're adding for the operation recipe, in the meantime, a static // assert will make sure we don't add something. - static_assert(sizeof(OpenACCReductionRecipe) == sizeof(int *)); + static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) == + 3 * sizeof(int *)); + for (auto &CombinerRecipe : Recipe.CombinerRecipes) { + if (CombinerRecipe.Op) { + Profiler.VisitDecl(CombinerRecipe.LHS); + Profiler.VisitDecl(CombinerRecipe.RHS); + Profiler.VisitStmt(CombinerRecipe.Op); + } + } } } diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 2b8044e..797a354 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -64,16 +64,14 @@ SubstTemplateTemplateParmPackStorage::getArgumentPack() const { TemplateTemplateParmDecl * SubstTemplateTemplateParmPackStorage::getParameterPack() const { - return cast<TemplateTemplateParmDecl>( - getReplacedTemplateParameterList(getAssociatedDecl()) - ->asArray()[Bits.Index]); + return cast<TemplateTemplateParmDecl>(std::get<0>( + getReplacedTemplateParameter(getAssociatedDecl(), Bits.Index))); } TemplateTemplateParmDecl * SubstTemplateTemplateParmStorage::getParameter() const { - return cast<TemplateTemplateParmDecl>( - getReplacedTemplateParameterList(getAssociatedDecl()) - ->asArray()[Bits.Index]); + return cast<TemplateTemplateParmDecl>(std::get<0>( + getReplacedTemplateParameter(getAssociatedDecl(), Bits.Index))); } void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 9794314..ee7a68e 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -4436,14 +4436,6 @@ IdentifierInfo *TemplateTypeParmType::getIdentifier() const { return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier(); } -static const TemplateTypeParmDecl *getReplacedParameter(Decl *D, - unsigned Index) { - if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) - return TTP; - return cast<TemplateTypeParmDecl>( - getReplacedTemplateParameterList(D)->getParam(Index)); -} - SubstTemplateTypeParmType::SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, unsigned Index, @@ -4466,7 +4458,8 @@ SubstTemplateTypeParmType::SubstTemplateTypeParmType(QualType Replacement, const TemplateTypeParmDecl * SubstTemplateTypeParmType::getReplacedParameter() const { - return ::getReplacedParameter(getAssociatedDecl(), getIndex()); + return cast<TemplateTypeParmDecl>(std::get<0>( + getReplacedTemplateParameter(getAssociatedDecl(), getIndex()))); } void SubstTemplateTypeParmType::Profile(llvm::FoldingSetNodeID &ID, @@ -4532,7 +4525,8 @@ bool SubstTemplateTypeParmPackType::getFinal() const { const TemplateTypeParmDecl * SubstTemplateTypeParmPackType::getReplacedParameter() const { - return ::getReplacedParameter(getAssociatedDecl(), getIndex()); + return cast<TemplateTypeParmDecl>(std::get<0>( + getReplacedTemplateParameter(getAssociatedDecl(), getIndex()))); } IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const { |