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