diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-10 09:58:53 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-10 09:58:53 +0000 |
commit | eefb3d5b49c844347f212073a7e975b8118fe8e9 (patch) | |
tree | c3493ab063010eff7342253e22bd8245b21c8774 /lib/Sema | |
parent | 09aaaa43cd5e24d21c666350476802e7d01d6988 (diff) |
Track whether a function type has a trailing return type as type sugar. Use this
to pretty-print such function types better, and to fix a case where we were not
instantiating templates in lexical order. In passing, move the Variadic bit from
Type's bitfields to FunctionProtoType to get the Type bitfields down to 32 bits.
Also ensure that we always substitute the return type of a function when
substituting explicitly-specified arguments, since that can cause us to bail
out with a SFINAE error before we hit a hard error in parameter substitution.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150241 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 46 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 9 |
4 files changed, 42 insertions, 22 deletions
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 1a7f1a12b3..ed05eff8e1 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -46,6 +46,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // If a lambda-expression does not include a lambda-declarator, it is as // if the lambda-declarator were (). FunctionProtoType::ExtProtoInfo EPI; + EPI.HasTrailingReturn = true; EPI.TypeQuals |= DeclSpec::TQ_const; MethodTy = Context.getFunctionType(Context.DependentTy, /*Args=*/0, /*NumArgs=*/0, EPI); diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 9d711001b3..1d84ce31b2 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2291,33 +2291,45 @@ Sema::SubstituteExplicitTemplateArguments( } } + const FunctionProtoType *Proto + = Function->getType()->getAs<FunctionProtoType>(); + assert(Proto && "Function template does not have a prototype?"); + // Instantiate the types of each of the function parameters given the - // explicitly-specified template arguments. - if (SubstParmTypes(Function->getLocation(), + // explicitly-specified template arguments. If the function has a trailing + // return type, substitute it after the arguments to ensure we substitute + // in lexical order. + if (Proto->hasTrailingReturn() && + SubstParmTypes(Function->getLocation(), Function->param_begin(), Function->getNumParams(), MultiLevelTemplateArgumentList(*ExplicitArgumentList), ParamTypes)) return TDK_SubstitutionFailure; - // If the caller wants a full function type back, instantiate the return - // type and form that function type. - if (FunctionType) { - // FIXME: exception-specifications? - const FunctionProtoType *Proto - = Function->getType()->getAs<FunctionProtoType>(); - assert(Proto && "Function template does not have a prototype?"); - - QualType ResultType - = SubstType(Proto->getResultType(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), - Function->getTypeSpecStartLoc(), - Function->getDeclName()); - if (ResultType.isNull() || Trap.hasErrorOccurred()) - return TDK_SubstitutionFailure; + // Instantiate the return type. + // FIXME: exception-specifications? + QualType ResultType + = SubstType(Proto->getResultType(), + MultiLevelTemplateArgumentList(*ExplicitArgumentList), + Function->getTypeSpecStartLoc(), + Function->getDeclName()); + 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(), + MultiLevelTemplateArgumentList(*ExplicitArgumentList), + ParamTypes)) + return TDK_SubstitutionFailure; + + if (FunctionType) { *FunctionType = BuildFunctionType(ResultType, ParamTypes.data(), ParamTypes.size(), Proto->isVariadic(), + Proto->hasTrailingReturn(), Proto->getTypeQuals(), Proto->getRefQualifier(), Function->getLocation(), diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 9fd611b5fe..51e1fb06e2 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1434,6 +1434,8 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize, /// /// \param Variadic Whether this is a variadic function type. /// +/// \param HasTrailingReturn Whether this function has a trailing return type. +/// /// \param Quals The cvr-qualifiers to be applied to the function type. /// /// \param Loc The location of the entity whose type involves this @@ -1448,7 +1450,8 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize, QualType Sema::BuildFunctionType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, - bool Variadic, unsigned Quals, + bool Variadic, bool HasTrailingReturn, + unsigned Quals, RefQualifierKind RefQualifier, SourceLocation Loc, DeclarationName Entity, FunctionType::ExtInfo Info) { @@ -1487,6 +1490,7 @@ QualType Sema::BuildFunctionType(QualType T, FunctionProtoType::ExtProtoInfo EPI; EPI.Variadic = Variadic; + EPI.HasTrailingReturn = HasTrailingReturn; EPI.TypeQuals = Quals; EPI.RefQualifier = RefQualifier; EPI.ExtInfo = Info; @@ -1498,7 +1502,6 @@ QualType Sema::BuildFunctionType(QualType T, /// /// \param T the type to which the member pointer refers. /// \param Class the class type into which the member pointer points. -/// \param CVR Qualifiers applied to the member pointer type /// \param Loc the location where this type begins /// \param Entity the name of the entity that will have this member pointer type /// @@ -2185,6 +2188,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, FunctionProtoType::ExtProtoInfo EPI; EPI.Variadic = FTI.isVariadic; + EPI.HasTrailingReturn = FTI.TrailingReturnType; EPI.TypeQuals = FTI.TypeQuals; EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None : FTI.RefQualifierIsLValueRef? RQ_LValue diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index ca72bc7d26..4742bbfc96 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -666,7 +666,8 @@ public: QualType RebuildFunctionProtoType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, - bool Variadic, unsigned Quals, + bool Variadic, bool HasTrailingReturn, + unsigned Quals, RefQualifierKind RefQualifier, const FunctionType::ExtInfo &Info); @@ -4137,6 +4138,7 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, ParamTypes.data(), ParamTypes.size(), T->isVariadic(), + T->hasTrailingReturn(), T->getTypeQuals(), T->getRefQualifier(), T->getExtInfo()); @@ -8209,7 +8211,7 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { paramTypes.data(), paramTypes.size(), oldBlock->isVariadic(), - 0, RQ_None, + false, 0, RQ_None, exprFunctionType->getExtInfo()); blockScope->FunctionType = functionType; @@ -8452,11 +8454,12 @@ QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, bool Variadic, + bool HasTrailingReturn, unsigned Quals, RefQualifierKind RefQualifier, const FunctionType::ExtInfo &Info) { return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic, - Quals, RefQualifier, + HasTrailingReturn, Quals, RefQualifier, getDerived().getBaseLocation(), getDerived().getBaseEntity(), Info); |