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