diff options
author | John McCall <rjmccall@apple.com> | 2016-03-01 02:09:25 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2016-03-01 02:09:25 +0000 |
commit | c8e321d4bc6862f4939ed5200b5d4cbb9fb41a90 (patch) | |
tree | 8bdccc67a7c4cfce0c74bf0dee7e8ff064b9cbac | |
parent | 5d7cf778e491db4b5fff2bebfec0a1ed24362d43 (diff) | |
download | bcm5719-llvm-c8e321d4bc6862f4939ed5200b5d4cbb9fb41a90.tar.gz bcm5719-llvm-c8e321d4bc6862f4939ed5200b5d4cbb9fb41a90.zip |
Fix the template instantiation of ExtParameterInfos; tests to follow.
llvm-svn: 262289
-rw-r--r-- | clang/include/clang/AST/Type.h | 5 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 60 |
6 files changed, 97 insertions, 20 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 42334252612..d6e30e4f068 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -3355,6 +3355,11 @@ public: return ArrayRef<ExtParameterInfo>(getExtParameterInfosBuffer(), getNumParams()); } + const ExtParameterInfo *getExtParameterInfosOrNull() const { + if (!hasExtParameterInfos()) + return nullptr; + return getExtParameterInfosBuffer(); + } ExtParameterInfo getExtParameterInfo(unsigned I) const { assert(I < getNumParams() && "parameter index out of range"); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 22a2ef7454b..8ff47e93ce0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6982,6 +6982,26 @@ public: SavedPendingLocalImplicitInstantiations; }; + class ExtParameterInfoBuilder { + SmallVector<FunctionProtoType::ExtParameterInfo, 4> Infos; + bool HasInteresting = false; + + public: + void set(unsigned index, FunctionProtoType::ExtParameterInfo info) { + assert(Infos.size() <= index); + Infos.resize(index); + Infos.push_back(info); + + if (!HasInteresting) + HasInteresting = (info != FunctionProtoType::ExtParameterInfo()); + } + + const FunctionProtoType::ExtParameterInfo * + getPointerOrNull(unsigned numParams) { + return (HasInteresting ? Infos.data() : nullptr); + } + }; + void PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, @@ -7011,9 +7031,11 @@ public: bool ExpectParameterPack); bool SubstParmTypes(SourceLocation Loc, ParmVarDecl **Params, unsigned NumParams, + const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl<QualType> &ParamTypes, - SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr); + SmallVectorImpl<ParmVarDecl *> *OutParams, + ExtParameterInfoBuilder &ParamInfos); ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0b090c8ff7e..b101a16f5c8 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2552,6 +2552,8 @@ Sema::SubstituteExplicitTemplateArguments( // Isolate our substituted parameters from our caller. LocalInstantiationScope InstScope(*this, /*MergeWithOuterScope*/true); + ExtParameterInfoBuilder ExtParamInfos; + // Instantiate the types of each of the function parameters given the // explicitly-specified template arguments. If the function has a trailing // return type, substitute it after the arguments to ensure we substitute @@ -2559,8 +2561,9 @@ Sema::SubstituteExplicitTemplateArguments( if (Proto->hasTrailingReturn()) { if (SubstParmTypes(Function->getLocation(), Function->param_begin(), Function->getNumParams(), + Proto->getExtParameterInfosOrNull(), MultiLevelTemplateArgumentList(*ExplicitArgumentList), - ParamTypes)) + ParamTypes, /*params*/ nullptr, ExtParamInfos)) return TDK_SubstitutionFailure; } @@ -2590,21 +2593,24 @@ Sema::SubstituteExplicitTemplateArguments( if (ResultType.isNull() || Trap.hasErrorOccurred()) return TDK_SubstitutionFailure; } - + // Instantiate the types of each of the function parameters given the // explicitly-specified template arguments if we didn't do so earlier. if (!Proto->hasTrailingReturn() && SubstParmTypes(Function->getLocation(), Function->param_begin(), Function->getNumParams(), + Proto->getExtParameterInfosOrNull(), MultiLevelTemplateArgumentList(*ExplicitArgumentList), - ParamTypes)) + ParamTypes, /*params*/ nullptr, ExtParamInfos)) return TDK_SubstitutionFailure; if (FunctionType) { + auto EPI = Proto->getExtProtoInfo(); + EPI.ExtParameterInfos = ExtParamInfos.getPointerOrNull(ParamTypes.size()); *FunctionType = BuildFunctionType(ResultType, ParamTypes, Function->getLocation(), Function->getDeclName(), - Proto->getExtProtoInfo()); + EPI); if (FunctionType->isNull() || Trap.hasErrorOccurred()) return TDK_SubstitutionFailure; } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index db3f47fd916..610817fcafd 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1710,9 +1710,11 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, /// from such a substitution. bool Sema::SubstParmTypes(SourceLocation Loc, ParmVarDecl **Params, unsigned NumParams, + const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl<QualType> &ParamTypes, - SmallVectorImpl<ParmVarDecl *> *OutParams) { + SmallVectorImpl<ParmVarDecl *> *OutParams, + ExtParameterInfoBuilder &ParamInfos) { assert(!ActiveTemplateInstantiations.empty() && "Cannot perform an instantiation without some context on the " "instantiation stack"); @@ -1720,8 +1722,9 @@ bool Sema::SubstParmTypes(SourceLocation Loc, TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, DeclarationName()); return Instantiator.TransformFunctionTypeParams(Loc, Params, NumParams, - nullptr, ParamTypes, - OutParams); + nullptr, ExtParamInfos, + ParamTypes, OutParams, + ParamInfos); } /// \brief Perform substitution on the base class specifiers of the diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 829d51ee968..fdf1c73bfc6 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3124,9 +3124,10 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, // In this case, we'll just go instantiate the ParmVarDecls that we // synthesized in the method declaration. SmallVector<QualType, 4> ParamTypes; + Sema::ExtParameterInfoBuilder ExtParamInfos; if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), - D->getNumParams(), TemplateArgs, ParamTypes, - &Params)) + D->getNumParams(), nullptr, TemplateArgs, + ParamTypes, &Params, ExtParamInfos)) return nullptr; } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 627165fa2c7..ffffb7757c2 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -607,8 +607,10 @@ public: bool TransformFunctionTypeParams(SourceLocation Loc, ParmVarDecl **Params, unsigned NumParams, const QualType *ParamTypes, + const FunctionProtoType::ExtParameterInfo *ParamInfos, SmallVectorImpl<QualType> &PTypes, - SmallVectorImpl<ParmVarDecl*> *PVars); + SmallVectorImpl<ParmVarDecl*> *PVars, + Sema::ExtParameterInfoBuilder &PInfos); /// \brief Transforms a single function-type parameter. Return null /// on error. @@ -4609,8 +4611,10 @@ bool TreeTransform<Derived>:: TransformFunctionTypeParams(SourceLocation Loc, ParmVarDecl **Params, unsigned NumParams, const QualType *ParamTypes, + const FunctionProtoType::ExtParameterInfo *ParamInfos, SmallVectorImpl<QualType> &OutParamTypes, - SmallVectorImpl<ParmVarDecl*> *PVars) { + SmallVectorImpl<ParmVarDecl*> *PVars, + Sema::ExtParameterInfoBuilder &PInfos) { int indexAdjustment = 0; for (unsigned i = 0; i != NumParams; ++i) { @@ -4659,6 +4663,8 @@ bool TreeTransform<Derived>:: if (!NewParm) return true; + if (ParamInfos) + PInfos.set(OutParamTypes.size(), ParamInfos[i]); OutParamTypes.push_back(NewParm->getType()); if (PVars) PVars->push_back(NewParm); @@ -4676,6 +4682,8 @@ bool TreeTransform<Derived>:: if (!NewParm) return true; + if (ParamInfos) + PInfos.set(OutParamTypes.size(), ParamInfos[i]); OutParamTypes.push_back(NewParm->getType()); if (PVars) PVars->push_back(NewParm); @@ -4706,6 +4714,8 @@ bool TreeTransform<Derived>:: if (!NewParm) return true; + if (ParamInfos) + PInfos.set(OutParamTypes.size(), ParamInfos[i]); OutParamTypes.push_back(NewParm->getType()); if (PVars) PVars->push_back(NewParm); @@ -4745,6 +4755,8 @@ bool TreeTransform<Derived>:: if (NewType.isNull()) return true; + if (ParamInfos) + PInfos.set(OutParamTypes.size(), ParamInfos[i]); OutParamTypes.push_back(NewType); if (PVars) PVars->push_back(nullptr); @@ -4762,6 +4774,8 @@ bool TreeTransform<Derived>:: if (NewType.isNull()) return true; + if (ParamInfos) + PInfos.set(OutParamTypes.size(), ParamInfos[i]); OutParamTypes.push_back(NewType); if (PVars) PVars->push_back(nullptr); @@ -4784,6 +4798,8 @@ bool TreeTransform<Derived>:: NewType = getSema().Context.getPackExpansionType(NewType, NumExpansions); + if (ParamInfos) + PInfos.set(OutParamTypes.size(), ParamInfos[i]); OutParamTypes.push_back(NewType); if (PVars) PVars->push_back(nullptr); @@ -4818,6 +4834,7 @@ template<typename Derived> template<typename Fn> QualType TreeTransform<Derived>::TransformFunctionProtoType( TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, unsigned ThisTypeQuals, Fn TransformExceptionSpec) { + // Transform the parameters and return type. // // We are required to instantiate the params and return type in source order. @@ -4827,6 +4844,7 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType( // SmallVector<QualType, 4> ParamTypes; SmallVector<ParmVarDecl*, 4> ParamDecls; + Sema::ExtParameterInfoBuilder ExtParamInfos; const FunctionProtoType *T = TL.getTypePtr(); QualType ResultType; @@ -4834,7 +4852,9 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType( if (T->hasTrailingReturn()) { if (getDerived().TransformFunctionTypeParams( TL.getBeginLoc(), TL.getParmArray(), TL.getNumParams(), - TL.getTypePtr()->param_type_begin(), ParamTypes, &ParamDecls)) + TL.getTypePtr()->param_type_begin(), + T->getExtParameterInfosOrNull(), + ParamTypes, &ParamDecls, ExtParamInfos)) return QualType(); { @@ -4858,7 +4878,9 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType( if (getDerived().TransformFunctionTypeParams( TL.getBeginLoc(), TL.getParmArray(), TL.getNumParams(), - TL.getTypePtr()->param_type_begin(), ParamTypes, &ParamDecls)) + TL.getTypePtr()->param_type_begin(), + T->getExtParameterInfosOrNull(), + ParamTypes, &ParamDecls, ExtParamInfos)) return QualType(); } @@ -4868,8 +4890,19 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType( if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged)) return QualType(); - // FIXME: Need to transform ConsumedParameters for variadic template - // expansion. + // Handle extended parameter information. + if (auto NewExtParamInfos = + ExtParamInfos.getPointerOrNull(ParamTypes.size())) { + if (!EPI.ExtParameterInfos || + llvm::makeArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) + != llvm::makeArrayRef(NewExtParamInfos, ParamTypes.size())) { + EPIChanged = true; + } + EPI.ExtParameterInfos = NewExtParamInfos; + } else if (EPI.ExtParameterInfos) { + EPIChanged = true; + EPI.ExtParameterInfos = nullptr; + } QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() || @@ -11113,22 +11146,29 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { SmallVector<ParmVarDecl*, 4> params; SmallVector<QualType, 4> paramTypes; + const FunctionProtoType *exprFunctionType = E->getFunctionType(); + // Parameter substitution. + Sema::ExtParameterInfoBuilder extParamInfos; if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(), oldBlock->param_begin(), oldBlock->param_size(), - nullptr, paramTypes, ¶ms)) { + nullptr, + exprFunctionType->getExtParameterInfosOrNull(), + paramTypes, ¶ms, + extParamInfos)) { getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr); return ExprError(); } - const FunctionProtoType *exprFunctionType = E->getFunctionType(); QualType exprResultType = getDerived().TransformType(exprFunctionType->getReturnType()); + auto epi = exprFunctionType->getExtProtoInfo(); + epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size()); + QualType functionType = - getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, - exprFunctionType->getExtProtoInfo()); + getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi); blockScope->FunctionType = functionType; // Set the parameters on the block decl. |