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_TEMPLATE_DEDUCTION_H 14 #define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H 15 16 #include "clang/Basic/PartialDiagnostic.h" 17 #include "clang/AST/DeclTemplate.h" 18 #include "llvm/ADT/SmallVector.h" 19 20 namespace clang { 21 22 class ASTContext; 23 class TemplateArgumentList; 24 25 namespace sema { 26 27 /// \brief Provides information about an attempted template argument 28 /// deduction, whose success or failure was described by a 29 /// TemplateDeductionResult value. 30 class TemplateDeductionInfo { 31 /// \brief The context in which the template arguments are stored. 32 ASTContext &Context; 33 34 /// \brief The deduced template argument list. 35 /// 36 TemplateArgumentList *Deduced; 37 38 /// \brief The source location at which template argument 39 /// deduction is occurring. 40 SourceLocation Loc; 41 42 /// \brief Have we suppressed an error during deduction? 43 bool HasSFINAEDiagnostic; 44 45 /// \brief Warnings (and follow-on notes) that were suppressed due to 46 /// SFINAE while performing template argument deduction. 47 SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; 48 49 // do not implement these 50 TemplateDeductionInfo(const TemplateDeductionInfo&); 51 TemplateDeductionInfo &operator=(const TemplateDeductionInfo&); 52 53 public: TemplateDeductionInfo(ASTContext & Context,SourceLocation Loc)54 TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc) 55 : Context(Context), Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { } 56 ~TemplateDeductionInfo()57 ~TemplateDeductionInfo() { 58 // FIXME: if (Deduced) Deduced->Destroy(Context); 59 } 60 61 /// \brief Returns the location at which template argument is 62 /// occurring. getLocation()63 SourceLocation getLocation() const { 64 return Loc; 65 } 66 67 /// \brief Take ownership of the deduced template argument list. take()68 TemplateArgumentList *take() { 69 TemplateArgumentList *Result = Deduced; 70 Deduced = 0; 71 return Result; 72 } 73 74 /// \brief Take ownership of the SFINAE diagnostic. takeSFINAEDiagnostic(PartialDiagnosticAt & PD)75 void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { 76 assert(HasSFINAEDiagnostic); 77 PD.first = SuppressedDiagnostics.front().first; 78 PD.second.swap(SuppressedDiagnostics.front().second); 79 SuppressedDiagnostics.clear(); 80 HasSFINAEDiagnostic = false; 81 } 82 83 /// \brief Provide a new template argument list that contains the 84 /// results of template argument deduction. reset(TemplateArgumentList * NewDeduced)85 void reset(TemplateArgumentList *NewDeduced) { 86 // FIXME: if (Deduced) Deduced->Destroy(Context); 87 Deduced = NewDeduced; 88 } 89 90 /// \brief Is a SFINAE diagnostic available? hasSFINAEDiagnostic()91 bool hasSFINAEDiagnostic() const { 92 return HasSFINAEDiagnostic; 93 } 94 95 /// \brief Set the diagnostic which caused the SFINAE failure. addSFINAEDiagnostic(SourceLocation Loc,PartialDiagnostic PD)96 void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { 97 // Only collect the first diagnostic. 98 if (HasSFINAEDiagnostic) 99 return; 100 SuppressedDiagnostics.clear(); 101 SuppressedDiagnostics.push_back( 102 std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 103 SuppressedDiagnostics.back().second.swap(PD); 104 HasSFINAEDiagnostic = true; 105 } 106 107 /// \brief Add a new diagnostic to the set of diagnostics addSuppressedDiagnostic(SourceLocation Loc,PartialDiagnostic PD)108 void addSuppressedDiagnostic(SourceLocation Loc, 109 PartialDiagnostic PD) { 110 if (HasSFINAEDiagnostic) 111 return; 112 SuppressedDiagnostics.push_back( 113 std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); 114 SuppressedDiagnostics.back().second.swap(PD); 115 } 116 117 /// \brief Iterator over the set of suppressed diagnostics. 118 typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator 119 diag_iterator; 120 121 /// \brief Returns an iterator at the beginning of the sequence of suppressed 122 /// diagnostics. diag_begin()123 diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } 124 125 /// \brief Returns an iterator at the end of the sequence of suppressed 126 /// diagnostics. diag_end()127 diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } 128 129 /// \brief The template parameter to which a template argument 130 /// deduction failure refers. 131 /// 132 /// Depending on the result of template argument deduction, this 133 /// template parameter may have different meanings: 134 /// 135 /// TDK_Incomplete: this is the first template parameter whose 136 /// corresponding template argument was not deduced. 137 /// 138 /// TDK_Inconsistent: this is the template parameter for which 139 /// two different template argument values were deduced. 140 TemplateParameter Param; 141 142 /// \brief The first template argument to which the template 143 /// argument deduction failure refers. 144 /// 145 /// Depending on the result of the template argument deduction, 146 /// this template argument may have different meanings: 147 /// 148 /// TDK_Inconsistent: this argument is the first value deduced 149 /// for the corresponding template parameter. 150 /// 151 /// TDK_SubstitutionFailure: this argument is the template 152 /// argument we were instantiating when we encountered an error. 153 /// 154 /// TDK_NonDeducedMismatch: this is the template argument 155 /// provided in the source code. 156 TemplateArgument FirstArg; 157 158 /// \brief The second template argument to which the template 159 /// argument deduction failure refers. 160 /// 161 /// FIXME: Finish documenting this. 162 TemplateArgument SecondArg; 163 }; 164 165 } 166 } 167 168 #endif 169