diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-14 01:49:59 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-14 01:49:59 +0000 |
| commit | c27b3d7623cfa6476c8db5957d3c7f937603ec44 (patch) | |
| tree | 386dd67c55fd4344320688e5d5fe1d1e22e83f80 /clang/lib/Sema | |
| parent | b2bca7e309848db08237d6d4a5955a5d5d8b337e (diff) | |
| download | bcm5719-llvm-c27b3d7623cfa6476c8db5957d3c7f937603ec44.tar.gz bcm5719-llvm-c27b3d7623cfa6476c8db5957d3c7f937603ec44.zip | |
Canonicalize implicit deduction guide parameter types when forming a deduction
guide from a constructor.
The purpose of this change is to avoid triggering instantiation of the class
when substituting back into the deduction guide if it uses a typedef member.
We will still instantiate the class if the constructor (explicitly or
implicitly, directly or indirectly) uses the current instantiation in a way
that we can't canonicalize out, but that seems unavoidable.
llvm-svn: 295016
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index e86f287e0c5..fd66c798654 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1585,12 +1585,7 @@ private: // -- The types of the function parameters are those of the constructor. for (auto *OldParam : TL.getParams()) { - // If we're transforming a non-template constructor, just reuse its - // parameters as the parameters of the deduction guide. Otherwise, we - // need to transform their references to constructor template parameters. - ParmVarDecl *NewParam = Args.getNumLevels() - ? transformFunctionTypeParam(OldParam, Args) - : OldParam; + ParmVarDecl *NewParam = transformFunctionTypeParam(OldParam, Args); if (!NewParam) return QualType(); ParamTypes.push_back(NewParam->getType()); @@ -1636,16 +1631,31 @@ private: transformFunctionTypeParam(ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args) { TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo(); - TypeSourceInfo *NewDI = SemaRef.SubstType( - OldDI, Args, OldParam->getLocation(), OldParam->getDeclName()); + TypeSourceInfo *NewDI = + Args.getNumLevels() + ? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(), + OldParam->getDeclName()) + : OldDI; if (!NewDI) return nullptr; + // Canonicalize the type. This (for instance) replaces references to + // typedef members of the current instantiations with the definitions of + // those typedefs, avoiding triggering instantiation of the deduced type + // during deduction. + // FIXME: It would be preferable to retain type sugar and source + // information here (and handle this in substitution instead). + NewDI = SemaRef.Context.getTrivialTypeSourceInfo( + SemaRef.Context.getCanonicalType(NewDI->getType()), + OldParam->getLocation()); + // Resolving a wording defect, we also inherit default arguments from the // constructor. ExprResult NewDefArg; if (OldParam->hasDefaultArg()) { - NewDefArg = SemaRef.SubstExpr(OldParam->getDefaultArg(), Args); + NewDefArg = Args.getNumLevels() + ? SemaRef.SubstExpr(OldParam->getDefaultArg(), Args) + : OldParam->getDefaultArg(); if (NewDefArg.isInvalid()) return nullptr; } |

