1212795Sdim//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/ 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim//===----------------------------------------------------------------------===/ 8212795Sdim// 9212795Sdim// This file provides types used with Sema's template argument deduction 10212795Sdim// routines. 11212795Sdim// 12212795Sdim//===----------------------------------------------------------------------===/ 13212795Sdim#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H 14212795Sdim#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H 15212795Sdim 16249423Sdim#include "clang/AST/DeclTemplate.h" 17218893Sdim#include "clang/Basic/PartialDiagnostic.h" 18218893Sdim#include "llvm/ADT/SmallVector.h" 19212795Sdim 20212795Sdimnamespace clang { 21212795Sdim 22212795Sdimclass TemplateArgumentList; 23263508Sdimclass Sema; 24212795Sdim 25212795Sdimnamespace sema { 26234353Sdim 27212795Sdim/// \brief Provides information about an attempted template argument 28212795Sdim/// deduction, whose success or failure was described by a 29212795Sdim/// TemplateDeductionResult value. 30212795Sdimclass TemplateDeductionInfo { 31212795Sdim /// \brief The deduced template argument list. 32212795Sdim /// 33212795Sdim TemplateArgumentList *Deduced; 34212795Sdim 35212795Sdim /// \brief The source location at which template argument 36212795Sdim /// deduction is occurring. 37212795Sdim SourceLocation Loc; 38212795Sdim 39239462Sdim /// \brief Have we suppressed an error during deduction? 40239462Sdim bool HasSFINAEDiagnostic; 41239462Sdim 42234353Sdim /// \brief Warnings (and follow-on notes) that were suppressed due to 43218893Sdim /// SFINAE while performing template argument deduction. 44226633Sdim SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; 45234353Sdim 46243830Sdim TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; 47243830Sdim void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; 48212795Sdim 49212795Sdimpublic: 50243830Sdim TemplateDeductionInfo(SourceLocation Loc) 51249423Sdim : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { } 52212795Sdim 53212795Sdim /// \brief Returns the location at which template argument is 54221345Sdim /// occurring. 55212795Sdim SourceLocation getLocation() const { 56212795Sdim return Loc; 57212795Sdim } 58212795Sdim 59212795Sdim /// \brief Take ownership of the deduced template argument list. 60212795Sdim TemplateArgumentList *take() { 61212795Sdim TemplateArgumentList *Result = Deduced; 62212795Sdim Deduced = 0; 63212795Sdim return Result; 64212795Sdim } 65212795Sdim 66239462Sdim /// \brief Take ownership of the SFINAE diagnostic. 67239462Sdim void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { 68239462Sdim assert(HasSFINAEDiagnostic); 69239462Sdim PD.first = SuppressedDiagnostics.front().first; 70239462Sdim PD.second.swap(SuppressedDiagnostics.front().second); 71239462Sdim SuppressedDiagnostics.clear(); 72239462Sdim HasSFINAEDiagnostic = false; 73239462Sdim } 74239462Sdim 75212795Sdim /// \brief Provide a new template argument list that contains the 76212795Sdim /// results of template argument deduction. 77212795Sdim void reset(TemplateArgumentList *NewDeduced) { 78212795Sdim Deduced = NewDeduced; 79212795Sdim } 80212795Sdim 81239462Sdim /// \brief Is a SFINAE diagnostic available? 82239462Sdim bool hasSFINAEDiagnostic() const { 83239462Sdim return HasSFINAEDiagnostic; 84239462Sdim } 85239462Sdim 86239462Sdim /// \brief Set the diagnostic which caused the SFINAE failure. 87239462Sdim void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { 88239462Sdim // Only collect the first diagnostic. 89239462Sdim if (HasSFINAEDiagnostic) 90239462Sdim return; 91239462Sdim SuppressedDiagnostics.clear(); 92239462Sdim SuppressedDiagnostics.push_back( 93239462Sdim std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 94239462Sdim SuppressedDiagnostics.back().second.swap(PD); 95239462Sdim HasSFINAEDiagnostic = true; 96239462Sdim } 97239462Sdim 98234353Sdim /// \brief Add a new diagnostic to the set of diagnostics 99234353Sdim void addSuppressedDiagnostic(SourceLocation Loc, 100239462Sdim PartialDiagnostic PD) { 101239462Sdim if (HasSFINAEDiagnostic) 102239462Sdim return; 103239462Sdim SuppressedDiagnostics.push_back( 104239462Sdim std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 105239462Sdim SuppressedDiagnostics.back().second.swap(PD); 106218893Sdim } 107234353Sdim 108218893Sdim /// \brief Iterator over the set of suppressed diagnostics. 109234353Sdim typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator 110218893Sdim diag_iterator; 111234353Sdim 112218893Sdim /// \brief Returns an iterator at the beginning of the sequence of suppressed 113218893Sdim /// diagnostics. 114218893Sdim diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } 115234353Sdim 116218893Sdim /// \brief Returns an iterator at the end of the sequence of suppressed 117218893Sdim /// diagnostics. 118218893Sdim diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } 119234353Sdim 120212795Sdim /// \brief The template parameter to which a template argument 121212795Sdim /// deduction failure refers. 122212795Sdim /// 123212795Sdim /// Depending on the result of template argument deduction, this 124212795Sdim /// template parameter may have different meanings: 125212795Sdim /// 126212795Sdim /// TDK_Incomplete: this is the first template parameter whose 127212795Sdim /// corresponding template argument was not deduced. 128212795Sdim /// 129212795Sdim /// TDK_Inconsistent: this is the template parameter for which 130212795Sdim /// two different template argument values were deduced. 131212795Sdim TemplateParameter Param; 132212795Sdim 133212795Sdim /// \brief The first template argument to which the template 134212795Sdim /// argument deduction failure refers. 135212795Sdim /// 136212795Sdim /// Depending on the result of the template argument deduction, 137212795Sdim /// this template argument may have different meanings: 138212795Sdim /// 139212795Sdim /// TDK_Inconsistent: this argument is the first value deduced 140212795Sdim /// for the corresponding template parameter. 141212795Sdim /// 142212795Sdim /// TDK_SubstitutionFailure: this argument is the template 143212795Sdim /// argument we were instantiating when we encountered an error. 144212795Sdim /// 145249423Sdim /// TDK_NonDeducedMismatch: this is the component of the 'parameter' 146249423Sdim /// of the deduction, directly provided in the source code. 147212795Sdim TemplateArgument FirstArg; 148212795Sdim 149212795Sdim /// \brief The second template argument to which the template 150212795Sdim /// argument deduction failure refers. 151212795Sdim /// 152249423Sdim /// TDK_NonDeducedMismatch: this is the mismatching component of the 153249423Sdim /// 'argument' of the deduction, from which we are deducing arguments. 154249423Sdim /// 155212795Sdim /// FIXME: Finish documenting this. 156212795Sdim TemplateArgument SecondArg; 157249423Sdim 158249423Sdim /// \brief The expression which caused a deduction failure. 159249423Sdim /// 160249423Sdim /// TDK_FailedOverloadResolution: this argument is the reference to 161251662Sdim /// an overloaded function which could not be resolved to a specific 162251662Sdim /// function. 163249423Sdim Expr *Expression; 164212795Sdim}; 165212795Sdim 166263508Sdim} // end namespace sema 167212795Sdim 168263508Sdim/// A structure used to record information about a failed 169263508Sdim/// template argument deduction, for diagnosis. 170263508Sdimstruct DeductionFailureInfo { 171263508Sdim /// A Sema::TemplateDeductionResult. 172263508Sdim unsigned Result : 8; 173263508Sdim 174263508Sdim /// \brief Indicates whether a diagnostic is stored in Diagnostic. 175263508Sdim unsigned HasDiagnostic : 1; 176263508Sdim 177263508Sdim /// \brief Opaque pointer containing additional data about 178263508Sdim /// this deduction failure. 179263508Sdim void *Data; 180263508Sdim 181263508Sdim /// \brief A diagnostic indicating why deduction failed. 182263508Sdim union { 183263508Sdim void *Align; 184263508Sdim char Diagnostic[sizeof(PartialDiagnosticAt)]; 185263508Sdim }; 186263508Sdim 187263508Sdim /// \brief Retrieve the diagnostic which caused this deduction failure, 188263508Sdim /// if any. 189263508Sdim PartialDiagnosticAt *getSFINAEDiagnostic(); 190263508Sdim 191263508Sdim /// \brief Retrieve the template parameter this deduction failure 192263508Sdim /// refers to, if any. 193263508Sdim TemplateParameter getTemplateParameter(); 194263508Sdim 195263508Sdim /// \brief Retrieve the template argument list associated with this 196263508Sdim /// deduction failure, if any. 197263508Sdim TemplateArgumentList *getTemplateArgumentList(); 198263508Sdim 199263508Sdim /// \brief Return the first template argument this deduction failure 200263508Sdim /// refers to, if any. 201263508Sdim const TemplateArgument *getFirstArg(); 202263508Sdim 203263508Sdim /// \brief Return the second template argument this deduction failure 204263508Sdim /// refers to, if any. 205263508Sdim const TemplateArgument *getSecondArg(); 206263508Sdim 207263508Sdim /// \brief Return the expression this deduction failure refers to, 208263508Sdim /// if any. 209263508Sdim Expr *getExpr(); 210263508Sdim 211263508Sdim /// \brief Free any memory associated with this deduction failure. 212263508Sdim void Destroy(); 213263508Sdim}; 214263508Sdim 215263508Sdim/// TemplateSpecCandidate - This is a generalization of OverloadCandidate 216263508Sdim/// which keeps track of template argument deduction failure info, when 217263508Sdim/// handling explicit specializations (and instantiations) of templates 218263508Sdim/// beyond function overloading. 219263508Sdim/// For now, assume that the candidates are non-matching specializations. 220263508Sdim/// TODO: In the future, we may need to unify/generalize this with 221263508Sdim/// OverloadCandidate. 222263508Sdimstruct TemplateSpecCandidate { 223263508Sdim /// Specialization - The actual specialization that this candidate 224263508Sdim /// represents. When NULL, this may be a built-in candidate. 225263508Sdim Decl *Specialization; 226263508Sdim 227263508Sdim /// Template argument deduction info 228263508Sdim DeductionFailureInfo DeductionFailure; 229263508Sdim 230263508Sdim void set(Decl *Spec, DeductionFailureInfo Info) { 231263508Sdim Specialization = Spec; 232263508Sdim DeductionFailure = Info; 233263508Sdim } 234263508Sdim 235263508Sdim /// Diagnose a template argument deduction failure. 236263508Sdim void NoteDeductionFailure(Sema &S); 237263508Sdim}; 238263508Sdim 239263508Sdim/// TemplateSpecCandidateSet - A set of generalized overload candidates, 240263508Sdim/// used in template specializations. 241263508Sdim/// TODO: In the future, we may need to unify/generalize this with 242263508Sdim/// OverloadCandidateSet. 243263508Sdimclass TemplateSpecCandidateSet { 244263508Sdim SmallVector<TemplateSpecCandidate, 16> Candidates; 245263508Sdim SourceLocation Loc; 246263508Sdim 247263508Sdim TemplateSpecCandidateSet( 248263508Sdim const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; 249263508Sdim void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; 250263508Sdim 251263508Sdim void destroyCandidates(); 252263508Sdim 253263508Sdimpublic: 254263508Sdim TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {} 255263508Sdim ~TemplateSpecCandidateSet() { destroyCandidates(); } 256263508Sdim 257263508Sdim SourceLocation getLocation() const { return Loc; } 258263508Sdim 259263508Sdim /// \brief Clear out all of the candidates. 260263508Sdim /// TODO: This may be unnecessary. 261263508Sdim void clear(); 262263508Sdim 263263508Sdim typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator; 264263508Sdim iterator begin() { return Candidates.begin(); } 265263508Sdim iterator end() { return Candidates.end(); } 266263508Sdim 267263508Sdim size_t size() const { return Candidates.size(); } 268263508Sdim bool empty() const { return Candidates.empty(); } 269263508Sdim 270263508Sdim /// \brief Add a new candidate with NumConversions conversion sequence slots 271263508Sdim /// to the overload set. 272263508Sdim TemplateSpecCandidate &addCandidate() { 273263508Sdim Candidates.push_back(TemplateSpecCandidate()); 274263508Sdim return Candidates.back(); 275263508Sdim } 276263508Sdim 277263508Sdim void NoteCandidates(Sema &S, SourceLocation Loc); 278263508Sdim 279263508Sdim void NoteCandidates(Sema &S, SourceLocation Loc) const { 280263508Sdim const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); 281263508Sdim } 282263508Sdim}; 283263508Sdim 284263508Sdim} // end namespace clang 285263508Sdim 286212795Sdim#endif 287