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_TEMPLATE_DEDUCTION_H 14 #define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_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 Warnings (and follow-on notes) that were suppressed due to 44 /// SFINAE while performing template argument deduction. 45 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; 46 47 TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; 48 void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; 49 50 public: 51 TemplateDeductionInfo(SourceLocation Loc) 52 : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false), 53 Expression(nullptr) {} 54 55 /// \brief Returns the location at which template argument is 56 /// occurring. 57 SourceLocation getLocation() const { 58 return Loc; 59 } 60 61 /// \brief Take ownership of the deduced template argument list. 62 TemplateArgumentList *take() { 63 TemplateArgumentList *Result = Deduced; 64 Deduced = nullptr; 65 return Result; 66 } 67 68 /// \brief Take ownership of the SFINAE diagnostic. 69 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { 70 assert(HasSFINAEDiagnostic); 71 PD.first = SuppressedDiagnostics.front().first; 72 PD.second.swap(SuppressedDiagnostics.front().second); 73 SuppressedDiagnostics.clear(); 74 HasSFINAEDiagnostic = false; 75 } 76 77 /// \brief Provide a new template argument list that contains the 78 /// results of template argument deduction. 79 void reset(TemplateArgumentList *NewDeduced) { 80 Deduced = NewDeduced; 81 } 82 83 /// \brief Is a SFINAE diagnostic available? 84 bool hasSFINAEDiagnostic() const { 85 return HasSFINAEDiagnostic; 86 } 87 88 /// \brief Set the diagnostic which caused the SFINAE failure. 89 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { 90 // Only collect the first diagnostic. 91 if (HasSFINAEDiagnostic) 92 return; 93 SuppressedDiagnostics.clear(); 94 SuppressedDiagnostics.push_back( 95 std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 96 SuppressedDiagnostics.back().second.swap(PD); 97 HasSFINAEDiagnostic = true; 98 } 99 100 /// \brief Add a new diagnostic to the set of diagnostics 101 void addSuppressedDiagnostic(SourceLocation Loc, 102 PartialDiagnostic PD) { 103 if (HasSFINAEDiagnostic) 104 return; 105 SuppressedDiagnostics.push_back( 106 std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 107 SuppressedDiagnostics.back().second.swap(PD); 108 } 109 110 /// \brief Iterator over the set of suppressed diagnostics. 111 typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator 112 diag_iterator; 113 114 /// \brief Returns an iterator at the beginning of the sequence of suppressed 115 /// diagnostics. 116 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } 117 118 /// \brief Returns an iterator at the end of the sequence of suppressed 119 /// diagnostics. 120 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } 121 122 /// \brief The template parameter to which a template argument 123 /// deduction failure refers. 124 /// 125 /// Depending on the result of template argument deduction, this 126 /// template parameter may have different meanings: 127 /// 128 /// TDK_Incomplete: this is the first template parameter whose 129 /// corresponding template argument was not deduced. 130 /// 131 /// TDK_Inconsistent: this is the template parameter for which 132 /// two different template argument values were deduced. 133 TemplateParameter Param; 134 135 /// \brief The first template argument to which the template 136 /// argument deduction failure refers. 137 /// 138 /// Depending on the result of the template argument deduction, 139 /// this template argument may have different meanings: 140 /// 141 /// TDK_Inconsistent: this argument is the first value deduced 142 /// for the corresponding template parameter. 143 /// 144 /// TDK_SubstitutionFailure: this argument is the template 145 /// argument we were instantiating when we encountered an error. 146 /// 147 /// TDK_NonDeducedMismatch: this is the component of the 'parameter' 148 /// of the deduction, directly provided in the source code. 149 TemplateArgument FirstArg; 150 151 /// \brief The second template argument to which the template 152 /// argument deduction failure refers. 153 /// 154 /// TDK_NonDeducedMismatch: this is the mismatching component of the 155 /// 'argument' of the deduction, from which we are deducing arguments. 156 /// 157 /// FIXME: Finish documenting this. 158 TemplateArgument SecondArg; 159 160 /// \brief The expression which caused a deduction failure. 161 /// 162 /// TDK_FailedOverloadResolution: this argument is the reference to 163 /// an overloaded function which could not be resolved to a specific 164 /// function. 165 Expr *Expression; 166 167 /// \brief Information on packs that we're currently expanding. 168 /// 169 /// FIXME: This should be kept internal to SemaTemplateDeduction. 170 SmallVector<DeducedPack *, 8> PendingDeducedPacks; 171 }; 172 173 } // end namespace sema 174 175 /// A structure used to record information about a failed 176 /// template argument deduction, for diagnosis. 177 struct DeductionFailureInfo { 178 /// A Sema::TemplateDeductionResult. 179 unsigned Result : 8; 180 181 /// \brief Indicates whether a diagnostic is stored in Diagnostic. 182 unsigned HasDiagnostic : 1; 183 184 /// \brief Opaque pointer containing additional data about 185 /// this deduction failure. 186 void *Data; 187 188 /// \brief A diagnostic indicating why deduction failed. 189 union { 190 void *Align; 191 char Diagnostic[sizeof(PartialDiagnosticAt)]; 192 }; 193 194 /// \brief Retrieve the diagnostic which caused this deduction failure, 195 /// if any. 196 PartialDiagnosticAt *getSFINAEDiagnostic(); 197 198 /// \brief Retrieve the template parameter this deduction failure 199 /// refers to, if any. 200 TemplateParameter getTemplateParameter(); 201 202 /// \brief Retrieve the template argument list associated with this 203 /// deduction failure, if any. 204 TemplateArgumentList *getTemplateArgumentList(); 205 206 /// \brief Return the first template argument this deduction failure 207 /// refers to, if any. 208 const TemplateArgument *getFirstArg(); 209 210 /// \brief Return the second template argument this deduction failure 211 /// refers to, if any. 212 const TemplateArgument *getSecondArg(); 213 214 /// \brief Return the expression this deduction failure refers to, 215 /// if any. 216 Expr *getExpr(); 217 218 /// \brief Free any memory associated with this deduction failure. 219 void Destroy(); 220 }; 221 222 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate 223 /// which keeps track of template argument deduction failure info, when 224 /// handling explicit specializations (and instantiations) of templates 225 /// beyond function overloading. 226 /// For now, assume that the candidates are non-matching specializations. 227 /// TODO: In the future, we may need to unify/generalize this with 228 /// OverloadCandidate. 229 struct TemplateSpecCandidate { 230 /// Specialization - The actual specialization that this candidate 231 /// represents. When NULL, this may be a built-in candidate. 232 Decl *Specialization; 233 234 /// Template argument deduction info 235 DeductionFailureInfo DeductionFailure; 236 237 void set(Decl *Spec, DeductionFailureInfo Info) { 238 Specialization = Spec; 239 DeductionFailure = Info; 240 } 241 242 /// Diagnose a template argument deduction failure. 243 void NoteDeductionFailure(Sema &S); 244 }; 245 246 /// TemplateSpecCandidateSet - A set of generalized overload candidates, 247 /// used in template specializations. 248 /// TODO: In the future, we may need to unify/generalize this with 249 /// OverloadCandidateSet. 250 class TemplateSpecCandidateSet { 251 SmallVector<TemplateSpecCandidate, 16> Candidates; 252 SourceLocation Loc; 253 254 TemplateSpecCandidateSet( 255 const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; 256 void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; 257 258 void destroyCandidates(); 259 260 public: 261 TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {} 262 ~TemplateSpecCandidateSet() { destroyCandidates(); } 263 264 SourceLocation getLocation() const { return Loc; } 265 266 /// \brief Clear out all of the candidates. 267 /// TODO: This may be unnecessary. 268 void clear(); 269 270 typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator; 271 iterator begin() { return Candidates.begin(); } 272 iterator end() { return Candidates.end(); } 273 274 size_t size() const { return Candidates.size(); } 275 bool empty() const { return Candidates.empty(); } 276 277 /// \brief Add a new candidate with NumConversions conversion sequence slots 278 /// to the overload set. 279 TemplateSpecCandidate &addCandidate() { 280 Candidates.push_back(TemplateSpecCandidate()); 281 return Candidates.back(); 282 } 283 284 void NoteCandidates(Sema &S, SourceLocation Loc); 285 286 void NoteCandidates(Sema &S, SourceLocation Loc) const { 287 const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); 288 } 289 }; 290 291 } // end namespace clang 292 293 #endif 294