summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/clang/Sema/TemplateDeduction.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983e/include/clang/Sema/TemplateDeduction.h')
-rw-r--r--clang-r353983e/include/clang/Sema/TemplateDeduction.h351
1 files changed, 351 insertions, 0 deletions
diff --git a/clang-r353983e/include/clang/Sema/TemplateDeduction.h b/clang-r353983e/include/clang/Sema/TemplateDeduction.h
new file mode 100644
index 00000000..662c4072
--- /dev/null
+++ b/clang-r353983e/include/clang/Sema/TemplateDeduction.h
@@ -0,0 +1,351 @@
+//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides types used with Sema's template argument deduction
+// routines.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
+#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
+
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+#include <cstddef>
+#include <utility>
+
+namespace clang {
+
+class Decl;
+struct DeducedPack;
+class Sema;
+
+namespace sema {
+
+/// Provides information about an attempted template argument
+/// deduction, whose success or failure was described by a
+/// TemplateDeductionResult value.
+class TemplateDeductionInfo {
+ /// The deduced template argument list.
+ TemplateArgumentList *Deduced = nullptr;
+
+ /// The source location at which template argument
+ /// deduction is occurring.
+ SourceLocation Loc;
+
+ /// Have we suppressed an error during deduction?
+ bool HasSFINAEDiagnostic = false;
+
+ /// The template parameter depth for which we're performing deduction.
+ unsigned DeducedDepth;
+
+ /// The number of parameters with explicitly-specified template arguments,
+ /// up to and including the partially-specified pack (if any).
+ unsigned ExplicitArgs = 0;
+
+ /// Warnings (and follow-on notes) that were suppressed due to
+ /// SFINAE while performing template argument deduction.
+ SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;
+
+public:
+ TemplateDeductionInfo(SourceLocation Loc, unsigned DeducedDepth = 0)
+ : Loc(Loc), DeducedDepth(DeducedDepth) {}
+ TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
+ TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
+
+ /// Returns the location at which template argument is
+ /// occurring.
+ SourceLocation getLocation() const {
+ return Loc;
+ }
+
+ /// The depth of template parameters for which deduction is being
+ /// performed.
+ unsigned getDeducedDepth() const {
+ return DeducedDepth;
+ }
+
+ /// Get the number of explicitly-specified arguments.
+ unsigned getNumExplicitArgs() const {
+ return ExplicitArgs;
+ }
+
+ /// Take ownership of the deduced template argument list.
+ TemplateArgumentList *take() {
+ TemplateArgumentList *Result = Deduced;
+ Deduced = nullptr;
+ return Result;
+ }
+
+ /// Take ownership of the SFINAE diagnostic.
+ void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
+ assert(HasSFINAEDiagnostic);
+ PD.first = SuppressedDiagnostics.front().first;
+ PD.second.swap(SuppressedDiagnostics.front().second);
+ clearSFINAEDiagnostic();
+ }
+
+ /// Discard any SFINAE diagnostics.
+ void clearSFINAEDiagnostic() {
+ SuppressedDiagnostics.clear();
+ HasSFINAEDiagnostic = false;
+ }
+
+ /// Peek at the SFINAE diagnostic.
+ const PartialDiagnosticAt &peekSFINAEDiagnostic() const {
+ assert(HasSFINAEDiagnostic);
+ return SuppressedDiagnostics.front();
+ }
+
+ /// Provide an initial template argument list that contains the
+ /// explicitly-specified arguments.
+ void setExplicitArgs(TemplateArgumentList *NewDeduced) {
+ Deduced = NewDeduced;
+ ExplicitArgs = Deduced->size();
+ }
+
+ /// Provide a new template argument list that contains the
+ /// results of template argument deduction.
+ void reset(TemplateArgumentList *NewDeduced) {
+ Deduced = NewDeduced;
+ }
+
+ /// Is a SFINAE diagnostic available?
+ bool hasSFINAEDiagnostic() const {
+ return HasSFINAEDiagnostic;
+ }
+
+ /// Set the diagnostic which caused the SFINAE failure.
+ void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
+ // Only collect the first diagnostic.
+ if (HasSFINAEDiagnostic)
+ return;
+ SuppressedDiagnostics.clear();
+ SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
+ HasSFINAEDiagnostic = true;
+ }
+
+ /// Add a new diagnostic to the set of diagnostics
+ void addSuppressedDiagnostic(SourceLocation Loc,
+ PartialDiagnostic PD) {
+ if (HasSFINAEDiagnostic)
+ return;
+ SuppressedDiagnostics.emplace_back(Loc, std::move(PD));
+ }
+
+ /// Iterator over the set of suppressed diagnostics.
+ using diag_iterator = SmallVectorImpl<PartialDiagnosticAt>::const_iterator;
+
+ /// Returns an iterator at the beginning of the sequence of suppressed
+ /// diagnostics.
+ diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }
+
+ /// Returns an iterator at the end of the sequence of suppressed
+ /// diagnostics.
+ diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }
+
+ /// The template parameter to which a template argument
+ /// deduction failure refers.
+ ///
+ /// Depending on the result of template argument deduction, this
+ /// template parameter may have different meanings:
+ ///
+ /// TDK_Incomplete: this is the first template parameter whose
+ /// corresponding template argument was not deduced.
+ ///
+ /// TDK_IncompletePack: this is the expanded parameter pack for
+ /// which we deduced too few arguments.
+ ///
+ /// TDK_Inconsistent: this is the template parameter for which
+ /// two different template argument values were deduced.
+ TemplateParameter Param;
+
+ /// The first template argument to which the template
+ /// argument deduction failure refers.
+ ///
+ /// Depending on the result of the template argument deduction,
+ /// this template argument may have different meanings:
+ ///
+ /// TDK_IncompletePack: this is the number of arguments we deduced
+ /// for the pack.
+ ///
+ /// TDK_Inconsistent: this argument is the first value deduced
+ /// for the corresponding template parameter.
+ ///
+ /// TDK_SubstitutionFailure: this argument is the template
+ /// argument we were instantiating when we encountered an error.
+ ///
+ /// TDK_DeducedMismatch: this is the parameter type, after substituting
+ /// deduced arguments.
+ ///
+ /// TDK_NonDeducedMismatch: this is the component of the 'parameter'
+ /// of the deduction, directly provided in the source code.
+ TemplateArgument FirstArg;
+
+ /// The second template argument to which the template
+ /// argument deduction failure refers.
+ ///
+ /// TDK_Inconsistent: this argument is the second value deduced
+ /// for the corresponding template parameter.
+ ///
+ /// TDK_DeducedMismatch: this is the (adjusted) call argument type.
+ ///
+ /// TDK_NonDeducedMismatch: this is the mismatching component of the
+ /// 'argument' of the deduction, from which we are deducing arguments.
+ ///
+ /// FIXME: Finish documenting this.
+ TemplateArgument SecondArg;
+
+ /// The index of the function argument that caused a deduction
+ /// failure.
+ ///
+ /// TDK_DeducedMismatch: this is the index of the argument that had a
+ /// different argument type from its substituted parameter type.
+ unsigned CallArgIndex = 0;
+
+ /// Information on packs that we're currently expanding.
+ ///
+ /// FIXME: This should be kept internal to SemaTemplateDeduction.
+ SmallVector<DeducedPack *, 8> PendingDeducedPacks;
+};
+
+} // namespace sema
+
+/// A structure used to record information about a failed
+/// template argument deduction, for diagnosis.
+struct DeductionFailureInfo {
+ /// A Sema::TemplateDeductionResult.
+ unsigned Result : 8;
+
+ /// Indicates whether a diagnostic is stored in Diagnostic.
+ unsigned HasDiagnostic : 1;
+
+ /// Opaque pointer containing additional data about
+ /// this deduction failure.
+ void *Data;
+
+ /// A diagnostic indicating why deduction failed.
+ alignas(PartialDiagnosticAt) char Diagnostic[sizeof(PartialDiagnosticAt)];
+
+ /// Retrieve the diagnostic which caused this deduction failure,
+ /// if any.
+ PartialDiagnosticAt *getSFINAEDiagnostic();
+
+ /// Retrieve the template parameter this deduction failure
+ /// refers to, if any.
+ TemplateParameter getTemplateParameter();
+
+ /// Retrieve the template argument list associated with this
+ /// deduction failure, if any.
+ TemplateArgumentList *getTemplateArgumentList();
+
+ /// Return the first template argument this deduction failure
+ /// refers to, if any.
+ const TemplateArgument *getFirstArg();
+
+ /// Return the second template argument this deduction failure
+ /// refers to, if any.
+ const TemplateArgument *getSecondArg();
+
+ /// Return the index of the call argument that this deduction
+ /// failure refers to, if any.
+ llvm::Optional<unsigned> getCallArgIndex();
+
+ /// Free any memory associated with this deduction failure.
+ void Destroy();
+};
+
+/// TemplateSpecCandidate - This is a generalization of OverloadCandidate
+/// which keeps track of template argument deduction failure info, when
+/// handling explicit specializations (and instantiations) of templates
+/// beyond function overloading.
+/// For now, assume that the candidates are non-matching specializations.
+/// TODO: In the future, we may need to unify/generalize this with
+/// OverloadCandidate.
+struct TemplateSpecCandidate {
+ /// The declaration that was looked up, together with its access.
+ /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
+ DeclAccessPair FoundDecl;
+
+ /// Specialization - The actual specialization that this candidate
+ /// represents. When NULL, this may be a built-in candidate.
+ Decl *Specialization;
+
+ /// Template argument deduction info
+ DeductionFailureInfo DeductionFailure;
+
+ void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
+ FoundDecl = Found;
+ Specialization = Spec;
+ DeductionFailure = Info;
+ }
+
+ /// Diagnose a template argument deduction failure.
+ void NoteDeductionFailure(Sema &S, bool ForTakingAddress);
+};
+
+/// TemplateSpecCandidateSet - A set of generalized overload candidates,
+/// used in template specializations.
+/// TODO: In the future, we may need to unify/generalize this with
+/// OverloadCandidateSet.
+class TemplateSpecCandidateSet {
+ SmallVector<TemplateSpecCandidate, 16> Candidates;
+ SourceLocation Loc;
+
+ // Stores whether we're taking the address of these candidates. This helps us
+ // produce better error messages when dealing with the pass_object_size
+ // attribute on parameters.
+ bool ForTakingAddress;
+
+ void destroyCandidates();
+
+public:
+ TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false)
+ : Loc(Loc), ForTakingAddress(ForTakingAddress) {}
+ TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
+ TemplateSpecCandidateSet &
+ operator=(const TemplateSpecCandidateSet &) = delete;
+ ~TemplateSpecCandidateSet() { destroyCandidates(); }
+
+ SourceLocation getLocation() const { return Loc; }
+
+ /// Clear out all of the candidates.
+ /// TODO: This may be unnecessary.
+ void clear();
+
+ using iterator = SmallVector<TemplateSpecCandidate, 16>::iterator;
+
+ iterator begin() { return Candidates.begin(); }
+ iterator end() { return Candidates.end(); }
+
+ size_t size() const { return Candidates.size(); }
+ bool empty() const { return Candidates.empty(); }
+
+ /// Add a new candidate with NumConversions conversion sequence slots
+ /// to the overload set.
+ TemplateSpecCandidate &addCandidate() {
+ Candidates.emplace_back();
+ return Candidates.back();
+ }
+
+ void NoteCandidates(Sema &S, SourceLocation Loc);
+
+ void NoteCandidates(Sema &S, SourceLocation Loc) const {
+ const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
+ }
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H