TemplateDeduction.h revision 360784
1//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file provides types used with Sema's template argument deduction 10// routines. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H 15#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H 16 17#include "clang/Sema/Ownership.h" 18#include "clang/Sema/SemaConcept.h" 19#include "clang/AST/ASTConcept.h" 20#include "clang/AST/DeclAccessPair.h" 21#include "clang/AST/DeclTemplate.h" 22#include "clang/AST/TemplateBase.h" 23#include "clang/Basic/PartialDiagnostic.h" 24#include "clang/Basic/SourceLocation.h" 25#include "llvm/ADT/Optional.h" 26#include "llvm/ADT/SmallVector.h" 27#include <cassert> 28#include <cstddef> 29#include <utility> 30 31namespace clang { 32 33class Decl; 34struct DeducedPack; 35class Sema; 36 37namespace sema { 38 39/// Provides information about an attempted template argument 40/// deduction, whose success or failure was described by a 41/// TemplateDeductionResult value. 42class TemplateDeductionInfo { 43 /// The deduced template argument list. 44 TemplateArgumentList *Deduced = nullptr; 45 46 /// The source location at which template argument 47 /// deduction is occurring. 48 SourceLocation Loc; 49 50 /// Have we suppressed an error during deduction? 51 bool HasSFINAEDiagnostic = false; 52 53 /// The template parameter depth for which we're performing deduction. 54 unsigned DeducedDepth; 55 56 /// The number of parameters with explicitly-specified template arguments, 57 /// up to and including the partially-specified pack (if any). 58 unsigned ExplicitArgs = 0; 59 60 /// Warnings (and follow-on notes) that were suppressed due to 61 /// SFINAE while performing template argument deduction. 62 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; 63 64public: 65 TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0) 66 : Loc(Loc), DeducedDepth(DeducedDepth) {} 67 TemplateDeductionInfo(const TemplateDeductionInfo &) = delete; 68 TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete; 69 70 enum ForBaseTag { ForBase }; 71 /// Create temporary template deduction info for speculatively deducing 72 /// against a base class of an argument's type. 73 TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info) 74 : Deduced(Info.Deduced), Loc(Info.Loc), DeducedDepth(Info.DeducedDepth), 75 ExplicitArgs(Info.ExplicitArgs) {} 76 77 /// Returns the location at which template argument is 78 /// occurring. 79 SourceLocation getLocation() const { 80 return Loc; 81 } 82 83 /// The depth of template parameters for which deduction is being 84 /// performed. 85 unsigned getDeducedDepth() const { 86 return DeducedDepth; 87 } 88 89 /// Get the number of explicitly-specified arguments. 90 unsigned getNumExplicitArgs() const { 91 return ExplicitArgs; 92 } 93 94 /// Take ownership of the deduced template argument list. 95 TemplateArgumentList *take() { 96 TemplateArgumentList *Result = Deduced; 97 Deduced = nullptr; 98 return Result; 99 } 100 101 /// Take ownership of the SFINAE diagnostic. 102 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { 103 assert(HasSFINAEDiagnostic); 104 PD.first = SuppressedDiagnostics.front().first; 105 PD.second.swap(SuppressedDiagnostics.front().second); 106 clearSFINAEDiagnostic(); 107 } 108 109 /// Discard any SFINAE diagnostics. 110 void clearSFINAEDiagnostic() { 111 SuppressedDiagnostics.clear(); 112 HasSFINAEDiagnostic = false; 113 } 114 115 /// Peek at the SFINAE diagnostic. 116 const PartialDiagnosticAt &peekSFINAEDiagnostic() const { 117 assert(HasSFINAEDiagnostic); 118 return SuppressedDiagnostics.front(); 119 } 120 121 /// Provide an initial template argument list that contains the 122 /// explicitly-specified arguments. 123 void setExplicitArgs(TemplateArgumentList *NewDeduced) { 124 Deduced = NewDeduced; 125 ExplicitArgs = Deduced->size(); 126 } 127 128 /// Provide a new template argument list that contains the 129 /// results of template argument deduction. 130 void reset(TemplateArgumentList *NewDeduced) { 131 Deduced = NewDeduced; 132 } 133 134 /// Is a SFINAE diagnostic available? 135 bool hasSFINAEDiagnostic() const { 136 return HasSFINAEDiagnostic; 137 } 138 139 /// Set the diagnostic which caused the SFINAE failure. 140 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { 141 // Only collect the first diagnostic. 142 if (HasSFINAEDiagnostic) 143 return; 144 SuppressedDiagnostics.clear(); 145 SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); 146 HasSFINAEDiagnostic = true; 147 } 148 149 /// Add a new diagnostic to the set of diagnostics 150 void addSuppressedDiagnostic(SourceLocation Loc, 151 PartialDiagnostic PD) { 152 if (HasSFINAEDiagnostic) 153 return; 154 SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); 155 } 156 157 /// Iterator over the set of suppressed diagnostics. 158 using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator; 159 160 /// Returns an iterator at the beginning of the sequence of suppressed 161 /// diagnostics. 162 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } 163 164 /// Returns an iterator at the end of the sequence of suppressed 165 /// diagnostics. 166 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } 167 168 /// The template parameter to which a template argument 169 /// deduction failure refers. 170 /// 171 /// Depending on the result of template argument deduction, this 172 /// template parameter may have different meanings: 173 /// 174 /// TDK_Incomplete: this is the first template parameter whose 175 /// corresponding template argument was not deduced. 176 /// 177 /// TDK_IncompletePack: this is the expanded parameter pack for 178 /// which we deduced too few arguments. 179 /// 180 /// TDK_Inconsistent: this is the template parameter for which 181 /// two different template argument values were deduced. 182 TemplateParameter Param; 183 184 /// The first template argument to which the template 185 /// argument deduction failure refers. 186 /// 187 /// Depending on the result of the template argument deduction, 188 /// this template argument may have different meanings: 189 /// 190 /// TDK_IncompletePack: this is the number of arguments we deduced 191 /// for the pack. 192 /// 193 /// TDK_Inconsistent: this argument is the first value deduced 194 /// for the corresponding template parameter. 195 /// 196 /// TDK_SubstitutionFailure: this argument is the template 197 /// argument we were instantiating when we encountered an error. 198 /// 199 /// TDK_DeducedMismatch: this is the parameter type, after substituting 200 /// deduced arguments. 201 /// 202 /// TDK_NonDeducedMismatch: this is the component of the 'parameter' 203 /// of the deduction, directly provided in the source code. 204 TemplateArgument FirstArg; 205 206 /// The second template argument to which the template 207 /// argument deduction failure refers. 208 /// 209 /// TDK_Inconsistent: this argument is the second value deduced 210 /// for the corresponding template parameter. 211 /// 212 /// TDK_DeducedMismatch: this is the (adjusted) call argument type. 213 /// 214 /// TDK_NonDeducedMismatch: this is the mismatching component of the 215 /// 'argument' of the deduction, from which we are deducing arguments. 216 /// 217 /// FIXME: Finish documenting this. 218 TemplateArgument SecondArg; 219 220 /// The index of the function argument that caused a deduction 221 /// failure. 222 /// 223 /// TDK_DeducedMismatch: this is the index of the argument that had a 224 /// different argument type from its substituted parameter type. 225 unsigned CallArgIndex = 0; 226 227 /// Information on packs that we're currently expanding. 228 /// 229 /// FIXME: This should be kept internal to SemaTemplateDeduction. 230 SmallVector<DeducedPack *, 8> PendingDeducedPacks; 231 232 /// \brief The constraint satisfaction details resulting from the associated 233 /// constraints satisfaction tests. 234 ConstraintSatisfaction AssociatedConstraintsSatisfaction; 235}; 236 237} // namespace sema 238 239/// A structure used to record information about a failed 240/// template argument deduction, for diagnosis. 241struct DeductionFailureInfo { 242 /// A Sema::TemplateDeductionResult. 243 unsigned Result : 8; 244 245 /// Indicates whether a diagnostic is stored in Diagnostic. 246 unsigned HasDiagnostic : 1; 247 248 /// Opaque pointer containing additional data about 249 /// this deduction failure. 250 void *Data; 251 252 /// A diagnostic indicating why deduction failed. 253 alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)]; 254 255 /// Retrieve the diagnostic which caused this deduction failure, 256 /// if any. 257 PartialDiagnosticAt *getSFINAEDiagnostic(); 258 259 /// Retrieve the template parameter this deduction failure 260 /// refers to, if any. 261 TemplateParameter getTemplateParameter(); 262 263 /// Retrieve the template argument list associated with this 264 /// deduction failure, if any. 265 TemplateArgumentList *getTemplateArgumentList(); 266 267 /// Return the first template argument this deduction failure 268 /// refers to, if any. 269 const TemplateArgument *getFirstArg(); 270 271 /// Return the second template argument this deduction failure 272 /// refers to, if any. 273 const TemplateArgument *getSecondArg(); 274 275 /// Return the index of the call argument that this deduction 276 /// failure refers to, if any. 277 llvm::Optional<unsigned> getCallArgIndex(); 278 279 /// Free any memory associated with this deduction failure. 280 void Destroy(); 281}; 282 283/// TemplateSpecCandidate - This is a generalization of OverloadCandidate 284/// which keeps track of template argument deduction failure info, when 285/// handling explicit specializations (and instantiations) of templates 286/// beyond function overloading. 287/// For now, assume that the candidates are non-matching specializations. 288/// TODO: In the future, we may need to unify/generalize this with 289/// OverloadCandidate. 290struct TemplateSpecCandidate { 291 /// The declaration that was looked up, together with its access. 292 /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl. 293 DeclAccessPair FoundDecl; 294 295 /// Specialization - The actual specialization that this candidate 296 /// represents. When NULL, this may be a built-in candidate. 297 Decl *Specialization; 298 299 /// Template argument deduction info 300 DeductionFailureInfo DeductionFailure; 301 302 void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) { 303 FoundDecl = Found; 304 Specialization = Spec; 305 DeductionFailure = Info; 306 } 307 308 /// Diagnose a template argument deduction failure. 309 void NoteDeductionFailure(Sema &S, bool ForTakingAddress); 310}; 311 312/// TemplateSpecCandidateSet - A set of generalized overload candidates, 313/// used in template specializations. 314/// TODO: In the future, we may need to unify/generalize this with 315/// OverloadCandidateSet. 316class TemplateSpecCandidateSet { 317 SmallVector<TemplateSpecCandidate, 16> Candidates; 318 SourceLocation Loc; 319 320 // Stores whether we're taking the address of these candidates. This helps us 321 // produce better error messages when dealing with the pass_object_size 322 // attribute on parameters. 323 bool ForTakingAddress; 324 325 void destroyCandidates(); 326 327public: 328 TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false) 329 : Loc(Loc), ForTakingAddress(ForTakingAddress) {} 330 TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete; 331 TemplateSpecCandidateSet & 332 operator=(const TemplateSpecCandidateSet &) = delete; 333 ~TemplateSpecCandidateSet() { destroyCandidates(); } 334 335 SourceLocation getLocation() const { return Loc; } 336 337 /// Clear out all of the candidates. 338 /// TODO: This may be unnecessary. 339 void clear(); 340 341 using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator; 342 343 iterator begin() { return Candidates.begin(); } 344 iterator end() { return Candidates.end(); } 345 346 size_t size() const { return Candidates.size(); } 347 bool empty() const { return Candidates.empty(); } 348 349 /// Add a new candidate with NumConversions conversion sequence slots 350 /// to the overload set. 351 TemplateSpecCandidate &addCandidate() { 352 Candidates.emplace_back(); 353 return Candidates.back(); 354 } 355 356 void NoteCandidates(Sema &S, SourceLocation Loc); 357 358 void NoteCandidates(Sema &S, SourceLocation Loc) const { 359 const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); 360 } 361}; 362 363} // namespace clang 364 365#endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H 366