1135446Strhodes//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/ 2254897Serwin// 3153816Sdougb// The LLVM Compiler Infrastructure 4153816Sdougb// 5204619Sdougb// This file is distributed under the University of Illinois Open Source 6135446Strhodes// License. See LICENSE.TXT for details. 7135446Strhodes//===----------------------------------------------------------------------===/ 8153816Sdougb// 9135446Strhodes// This file provides types used with Sema's template argument deduction 10135446Strhodes// routines. 11153816Sdougb// 12135446Strhodes//===----------------------------------------------------------------------===/ 13135446Strhodes#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H 14135446Strhodes#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H 15135446Strhodes 16135446Strhodes#include "clang/AST/DeclTemplate.h" 17234010Sdougb#include "clang/Basic/PartialDiagnostic.h" 18153816Sdougb#include "llvm/ADT/SmallVector.h" 19153816Sdougb 20153816Sdougbnamespace clang { 21153816Sdougb 22170222Sdougbclass TemplateArgumentList; 23153816Sdougbclass Sema; 24153816Sdougb 25225361Sdougbnamespace sema { 26153816Sdougb 27153816Sdougb/// \brief Provides information about an attempted template argument 28153816Sdougb/// deduction, whose success or failure was described by a 29153816Sdougb/// TemplateDeductionResult value. 30153816Sdougbclass TemplateDeductionInfo { 31153816Sdougb /// \brief The deduced template argument list. 32153816Sdougb /// 33153816Sdougb TemplateArgumentList *Deduced; 34170222Sdougb 35153816Sdougb /// \brief The source location at which template argument 36153816Sdougb /// deduction is occurring. 37153816Sdougb SourceLocation Loc; 38170222Sdougb 39153816Sdougb /// \brief Have we suppressed an error during deduction? 40170222Sdougb bool HasSFINAEDiagnostic; 41170222Sdougb 42170222Sdougb /// \brief Warnings (and follow-on notes) that were suppressed due to 43153816Sdougb /// SFINAE while performing template argument deduction. 44153816Sdougb SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; 45153816Sdougb 46170222Sdougb TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; 47153816Sdougb void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; 48170222Sdougb 49170222Sdougbpublic: 50153816Sdougb TemplateDeductionInfo(SourceLocation Loc) 51153816Sdougb : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { } 52153816Sdougb 53153816Sdougb /// \brief Returns the location at which template argument is 54153816Sdougb /// occurring. 55170222Sdougb SourceLocation getLocation() const { 56170222Sdougb return Loc; 57170222Sdougb } 58153816Sdougb 59153816Sdougb /// \brief Take ownership of the deduced template argument list. 60153816Sdougb TemplateArgumentList *take() { 61170222Sdougb TemplateArgumentList *Result = Deduced; 62153816Sdougb Deduced = 0; 63170222Sdougb return Result; 64153816Sdougb } 65153816Sdougb 66153816Sdougb /// \brief Take ownership of the SFINAE diagnostic. 67153816Sdougb void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { 68153816Sdougb assert(HasSFINAEDiagnostic); 69153816Sdougb PD.first = SuppressedDiagnostics.front().first; 70153816Sdougb PD.second.swap(SuppressedDiagnostics.front().second); 71170222Sdougb SuppressedDiagnostics.clear(); 72170222Sdougb HasSFINAEDiagnostic = false; 73170222Sdougb } 74153816Sdougb 75153816Sdougb /// \brief Provide a new template argument list that contains the 76153816Sdougb /// results of template argument deduction. 77170222Sdougb void reset(TemplateArgumentList *NewDeduced) { 78153816Sdougb Deduced = NewDeduced; 79170222Sdougb } 80153816Sdougb 81153816Sdougb /// \brief Is a SFINAE diagnostic available? 82170222Sdougb bool hasSFINAEDiagnostic() const { 83153816Sdougb return HasSFINAEDiagnostic; 84153816Sdougb } 85153816Sdougb 86170222Sdougb /// \brief Set the diagnostic which caused the SFINAE failure. 87153816Sdougb void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { 88170222Sdougb // Only collect the first diagnostic. 89170222Sdougb if (HasSFINAEDiagnostic) 90153816Sdougb return; 91153816Sdougb SuppressedDiagnostics.clear(); 92153816Sdougb SuppressedDiagnostics.push_back( 93254897Serwin std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 94170222Sdougb SuppressedDiagnostics.back().second.swap(PD); 95170222Sdougb HasSFINAEDiagnostic = true; 96170222Sdougb } 97170222Sdougb 98170222Sdougb /// \brief Add a new diagnostic to the set of diagnostics 99170222Sdougb void addSuppressedDiagnostic(SourceLocation Loc, 100170222Sdougb PartialDiagnostic PD) { 101170222Sdougb if (HasSFINAEDiagnostic) 102170222Sdougb return; 103170222Sdougb SuppressedDiagnostics.push_back( 104170222Sdougb std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 105170222Sdougb SuppressedDiagnostics.back().second.swap(PD); 106170222Sdougb } 107170222Sdougb 108170222Sdougb /// \brief Iterator over the set of suppressed diagnostics. 109170222Sdougb typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator 110170222Sdougb diag_iterator; 111170222Sdougb 112170222Sdougb /// \brief Returns an iterator at the beginning of the sequence of suppressed 113170222Sdougb /// diagnostics. 114170222Sdougb diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } 115170222Sdougb 116170222Sdougb /// \brief Returns an iterator at the end of the sequence of suppressed 117170222Sdougb /// diagnostics. 118170222Sdougb diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } 119170222Sdougb 120170222Sdougb /// \brief The template parameter to which a template argument 121170222Sdougb /// deduction failure refers. 122170222Sdougb /// 123170222Sdougb /// Depending on the result of template argument deduction, this 124153816Sdougb /// template parameter may have different meanings: 125153816Sdougb /// 126254897Serwin /// TDK_Incomplete: this is the first template parameter whose 127170222Sdougb /// corresponding template argument was not deduced. 128170222Sdougb /// 129170222Sdougb /// TDK_Inconsistent: this is the template parameter for which 130170222Sdougb /// two different template argument values were deduced. 131170222Sdougb TemplateParameter Param; 132170222Sdougb 133170222Sdougb /// \brief The first template argument to which the template 134170222Sdougb /// argument deduction failure refers. 135170222Sdougb /// 136170222Sdougb /// Depending on the result of the template argument deduction, 137170222Sdougb /// this template argument may have different meanings: 138170222Sdougb /// 139170222Sdougb /// TDK_Inconsistent: this argument is the first value deduced 140170222Sdougb /// for the corresponding template parameter. 141170222Sdougb /// 142170222Sdougb /// TDK_SubstitutionFailure: this argument is the template 143153816Sdougb /// argument we were instantiating when we encountered an error. 144153816Sdougb /// 145254897Serwin /// TDK_NonDeducedMismatch: this is the component of the 'parameter' 146170222Sdougb /// of the deduction, directly provided in the source code. 147170222Sdougb TemplateArgument FirstArg; 148170222Sdougb 149153816Sdougb /// \brief The second template argument to which the template 150153816Sdougb /// argument deduction failure refers. 151254897Serwin /// 152170222Sdougb /// TDK_NonDeducedMismatch: this is the mismatching component of the 153170222Sdougb /// 'argument' of the deduction, from which we are deducing arguments. 154153816Sdougb /// 155153816Sdougb /// FIXME: Finish documenting this. 156153816Sdougb 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. 170struct 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. 222struct 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. 243class 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 253public: 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