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_TEMPLATEDEDUCTION_H
     14 #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_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 struct DeducedPack;
     23 class TemplateArgumentList;
     24 class Sema;
     25 
     26 namespace sema {
     27 
     28 /// \brief Provides information about an attempted template argument
     29 /// deduction, whose success or failure was described by a
     30 /// TemplateDeductionResult value.
     31 class TemplateDeductionInfo {
     32   /// \brief The deduced template argument list.
     33   ///
     34   TemplateArgumentList *Deduced;
     35 
     36   /// \brief The source location at which template argument
     37   /// deduction is occurring.
     38   SourceLocation Loc;
     39 
     40   /// \brief Have we suppressed an error during deduction?
     41   bool HasSFINAEDiagnostic;
     42 
     43   /// \brief The template parameter depth for which we're performing deduction.
     44   unsigned DeducedDepth;
     45 
     46   /// \brief Warnings (and follow-on notes) that were suppressed due to
     47   /// SFINAE while performing template argument deduction.
     48   SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
     49 
     50   TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
     51   void operator=(const TemplateDeductionInfo &) = delete;
     52 
     53 public:
     54   TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
     55     : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
     56       DeducedDepth(DeducedDepth), CallArgIndex(0) {}
     57 
     58   /// \brief Returns the location at which template argument is
     59   /// occurring.
     60   SourceLocation getLocation() const {
     61     return Loc;
     62   }
     63 
     64   /// \brief The depth of template parameters for which deduction is being
     65   /// performed.
     66   unsigned getDeducedDepth() const {
     67     return DeducedDepth;
     68   }
     69 
     70   /// \brief Take ownership of the deduced template argument list.
     71   TemplateArgumentList *take() {
     72     TemplateArgumentList *Result = Deduced;
     73     Deduced = nullptr;
     74     return Result;
     75   }
     76 
     77   /// \brief Take ownership of the SFINAE diagnostic.
     78   void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
     79     assert(HasSFINAEDiagnostic);
     80     PD.first = SuppressedDiagnostics.front().first;
     81     PD.second.swap(SuppressedDiagnostics.front().second);
     82     clearSFINAEDiagnostic();
     83   }
     84 
     85   /// \brief Discard any SFINAE diagnostics.
     86   void clearSFINAEDiagnostic() {
     87     SuppressedDiagnostics.clear();
     88     HasSFINAEDiagnostic = false;
     89   }
     90 
     91   /// \brief Provide a new template argument list that contains the
     92   /// results of template argument deduction.
     93   void reset(TemplateArgumentList *NewDeduced) {
     94     Deduced = NewDeduced;
     95   }
     96 
     97   /// \brief Is a SFINAE diagnostic available?
     98   bool hasSFINAEDiagnostic() const {
     99     return HasSFINAEDiagnostic;
    100   }
    101 
    102   /// \brief Set the diagnostic which caused the SFINAE failure.
    103   void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
    104     // Only collect the first diagnostic.
    105     if (HasSFINAEDiagnostic)
    106       return;
    107     SuppressedDiagnostics.clear();
    108     SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
    109     HasSFINAEDiagnostic = true;
    110   }
    111 
    112   /// \brief Add a new diagnostic to the set of diagnostics
    113   void addSuppressedDiagnostic(SourceLocation Loc,
    114                                PartialDiagnostic PD) {
    115     if (HasSFINAEDiagnostic)
    116       return;
    117     SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
    118   }
    119 
    120   /// \brief Iterator over the set of suppressed diagnostics.
    121   typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
    122     diag_iterator;
    123 
    124   /// \brief Returns an iterator at the beginning of the sequence of suppressed
    125   /// diagnostics.
    126   diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
    127 
    128   /// \brief Returns an iterator at the end of the sequence of suppressed
    129   /// diagnostics.
    130   diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
    131 
    132   /// \brief The template parameter to which a template argument
    133   /// deduction failure refers.
    134   ///
    135   /// Depending on the result of template argument deduction, this
    136   /// template parameter may have different meanings:
    137   ///
    138   ///   TDK_Incomplete: this is the first template parameter whose
    139   ///   corresponding template argument was not deduced.
    140   ///
    141   ///   TDK_Inconsistent: this is the template parameter for which
    142   ///   two different template argument values were deduced.
    143   TemplateParameter Param;
    144 
    145   /// \brief The first template argument to which the template
    146   /// argument deduction failure refers.
    147   ///
    148   /// Depending on the result of the template argument deduction,
    149   /// this template argument may have different meanings:
    150   ///
    151   ///   TDK_Inconsistent: this argument is the first value deduced
    152   ///   for the corresponding template parameter.
    153   ///
    154   ///   TDK_SubstitutionFailure: this argument is the template
    155   ///   argument we were instantiating when we encountered an error.
    156   ///
    157   ///   TDK_DeducedMismatch: this is the parameter type, after substituting
    158   ///   deduced arguments.
    159   ///
    160   ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
    161   ///   of the deduction, directly provided in the source code.
    162   TemplateArgument FirstArg;
    163 
    164   /// \brief The second template argument to which the template
    165   /// argument deduction failure refers.
    166   ///
    167   ///   TDK_Inconsistent: this argument is the second value deduced
    168   ///   for the corresponding template parameter.
    169   ///
    170   ///   TDK_DeducedMismatch: this is the (adjusted) call argument type.
    171   ///
    172   ///   TDK_NonDeducedMismatch: this is the mismatching component of the
    173   ///   'argument' of the deduction, from which we are deducing arguments.
    174   ///
    175   /// FIXME: Finish documenting this.
    176   TemplateArgument SecondArg;
    177 
    178   /// \brief The index of the function argument that caused a deduction
    179   /// failure.
    180   ///
    181   ///   TDK_DeducedMismatch: this is the index of the argument that had a
    182   ///   different argument type from its substituted parameter type.
    183   unsigned CallArgIndex;
    184 
    185   /// \brief Information on packs that we're currently expanding.
    186   ///
    187   /// FIXME: This should be kept internal to SemaTemplateDeduction.
    188   SmallVector<DeducedPack *, 8> PendingDeducedPacks;
    189 };
    190 
    191 } // end namespace sema
    192 
    193 /// A structure used to record information about a failed
    194 /// template argument deduction, for diagnosis.
    195 struct DeductionFailureInfo {
    196   /// A Sema::TemplateDeductionResult.
    197   unsigned Result : 8;
    198 
    199   /// \brief Indicates whether a diagnostic is stored in Diagnostic.
    200   unsigned HasDiagnostic : 1;
    201 
    202   /// \brief Opaque pointer containing additional data about
    203   /// this deduction failure.
    204   void *Data;
    205 
    206   /// \brief A diagnostic indicating why deduction failed.
    207   alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
    208 
    209   /// \brief Retrieve the diagnostic which caused this deduction failure,
    210   /// if any.
    211   PartialDiagnosticAt *getSFINAEDiagnostic();
    212 
    213   /// \brief Retrieve the template parameter this deduction failure
    214   /// refers to, if any.
    215   TemplateParameter getTemplateParameter();
    216 
    217   /// \brief Retrieve the template argument list associated with this
    218   /// deduction failure, if any.
    219   TemplateArgumentList *getTemplateArgumentList();
    220 
    221   /// \brief Return the first template argument this deduction failure
    222   /// refers to, if any.
    223   const TemplateArgument *getFirstArg();
    224 
    225   /// \brief Return the second template argument this deduction failure
    226   /// refers to, if any.
    227   const TemplateArgument *getSecondArg();
    228 
    229   /// \brief Return the index of the call argument that this deduction
    230   /// failure refers to, if any.
    231   llvm::Optional<unsigned> getCallArgIndex();
    232 
    233   /// \brief Free any memory associated with this deduction failure.
    234   void Destroy();
    235 };
    236 
    237 /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
    238 /// which keeps track of template argument deduction failure info, when
    239 /// handling explicit specializations (and instantiations) of templates
    240 /// beyond function overloading.
    241 /// For now, assume that the candidates are non-matching specializations.
    242 /// TODO: In the future, we may need to unify/generalize this with
    243 /// OverloadCandidate.
    244 struct TemplateSpecCandidate {
    245   /// \brief The declaration that was looked up, together with its access.
    246   /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
    247   DeclAccessPair FoundDecl;
    248 
    249   /// Specialization - The actual specialization that this candidate
    250   /// represents. When NULL, this may be a built-in candidate.
    251   Decl *Specialization;
    252 
    253   /// Template argument deduction info
    254   DeductionFailureInfo DeductionFailure;
    255 
    256   void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
    257     FoundDecl = Found;
    258     Specialization = Spec;
    259     DeductionFailure = Info;
    260   }
    261 
    262   /// Diagnose a template argument deduction failure.
    263   void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
    264 };
    265 
    266 /// TemplateSpecCandidateSet - A set of generalized overload candidates,
    267 /// used in template specializations.
    268 /// TODO: In the future, we may need to unify/generalize this with
    269 /// OverloadCandidateSet.
    270 class TemplateSpecCandidateSet {
    271   SmallVector<TemplateSpecCandidate, 16> Candidates;
    272   SourceLocation Loc;
    273   // Stores whether we're taking the address of these candidates. This helps us
    274   // produce better error messages when dealing with the pass_object_size
    275   // attribute on parameters.
    276   bool ForTakingAddress;
    277 
    278   TemplateSpecCandidateSet(
    279       const TemplateSpecCandidateSet &) = delete;
    280   void operator=(const TemplateSpecCandidateSet &) = delete;
    281 
    282   void destroyCandidates();
    283 
    284 public:
    285   TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
    286       : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
    287   ~TemplateSpecCandidateSet() { destroyCandidates(); }
    288 
    289   SourceLocation getLocation() const { return Loc; }
    290 
    291   /// \brief Clear out all of the candidates.
    292   /// TODO: This may be unnecessary.
    293   void clear();
    294 
    295   typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
    296   iterator begin() { return Candidates.begin(); }
    297   iterator end() { return Candidates.end(); }
    298 
    299   size_t size() const { return Candidates.size(); }
    300   bool empty() const { return Candidates.empty(); }
    301 
    302   /// \brief Add a new candidate with NumConversions conversion sequence slots
    303   /// to the overload set.
    304   TemplateSpecCandidate &addCandidate() {
    305     Candidates.emplace_back();
    306     return Candidates.back();
    307   }
    308 
    309   void NoteCandidates(Sema &S, SourceLocation Loc);
    310 
    311   void NoteCandidates(Sema &S, SourceLocation Loc) const {
    312     const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
    313   }
    314 };
    315 
    316 } // end namespace clang
    317 
    318 #endif
    319