Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file provides types used with Sema's template argument deduction
  10. // routines.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
  15. #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
  16.  
  17. #include "clang/Sema/Ownership.h"
  18. #include "clang/Sema/SemaConcept.h"
  19. #include "clang/AST/ASTConcept.h"
  20. #include "clang/AST/DeclAccessPair.h"
  21. #include "clang/AST/DeclTemplate.h"
  22. #include "clang/AST/TemplateBase.h"
  23. #include "clang/Basic/PartialDiagnostic.h"
  24. #include "clang/Basic/SourceLocation.h"
  25. #include "llvm/ADT/SmallVector.h"
  26. #include <cassert>
  27. #include <cstddef>
  28. #include <optional>
  29. #include <utility>
  30.  
  31. namespace clang {
  32.  
  33. class Decl;
  34. struct DeducedPack;
  35. class Sema;
  36.  
  37. namespace sema {
  38.  
  39. /// Provides information about an attempted template argument
  40. /// deduction, whose success or failure was described by a
  41. /// TemplateDeductionResult value.
  42. class TemplateDeductionInfo {
  43.   /// The deduced template argument list.
  44.   TemplateArgumentList *DeducedSugared = nullptr, *DeducedCanonical = nullptr;
  45.  
  46.   /// The source location at which template argument
  47.   /// deduction is occurring.
  48.   SourceLocation Loc;
  49.  
  50.   /// Have we suppressed an error during deduction?
  51.   bool HasSFINAEDiagnostic = false;
  52.  
  53.   /// The template parameter depth for which we're performing deduction.
  54.   unsigned DeducedDepth;
  55.  
  56.   /// The number of parameters with explicitly-specified template arguments,
  57.   /// up to and including the partially-specified pack (if any).
  58.   unsigned ExplicitArgs = 0;
  59.  
  60.   /// Warnings (and follow-on notes) that were suppressed due to
  61.   /// SFINAE while performing template argument deduction.
  62.   SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
  63.  
  64. public:
  65.   TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
  66.       : Loc(Loc), DeducedDepth(DeducedDepth) {}
  67.   TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
  68.   TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
  69.  
  70.   enum ForBaseTag { ForBase };
  71.   /// Create temporary template deduction info for speculatively deducing
  72.   /// against a base class of an argument's type.
  73.   TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info)
  74.       : DeducedSugared(Info.DeducedSugared), Loc(Info.Loc),
  75.         DeducedDepth(Info.DeducedDepth), ExplicitArgs(Info.ExplicitArgs) {}
  76.  
  77.   /// Returns the location at which template argument is
  78.   /// occurring.
  79.   SourceLocation getLocation() const {
  80.     return Loc;
  81.   }
  82.  
  83.   /// The depth of template parameters for which deduction is being
  84.   /// performed.
  85.   unsigned getDeducedDepth() const {
  86.     return DeducedDepth;
  87.   }
  88.  
  89.   /// Get the number of explicitly-specified arguments.
  90.   unsigned getNumExplicitArgs() const {
  91.     return ExplicitArgs;
  92.   }
  93.  
  94.   /// Take ownership of the deduced template argument lists.
  95.   TemplateArgumentList *takeSugared() {
  96.     TemplateArgumentList *Result = DeducedSugared;
  97.     DeducedSugared = nullptr;
  98.     return Result;
  99.   }
  100.   TemplateArgumentList *takeCanonical() {
  101.     TemplateArgumentList *Result = DeducedCanonical;
  102.     DeducedCanonical = nullptr;
  103.     return Result;
  104.   }
  105.  
  106.   /// Take ownership of the SFINAE diagnostic.
  107.   void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
  108.     assert(HasSFINAEDiagnostic);
  109.     PD.first = SuppressedDiagnostics.front().first;
  110.     PD.second.swap(SuppressedDiagnostics.front().second);
  111.     clearSFINAEDiagnostic();
  112.   }
  113.  
  114.   /// Discard any SFINAE diagnostics.
  115.   void clearSFINAEDiagnostic() {
  116.     SuppressedDiagnostics.clear();
  117.     HasSFINAEDiagnostic = false;
  118.   }
  119.  
  120.   /// Peek at the SFINAE diagnostic.
  121.   const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
  122.     assert(HasSFINAEDiagnostic);
  123.     return SuppressedDiagnostics.front();
  124.   }
  125.  
  126.   /// Provide an initial template argument list that contains the
  127.   /// explicitly-specified arguments.
  128.   void setExplicitArgs(TemplateArgumentList *NewDeducedSugared,
  129.                        TemplateArgumentList *NewDeducedCanonical) {
  130.     assert(NewDeducedSugared->size() == NewDeducedCanonical->size());
  131.     DeducedSugared = NewDeducedSugared;
  132.     DeducedCanonical = NewDeducedCanonical;
  133.     ExplicitArgs = DeducedSugared->size();
  134.   }
  135.  
  136.   /// Provide a new template argument list that contains the
  137.   /// results of template argument deduction.
  138.   void reset(TemplateArgumentList *NewDeducedSugared,
  139.              TemplateArgumentList *NewDeducedCanonical) {
  140.     DeducedSugared = NewDeducedSugared;
  141.     DeducedCanonical = NewDeducedCanonical;
  142.   }
  143.  
  144.   /// Is a SFINAE diagnostic available?
  145.   bool hasSFINAEDiagnostic() const {
  146.     return HasSFINAEDiagnostic;
  147.   }
  148.  
  149.   /// Set the diagnostic which caused the SFINAE failure.
  150.   void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
  151.     // Only collect the first diagnostic.
  152.     if (HasSFINAEDiagnostic)
  153.       return;
  154.     SuppressedDiagnostics.clear();
  155.     SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
  156.     HasSFINAEDiagnostic = true;
  157.   }
  158.  
  159.   /// Add a new diagnostic to the set of diagnostics
  160.   void addSuppressedDiagnostic(SourceLocation Loc,
  161.                                PartialDiagnostic PD) {
  162.     if (HasSFINAEDiagnostic)
  163.       return;
  164.     SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
  165.   }
  166.  
  167.   /// Iterator over the set of suppressed diagnostics.
  168.   using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator;
  169.  
  170.   /// Returns an iterator at the beginning of the sequence of suppressed
  171.   /// diagnostics.
  172.   diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
  173.  
  174.   /// Returns an iterator at the end of the sequence of suppressed
  175.   /// diagnostics.
  176.   diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
  177.  
  178.   /// The template parameter to which a template argument
  179.   /// deduction failure refers.
  180.   ///
  181.   /// Depending on the result of template argument deduction, this
  182.   /// template parameter may have different meanings:
  183.   ///
  184.   ///   TDK_Incomplete: this is the first template parameter whose
  185.   ///   corresponding template argument was not deduced.
  186.   ///
  187.   ///   TDK_IncompletePack: this is the expanded parameter pack for
  188.   ///   which we deduced too few arguments.
  189.   ///
  190.   ///   TDK_Inconsistent: this is the template parameter for which
  191.   ///   two different template argument values were deduced.
  192.   TemplateParameter Param;
  193.  
  194.   /// The first template argument to which the template
  195.   /// argument deduction failure refers.
  196.   ///
  197.   /// Depending on the result of the template argument deduction,
  198.   /// this template argument may have different meanings:
  199.   ///
  200.   ///   TDK_IncompletePack: this is the number of arguments we deduced
  201.   ///   for the pack.
  202.   ///
  203.   ///   TDK_Inconsistent: this argument is the first value deduced
  204.   ///   for the corresponding template parameter.
  205.   ///
  206.   ///   TDK_SubstitutionFailure: this argument is the template
  207.   ///   argument we were instantiating when we encountered an error.
  208.   ///
  209.   ///   TDK_DeducedMismatch: this is the parameter type, after substituting
  210.   ///   deduced arguments.
  211.   ///
  212.   ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
  213.   ///   of the deduction, directly provided in the source code.
  214.   TemplateArgument FirstArg;
  215.  
  216.   /// The second template argument to which the template
  217.   /// argument deduction failure refers.
  218.   ///
  219.   ///   TDK_Inconsistent: this argument is the second value deduced
  220.   ///   for the corresponding template parameter.
  221.   ///
  222.   ///   TDK_DeducedMismatch: this is the (adjusted) call argument type.
  223.   ///
  224.   ///   TDK_NonDeducedMismatch: this is the mismatching component of the
  225.   ///   'argument' of the deduction, from which we are deducing arguments.
  226.   ///
  227.   /// FIXME: Finish documenting this.
  228.   TemplateArgument SecondArg;
  229.  
  230.   /// The index of the function argument that caused a deduction
  231.   /// failure.
  232.   ///
  233.   ///   TDK_DeducedMismatch: this is the index of the argument that had a
  234.   ///   different argument type from its substituted parameter type.
  235.   unsigned CallArgIndex = 0;
  236.  
  237.   /// Information on packs that we're currently expanding.
  238.   ///
  239.   /// FIXME: This should be kept internal to SemaTemplateDeduction.
  240.   SmallVector<DeducedPack *, 8> PendingDeducedPacks;
  241.  
  242.   /// \brief The constraint satisfaction details resulting from the associated
  243.   /// constraints satisfaction tests.
  244.   ConstraintSatisfaction AssociatedConstraintsSatisfaction;
  245. };
  246.  
  247. } // namespace sema
  248.  
  249. /// A structure used to record information about a failed
  250. /// template argument deduction, for diagnosis.
  251. struct DeductionFailureInfo {
  252.   /// A Sema::TemplateDeductionResult.
  253.   unsigned Result : 8;
  254.  
  255.   /// Indicates whether a diagnostic is stored in Diagnostic.
  256.   unsigned HasDiagnostic : 1;
  257.  
  258.   /// Opaque pointer containing additional data about
  259.   /// this deduction failure.
  260.   void *Data;
  261.  
  262.   /// A diagnostic indicating why deduction failed.
  263.   alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
  264.  
  265.   /// Retrieve the diagnostic which caused this deduction failure,
  266.   /// if any.
  267.   PartialDiagnosticAt *getSFINAEDiagnostic();
  268.  
  269.   /// Retrieve the template parameter this deduction failure
  270.   /// refers to, if any.
  271.   TemplateParameter getTemplateParameter();
  272.  
  273.   /// Retrieve the template argument list associated with this
  274.   /// deduction failure, if any.
  275.   TemplateArgumentList *getTemplateArgumentList();
  276.  
  277.   /// Return the first template argument this deduction failure
  278.   /// refers to, if any.
  279.   const TemplateArgument *getFirstArg();
  280.  
  281.   /// Return the second template argument this deduction failure
  282.   /// refers to, if any.
  283.   const TemplateArgument *getSecondArg();
  284.  
  285.   /// Return the index of the call argument that this deduction
  286.   /// failure refers to, if any.
  287.   std::optional<unsigned> getCallArgIndex();
  288.  
  289.   /// Free any memory associated with this deduction failure.
  290.   void Destroy();
  291. };
  292.  
  293. /// TemplateSpecCandidate - This is a generalization of OverloadCandidate
  294. /// which keeps track of template argument deduction failure info, when
  295. /// handling explicit specializations (and instantiations) of templates
  296. /// beyond function overloading.
  297. /// For now, assume that the candidates are non-matching specializations.
  298. /// TODO: In the future, we may need to unify/generalize this with
  299. /// OverloadCandidate.
  300. struct TemplateSpecCandidate {
  301.   /// The declaration that was looked up, together with its access.
  302.   /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
  303.   DeclAccessPair FoundDecl;
  304.  
  305.   /// Specialization - The actual specialization that this candidate
  306.   /// represents. When NULL, this may be a built-in candidate.
  307.   Decl *Specialization;
  308.  
  309.   /// Template argument deduction info
  310.   DeductionFailureInfo DeductionFailure;
  311.  
  312.   void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
  313.     FoundDecl = Found;
  314.     Specialization = Spec;
  315.     DeductionFailure = Info;
  316.   }
  317.  
  318.   /// Diagnose a template argument deduction failure.
  319.   void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
  320. };
  321.  
  322. /// TemplateSpecCandidateSet - A set of generalized overload candidates,
  323. /// used in template specializations.
  324. /// TODO: In the future, we may need to unify/generalize this with
  325. /// OverloadCandidateSet.
  326. class TemplateSpecCandidateSet {
  327.   SmallVector<TemplateSpecCandidate, 16> Candidates;
  328.   SourceLocation Loc;
  329.  
  330.   // Stores whether we're taking the address of these candidates. This helps us
  331.   // produce better error messages when dealing with the pass_object_size
  332.   // attribute on parameters.
  333.   bool ForTakingAddress;
  334.  
  335.   void destroyCandidates();
  336.  
  337. public:
  338.   TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
  339.       : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
  340.   TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
  341.   TemplateSpecCandidateSet &
  342.   operator=(const TemplateSpecCandidateSet &) = delete;
  343.   ~TemplateSpecCandidateSet() { destroyCandidates(); }
  344.  
  345.   SourceLocation getLocation() const { return Loc; }
  346.  
  347.   /// Clear out all of the candidates.
  348.   /// TODO: This may be unnecessary.
  349.   void clear();
  350.  
  351.   using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator;
  352.  
  353.   iterator begin() { return Candidates.begin(); }
  354.   iterator end() { return Candidates.end(); }
  355.  
  356.   size_t size() const { return Candidates.size(); }
  357.   bool empty() const { return Candidates.empty(); }
  358.  
  359.   /// Add a new candidate with NumConversions conversion sequence slots
  360.   /// to the overload set.
  361.   TemplateSpecCandidate &addCandidate() {
  362.     Candidates.emplace_back();
  363.     return Candidates.back();
  364.   }
  365.  
  366.   void NoteCandidates(Sema &S, SourceLocation Loc);
  367.  
  368.   void NoteCandidates(Sema &S, SourceLocation Loc) const {
  369.     const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
  370.   }
  371. };
  372.  
  373. } // namespace clang
  374.  
  375. #endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
  376.