1*67e74705SXin Li //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/ 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li //===----------------------------------------------------------------------===/ 8*67e74705SXin Li // 9*67e74705SXin Li // This file provides types used with Sema's template argument deduction 10*67e74705SXin Li // routines. 11*67e74705SXin Li // 12*67e74705SXin Li //===----------------------------------------------------------------------===/ 13*67e74705SXin Li #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H 14*67e74705SXin Li #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H 15*67e74705SXin Li 16*67e74705SXin Li #include "clang/AST/DeclTemplate.h" 17*67e74705SXin Li #include "clang/Basic/PartialDiagnostic.h" 18*67e74705SXin Li #include "llvm/ADT/SmallVector.h" 19*67e74705SXin Li 20*67e74705SXin Li namespace clang { 21*67e74705SXin Li 22*67e74705SXin Li struct DeducedPack; 23*67e74705SXin Li class TemplateArgumentList; 24*67e74705SXin Li class Sema; 25*67e74705SXin Li 26*67e74705SXin Li namespace sema { 27*67e74705SXin Li 28*67e74705SXin Li /// \brief Provides information about an attempted template argument 29*67e74705SXin Li /// deduction, whose success or failure was described by a 30*67e74705SXin Li /// TemplateDeductionResult value. 31*67e74705SXin Li class TemplateDeductionInfo { 32*67e74705SXin Li /// \brief The deduced template argument list. 33*67e74705SXin Li /// 34*67e74705SXin Li TemplateArgumentList *Deduced; 35*67e74705SXin Li 36*67e74705SXin Li /// \brief The source location at which template argument 37*67e74705SXin Li /// deduction is occurring. 38*67e74705SXin Li SourceLocation Loc; 39*67e74705SXin Li 40*67e74705SXin Li /// \brief Have we suppressed an error during deduction? 41*67e74705SXin Li bool HasSFINAEDiagnostic; 42*67e74705SXin Li 43*67e74705SXin Li /// \brief Warnings (and follow-on notes) that were suppressed due to 44*67e74705SXin Li /// SFINAE while performing template argument deduction. 45*67e74705SXin Li SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; 46*67e74705SXin Li 47*67e74705SXin Li TemplateDeductionInfo(const TemplateDeductionInfo &) = delete; 48*67e74705SXin Li void operator=(const TemplateDeductionInfo &) = delete; 49*67e74705SXin Li 50*67e74705SXin Li public: TemplateDeductionInfo(SourceLocation Loc)51*67e74705SXin Li TemplateDeductionInfo(SourceLocation Loc) 52*67e74705SXin Li : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false), 53*67e74705SXin Li Expression(nullptr) {} 54*67e74705SXin Li 55*67e74705SXin Li /// \brief Returns the location at which template argument is 56*67e74705SXin Li /// occurring. getLocation()57*67e74705SXin Li SourceLocation getLocation() const { 58*67e74705SXin Li return Loc; 59*67e74705SXin Li } 60*67e74705SXin Li 61*67e74705SXin Li /// \brief Take ownership of the deduced template argument list. take()62*67e74705SXin Li TemplateArgumentList *take() { 63*67e74705SXin Li TemplateArgumentList *Result = Deduced; 64*67e74705SXin Li Deduced = nullptr; 65*67e74705SXin Li return Result; 66*67e74705SXin Li } 67*67e74705SXin Li 68*67e74705SXin Li /// \brief Take ownership of the SFINAE diagnostic. takeSFINAEDiagnostic(PartialDiagnosticAt & PD)69*67e74705SXin Li void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { 70*67e74705SXin Li assert(HasSFINAEDiagnostic); 71*67e74705SXin Li PD.first = SuppressedDiagnostics.front().first; 72*67e74705SXin Li PD.second.swap(SuppressedDiagnostics.front().second); 73*67e74705SXin Li SuppressedDiagnostics.clear(); 74*67e74705SXin Li HasSFINAEDiagnostic = false; 75*67e74705SXin Li } 76*67e74705SXin Li 77*67e74705SXin Li /// \brief Provide a new template argument list that contains the 78*67e74705SXin Li /// results of template argument deduction. reset(TemplateArgumentList * NewDeduced)79*67e74705SXin Li void reset(TemplateArgumentList *NewDeduced) { 80*67e74705SXin Li Deduced = NewDeduced; 81*67e74705SXin Li } 82*67e74705SXin Li 83*67e74705SXin Li /// \brief Is a SFINAE diagnostic available? hasSFINAEDiagnostic()84*67e74705SXin Li bool hasSFINAEDiagnostic() const { 85*67e74705SXin Li return HasSFINAEDiagnostic; 86*67e74705SXin Li } 87*67e74705SXin Li 88*67e74705SXin Li /// \brief Set the diagnostic which caused the SFINAE failure. addSFINAEDiagnostic(SourceLocation Loc,PartialDiagnostic PD)89*67e74705SXin Li void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { 90*67e74705SXin Li // Only collect the first diagnostic. 91*67e74705SXin Li if (HasSFINAEDiagnostic) 92*67e74705SXin Li return; 93*67e74705SXin Li SuppressedDiagnostics.clear(); 94*67e74705SXin Li SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); 95*67e74705SXin Li HasSFINAEDiagnostic = true; 96*67e74705SXin Li } 97*67e74705SXin Li 98*67e74705SXin Li /// \brief Add a new diagnostic to the set of diagnostics addSuppressedDiagnostic(SourceLocation Loc,PartialDiagnostic PD)99*67e74705SXin Li void addSuppressedDiagnostic(SourceLocation Loc, 100*67e74705SXin Li PartialDiagnostic PD) { 101*67e74705SXin Li if (HasSFINAEDiagnostic) 102*67e74705SXin Li return; 103*67e74705SXin Li SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); 104*67e74705SXin Li } 105*67e74705SXin Li 106*67e74705SXin Li /// \brief Iterator over the set of suppressed diagnostics. 107*67e74705SXin Li typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator 108*67e74705SXin Li diag_iterator; 109*67e74705SXin Li 110*67e74705SXin Li /// \brief Returns an iterator at the beginning of the sequence of suppressed 111*67e74705SXin Li /// diagnostics. diag_begin()112*67e74705SXin Li diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } 113*67e74705SXin Li 114*67e74705SXin Li /// \brief Returns an iterator at the end of the sequence of suppressed 115*67e74705SXin Li /// diagnostics. diag_end()116*67e74705SXin Li diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } 117*67e74705SXin Li 118*67e74705SXin Li /// \brief The template parameter to which a template argument 119*67e74705SXin Li /// deduction failure refers. 120*67e74705SXin Li /// 121*67e74705SXin Li /// Depending on the result of template argument deduction, this 122*67e74705SXin Li /// template parameter may have different meanings: 123*67e74705SXin Li /// 124*67e74705SXin Li /// TDK_Incomplete: this is the first template parameter whose 125*67e74705SXin Li /// corresponding template argument was not deduced. 126*67e74705SXin Li /// 127*67e74705SXin Li /// TDK_Inconsistent: this is the template parameter for which 128*67e74705SXin Li /// two different template argument values were deduced. 129*67e74705SXin Li TemplateParameter Param; 130*67e74705SXin Li 131*67e74705SXin Li /// \brief The first template argument to which the template 132*67e74705SXin Li /// argument deduction failure refers. 133*67e74705SXin Li /// 134*67e74705SXin Li /// Depending on the result of the template argument deduction, 135*67e74705SXin Li /// this template argument may have different meanings: 136*67e74705SXin Li /// 137*67e74705SXin Li /// TDK_Inconsistent: this argument is the first value deduced 138*67e74705SXin Li /// for the corresponding template parameter. 139*67e74705SXin Li /// 140*67e74705SXin Li /// TDK_SubstitutionFailure: this argument is the template 141*67e74705SXin Li /// argument we were instantiating when we encountered an error. 142*67e74705SXin Li /// 143*67e74705SXin Li /// TDK_DeducedMismatch: this is the parameter type, after substituting 144*67e74705SXin Li /// deduced arguments. 145*67e74705SXin Li /// 146*67e74705SXin Li /// TDK_NonDeducedMismatch: this is the component of the 'parameter' 147*67e74705SXin Li /// of the deduction, directly provided in the source code. 148*67e74705SXin Li TemplateArgument FirstArg; 149*67e74705SXin Li 150*67e74705SXin Li /// \brief The second template argument to which the template 151*67e74705SXin Li /// argument deduction failure refers. 152*67e74705SXin Li /// 153*67e74705SXin Li /// TDK_Inconsistent: this argument is the second value deduced 154*67e74705SXin Li /// for the corresponding template parameter. 155*67e74705SXin Li /// 156*67e74705SXin Li /// TDK_DeducedMismatch: this is the (adjusted) call argument type. 157*67e74705SXin Li /// 158*67e74705SXin Li /// TDK_NonDeducedMismatch: this is the mismatching component of the 159*67e74705SXin Li /// 'argument' of the deduction, from which we are deducing arguments. 160*67e74705SXin Li /// 161*67e74705SXin Li /// FIXME: Finish documenting this. 162*67e74705SXin Li TemplateArgument SecondArg; 163*67e74705SXin Li 164*67e74705SXin Li union { 165*67e74705SXin Li /// \brief The expression which caused a deduction failure. 166*67e74705SXin Li /// 167*67e74705SXin Li /// TDK_FailedOverloadResolution: this argument is the reference to 168*67e74705SXin Li /// an overloaded function which could not be resolved to a specific 169*67e74705SXin Li /// function. 170*67e74705SXin Li Expr *Expression; 171*67e74705SXin Li 172*67e74705SXin Li /// \brief The index of the function argument that caused a deduction 173*67e74705SXin Li /// failure. 174*67e74705SXin Li /// 175*67e74705SXin Li /// TDK_DeducedMismatch: this is the index of the argument that had a 176*67e74705SXin Li /// different argument type from its substituted parameter type. 177*67e74705SXin Li unsigned CallArgIndex; 178*67e74705SXin Li }; 179*67e74705SXin Li 180*67e74705SXin Li /// \brief Information on packs that we're currently expanding. 181*67e74705SXin Li /// 182*67e74705SXin Li /// FIXME: This should be kept internal to SemaTemplateDeduction. 183*67e74705SXin Li SmallVector<DeducedPack *, 8> PendingDeducedPacks; 184*67e74705SXin Li }; 185*67e74705SXin Li 186*67e74705SXin Li } // end namespace sema 187*67e74705SXin Li 188*67e74705SXin Li /// A structure used to record information about a failed 189*67e74705SXin Li /// template argument deduction, for diagnosis. 190*67e74705SXin Li struct DeductionFailureInfo { 191*67e74705SXin Li /// A Sema::TemplateDeductionResult. 192*67e74705SXin Li unsigned Result : 8; 193*67e74705SXin Li 194*67e74705SXin Li /// \brief Indicates whether a diagnostic is stored in Diagnostic. 195*67e74705SXin Li unsigned HasDiagnostic : 1; 196*67e74705SXin Li 197*67e74705SXin Li /// \brief Opaque pointer containing additional data about 198*67e74705SXin Li /// this deduction failure. 199*67e74705SXin Li void *Data; 200*67e74705SXin Li 201*67e74705SXin Li /// \brief A diagnostic indicating why deduction failed. 202*67e74705SXin Li union { 203*67e74705SXin Li void *Align; 204*67e74705SXin Li char Diagnostic[sizeof(PartialDiagnosticAt)]; 205*67e74705SXin Li }; 206*67e74705SXin Li 207*67e74705SXin Li /// \brief Retrieve the diagnostic which caused this deduction failure, 208*67e74705SXin Li /// if any. 209*67e74705SXin Li PartialDiagnosticAt *getSFINAEDiagnostic(); 210*67e74705SXin Li 211*67e74705SXin Li /// \brief Retrieve the template parameter this deduction failure 212*67e74705SXin Li /// refers to, if any. 213*67e74705SXin Li TemplateParameter getTemplateParameter(); 214*67e74705SXin Li 215*67e74705SXin Li /// \brief Retrieve the template argument list associated with this 216*67e74705SXin Li /// deduction failure, if any. 217*67e74705SXin Li TemplateArgumentList *getTemplateArgumentList(); 218*67e74705SXin Li 219*67e74705SXin Li /// \brief Return the first template argument this deduction failure 220*67e74705SXin Li /// refers to, if any. 221*67e74705SXin Li const TemplateArgument *getFirstArg(); 222*67e74705SXin Li 223*67e74705SXin Li /// \brief Return the second template argument this deduction failure 224*67e74705SXin Li /// refers to, if any. 225*67e74705SXin Li const TemplateArgument *getSecondArg(); 226*67e74705SXin Li 227*67e74705SXin Li /// \brief Return the expression this deduction failure refers to, 228*67e74705SXin Li /// if any. 229*67e74705SXin Li Expr *getExpr(); 230*67e74705SXin Li 231*67e74705SXin Li /// \brief Return the index of the call argument that this deduction 232*67e74705SXin Li /// failure refers to, if any. 233*67e74705SXin Li llvm::Optional<unsigned> getCallArgIndex(); 234*67e74705SXin Li 235*67e74705SXin Li /// \brief Free any memory associated with this deduction failure. 236*67e74705SXin Li void Destroy(); 237*67e74705SXin Li }; 238*67e74705SXin Li 239*67e74705SXin Li /// TemplateSpecCandidate - This is a generalization of OverloadCandidate 240*67e74705SXin Li /// which keeps track of template argument deduction failure info, when 241*67e74705SXin Li /// handling explicit specializations (and instantiations) of templates 242*67e74705SXin Li /// beyond function overloading. 243*67e74705SXin Li /// For now, assume that the candidates are non-matching specializations. 244*67e74705SXin Li /// TODO: In the future, we may need to unify/generalize this with 245*67e74705SXin Li /// OverloadCandidate. 246*67e74705SXin Li struct TemplateSpecCandidate { 247*67e74705SXin Li /// \brief The declaration that was looked up, together with its access. 248*67e74705SXin Li /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl. 249*67e74705SXin Li DeclAccessPair FoundDecl; 250*67e74705SXin Li 251*67e74705SXin Li /// Specialization - The actual specialization that this candidate 252*67e74705SXin Li /// represents. When NULL, this may be a built-in candidate. 253*67e74705SXin Li Decl *Specialization; 254*67e74705SXin Li 255*67e74705SXin Li /// Template argument deduction info 256*67e74705SXin Li DeductionFailureInfo DeductionFailure; 257*67e74705SXin Li setTemplateSpecCandidate258*67e74705SXin Li void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) { 259*67e74705SXin Li FoundDecl = Found; 260*67e74705SXin Li Specialization = Spec; 261*67e74705SXin Li DeductionFailure = Info; 262*67e74705SXin Li } 263*67e74705SXin Li 264*67e74705SXin Li /// Diagnose a template argument deduction failure. 265*67e74705SXin Li void NoteDeductionFailure(Sema &S, bool ForTakingAddress); 266*67e74705SXin Li }; 267*67e74705SXin Li 268*67e74705SXin Li /// TemplateSpecCandidateSet - A set of generalized overload candidates, 269*67e74705SXin Li /// used in template specializations. 270*67e74705SXin Li /// TODO: In the future, we may need to unify/generalize this with 271*67e74705SXin Li /// OverloadCandidateSet. 272*67e74705SXin Li class TemplateSpecCandidateSet { 273*67e74705SXin Li SmallVector<TemplateSpecCandidate, 16> Candidates; 274*67e74705SXin Li SourceLocation Loc; 275*67e74705SXin Li // Stores whether we're taking the address of these candidates. This helps us 276*67e74705SXin Li // produce better error messages when dealing with the pass_object_size 277*67e74705SXin Li // attribute on parameters. 278*67e74705SXin Li bool ForTakingAddress; 279*67e74705SXin Li 280*67e74705SXin Li TemplateSpecCandidateSet( 281*67e74705SXin Li const TemplateSpecCandidateSet &) = delete; 282*67e74705SXin Li void operator=(const TemplateSpecCandidateSet &) = delete; 283*67e74705SXin Li 284*67e74705SXin Li void destroyCandidates(); 285*67e74705SXin Li 286*67e74705SXin Li public: 287*67e74705SXin Li TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false) Loc(Loc)288*67e74705SXin Li : Loc(Loc), ForTakingAddress(ForTakingAddress) {} ~TemplateSpecCandidateSet()289*67e74705SXin Li ~TemplateSpecCandidateSet() { destroyCandidates(); } 290*67e74705SXin Li getLocation()291*67e74705SXin Li SourceLocation getLocation() const { return Loc; } 292*67e74705SXin Li 293*67e74705SXin Li /// \brief Clear out all of the candidates. 294*67e74705SXin Li /// TODO: This may be unnecessary. 295*67e74705SXin Li void clear(); 296*67e74705SXin Li 297*67e74705SXin Li typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator; begin()298*67e74705SXin Li iterator begin() { return Candidates.begin(); } end()299*67e74705SXin Li iterator end() { return Candidates.end(); } 300*67e74705SXin Li size()301*67e74705SXin Li size_t size() const { return Candidates.size(); } empty()302*67e74705SXin Li bool empty() const { return Candidates.empty(); } 303*67e74705SXin Li 304*67e74705SXin Li /// \brief Add a new candidate with NumConversions conversion sequence slots 305*67e74705SXin Li /// to the overload set. addCandidate()306*67e74705SXin Li TemplateSpecCandidate &addCandidate() { 307*67e74705SXin Li Candidates.emplace_back(); 308*67e74705SXin Li return Candidates.back(); 309*67e74705SXin Li } 310*67e74705SXin Li 311*67e74705SXin Li void NoteCandidates(Sema &S, SourceLocation Loc); 312*67e74705SXin Li NoteCandidates(Sema & S,SourceLocation Loc)313*67e74705SXin Li void NoteCandidates(Sema &S, SourceLocation Loc) const { 314*67e74705SXin Li const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); 315*67e74705SXin Li } 316*67e74705SXin Li }; 317*67e74705SXin Li 318*67e74705SXin Li } // end namespace clang 319*67e74705SXin Li 320*67e74705SXin Li #endif 321