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,
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);
// 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
if (Proto->hasTrailingReturn()) {
if (SubstParmTypes(Function->getLocation(),
Function->param_begin(), Function->getNumParams(),
+ Proto->getExtParameterInfosOrNull(),
MultiLevelTemplateArgumentList(*ExplicitArgumentList),
- ParamTypes))
+ ParamTypes, /*params*/ nullptr, ExtParamInfos))
return TDK_SubstitutionFailure;
}
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;
}
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.
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) {
if (!NewParm)
return true;
+ if (ParamInfos)
+ PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewParm->getType());
if (PVars)
PVars->push_back(NewParm);
if (!NewParm)
return true;
+ if (ParamInfos)
+ PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewParm->getType());
if (PVars)
PVars->push_back(NewParm);
if (!NewParm)
return true;
+ if (ParamInfos)
+ PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewParm->getType());
if (PVars)
PVars->push_back(NewParm);
if (NewType.isNull())
return true;
+ if (ParamInfos)
+ PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewType);
if (PVars)
PVars->push_back(nullptr);
if (NewType.isNull())
return true;
+ if (ParamInfos)
+ PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewType);
if (PVars)
PVars->push_back(nullptr);
NewType = getSema().Context.getPackExpansionType(NewType,
NumExpansions);
+ if (ParamInfos)
+ PInfos.set(OutParamTypes.size(), ParamInfos[i]);
OutParamTypes.push_back(NewType);
if (PVars)
PVars->push_back(nullptr);
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.
//
SmallVector<QualType, 4> ParamTypes;
SmallVector<ParmVarDecl*, 4> ParamDecls;
+ Sema::ExtParameterInfoBuilder ExtParamInfos;
const FunctionProtoType *T = TL.getTypePtr();
QualType ResultType;
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();
{
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();
}
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() ||
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.