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