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