clang API Documentation

TemplateDeduction.h
Go to the documentation of this file.
00001 //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //===----------------------------------------------------------------------===/
00008 //
00009 //  This file provides types used with Sema's template argument deduction
00010 // routines.
00011 //
00012 //===----------------------------------------------------------------------===/
00013 #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
00014 #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
00015 
00016 #include "clang/AST/DeclTemplate.h"
00017 #include "clang/Basic/PartialDiagnostic.h"
00018 #include "llvm/ADT/SmallVector.h"
00019 
00020 namespace clang {
00021 
00022 struct DeducedPack;
00023 class TemplateArgumentList;
00024 class Sema;
00025 
00026 namespace sema {
00027 
00028 /// \brief Provides information about an attempted template argument
00029 /// deduction, whose success or failure was described by a
00030 /// TemplateDeductionResult value.
00031 class TemplateDeductionInfo {
00032   /// \brief The deduced template argument list.
00033   ///
00034   TemplateArgumentList *Deduced;
00035 
00036   /// \brief The source location at which template argument
00037   /// deduction is occurring.
00038   SourceLocation Loc;
00039 
00040   /// \brief Have we suppressed an error during deduction?
00041   bool HasSFINAEDiagnostic;
00042 
00043   /// \brief Warnings (and follow-on notes) that were suppressed due to
00044   /// SFINAE while performing template argument deduction.
00045   SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
00046 
00047   TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
00048   void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
00049 
00050 public:
00051   TemplateDeductionInfo(SourceLocation Loc)
00052     : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
00053       Expression(nullptr) {}
00054 
00055   /// \brief Returns the location at which template argument is
00056   /// occurring.
00057   SourceLocation getLocation() const {
00058     return Loc;
00059   }
00060 
00061   /// \brief Take ownership of the deduced template argument list.
00062   TemplateArgumentList *take() {
00063     TemplateArgumentList *Result = Deduced;
00064     Deduced = nullptr;
00065     return Result;
00066   }
00067 
00068   /// \brief Take ownership of the SFINAE diagnostic.
00069   void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
00070     assert(HasSFINAEDiagnostic);
00071     PD.first = SuppressedDiagnostics.front().first;
00072     PD.second.swap(SuppressedDiagnostics.front().second);
00073     SuppressedDiagnostics.clear();
00074     HasSFINAEDiagnostic = false;
00075   }
00076 
00077   /// \brief Provide a new template argument list that contains the
00078   /// results of template argument deduction.
00079   void reset(TemplateArgumentList *NewDeduced) {
00080     Deduced = NewDeduced;
00081   }
00082 
00083   /// \brief Is a SFINAE diagnostic available?
00084   bool hasSFINAEDiagnostic() const {
00085     return HasSFINAEDiagnostic;
00086   }
00087 
00088   /// \brief Set the diagnostic which caused the SFINAE failure.
00089   void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
00090     // Only collect the first diagnostic.
00091     if (HasSFINAEDiagnostic)
00092       return;
00093     SuppressedDiagnostics.clear();
00094     SuppressedDiagnostics.push_back(
00095         std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
00096     SuppressedDiagnostics.back().second.swap(PD);
00097     HasSFINAEDiagnostic = true;
00098   }
00099 
00100   /// \brief Add a new diagnostic to the set of diagnostics
00101   void addSuppressedDiagnostic(SourceLocation Loc,
00102                                PartialDiagnostic PD) {
00103     if (HasSFINAEDiagnostic)
00104       return;
00105     SuppressedDiagnostics.push_back(
00106         std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
00107     SuppressedDiagnostics.back().second.swap(PD);
00108   }
00109 
00110   /// \brief Iterator over the set of suppressed diagnostics.
00111   typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
00112     diag_iterator;
00113 
00114   /// \brief Returns an iterator at the beginning of the sequence of suppressed
00115   /// diagnostics.
00116   diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
00117 
00118   /// \brief Returns an iterator at the end of the sequence of suppressed
00119   /// diagnostics.
00120   diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
00121 
00122   /// \brief The template parameter to which a template argument
00123   /// deduction failure refers.
00124   ///
00125   /// Depending on the result of template argument deduction, this
00126   /// template parameter may have different meanings:
00127   ///
00128   ///   TDK_Incomplete: this is the first template parameter whose
00129   ///   corresponding template argument was not deduced.
00130   ///
00131   ///   TDK_Inconsistent: this is the template parameter for which
00132   ///   two different template argument values were deduced.
00133   TemplateParameter Param;
00134 
00135   /// \brief The first template argument to which the template
00136   /// argument deduction failure refers.
00137   ///
00138   /// Depending on the result of the template argument deduction,
00139   /// this template argument may have different meanings:
00140   ///
00141   ///   TDK_Inconsistent: this argument is the first value deduced
00142   ///   for the corresponding template parameter.
00143   ///
00144   ///   TDK_SubstitutionFailure: this argument is the template
00145   ///   argument we were instantiating when we encountered an error.
00146   ///
00147   ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
00148   ///   of the deduction, directly provided in the source code.
00149   TemplateArgument FirstArg;
00150 
00151   /// \brief The second template argument to which the template
00152   /// argument deduction failure refers.
00153   ///
00154   ///   TDK_NonDeducedMismatch: this is the mismatching component of the
00155   ///   'argument' of the deduction, from which we are deducing arguments.
00156   ///
00157   /// FIXME: Finish documenting this.
00158   TemplateArgument SecondArg;
00159 
00160   /// \brief The expression which caused a deduction failure.
00161   ///
00162   ///   TDK_FailedOverloadResolution: this argument is the reference to
00163   ///   an overloaded function which could not be resolved to a specific
00164   ///   function.
00165   Expr *Expression;
00166 
00167   /// \brief Information on packs that we're currently expanding.
00168   ///
00169   /// FIXME: This should be kept internal to SemaTemplateDeduction.
00170   SmallVector<DeducedPack *, 8> PendingDeducedPacks;
00171 };
00172 
00173 } // end namespace sema
00174 
00175 /// A structure used to record information about a failed
00176 /// template argument deduction, for diagnosis.
00177 struct DeductionFailureInfo {
00178   /// A Sema::TemplateDeductionResult.
00179   unsigned Result : 8;
00180 
00181   /// \brief Indicates whether a diagnostic is stored in Diagnostic.
00182   unsigned HasDiagnostic : 1;
00183 
00184   /// \brief Opaque pointer containing additional data about
00185   /// this deduction failure.
00186   void *Data;
00187 
00188   /// \brief A diagnostic indicating why deduction failed.
00189   union {
00190     void *Align;
00191     char Diagnostic[sizeof(PartialDiagnosticAt)];
00192   };
00193 
00194   /// \brief Retrieve the diagnostic which caused this deduction failure,
00195   /// if any.
00196   PartialDiagnosticAt *getSFINAEDiagnostic();
00197 
00198   /// \brief Retrieve the template parameter this deduction failure
00199   /// refers to, if any.
00200   TemplateParameter getTemplateParameter();
00201 
00202   /// \brief Retrieve the template argument list associated with this
00203   /// deduction failure, if any.
00204   TemplateArgumentList *getTemplateArgumentList();
00205 
00206   /// \brief Return the first template argument this deduction failure
00207   /// refers to, if any.
00208   const TemplateArgument *getFirstArg();
00209 
00210   /// \brief Return the second template argument this deduction failure
00211   /// refers to, if any.
00212   const TemplateArgument *getSecondArg();
00213 
00214   /// \brief Return the expression this deduction failure refers to,
00215   /// if any.
00216   Expr *getExpr();
00217 
00218   /// \brief Free any memory associated with this deduction failure.
00219   void Destroy();
00220 };
00221 
00222 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
00223 /// which keeps track of template argument deduction failure info, when
00224 /// handling explicit specializations (and instantiations) of templates
00225 /// beyond function overloading.
00226 /// For now, assume that the candidates are non-matching specializations.
00227 /// TODO: In the future, we may need to unify/generalize this with
00228 /// OverloadCandidate.
00229 struct TemplateSpecCandidate {
00230   /// Specialization - The actual specialization that this candidate
00231   /// represents. When NULL, this may be a built-in candidate.
00232   Decl *Specialization;
00233 
00234   /// Template argument deduction info
00235   DeductionFailureInfo DeductionFailure;
00236 
00237   void set(Decl *Spec, DeductionFailureInfo Info) {
00238     Specialization = Spec;
00239     DeductionFailure = Info;
00240   }
00241 
00242   /// Diagnose a template argument deduction failure.
00243   void NoteDeductionFailure(Sema &S);
00244 };
00245 
00246 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
00247 /// used in template specializations.
00248 /// TODO: In the future, we may need to unify/generalize this with
00249 /// OverloadCandidateSet.
00250 class TemplateSpecCandidateSet {
00251   SmallVector<TemplateSpecCandidate, 16> Candidates;
00252   SourceLocation Loc;
00253 
00254   TemplateSpecCandidateSet(
00255       const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
00256   void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
00257 
00258   void destroyCandidates();
00259 
00260 public:
00261   TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {}
00262   ~TemplateSpecCandidateSet() { destroyCandidates(); }
00263 
00264   SourceLocation getLocation() const { return Loc; }
00265 
00266   /// \brief Clear out all of the candidates.
00267   /// TODO: This may be unnecessary.
00268   void clear();
00269 
00270   typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
00271   iterator begin() { return Candidates.begin(); }
00272   iterator end() { return Candidates.end(); }
00273 
00274   size_t size() const { return Candidates.size(); }
00275   bool empty() const { return Candidates.empty(); }
00276 
00277   /// \brief Add a new candidate with NumConversions conversion sequence slots
00278   /// to the overload set.
00279   TemplateSpecCandidate &addCandidate() {
00280     Candidates.push_back(TemplateSpecCandidate());
00281     return Candidates.back();
00282   }
00283 
00284   void NoteCandidates(Sema &S, SourceLocation Loc);
00285 
00286   void NoteCandidates(Sema &S, SourceLocation Loc) const {
00287     const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
00288   }
00289 };
00290 
00291 } // end namespace clang
00292 
00293 #endif