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