• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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