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