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