aboutsummaryrefslogtreecommitdiff
path: root/clang/include/clang/Sema/Overload.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Sema/Overload.h')
-rw-r--r--clang/include/clang/Sema/Overload.h249
1 files changed, 178 insertions, 71 deletions
diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h
index eb32b8f..28ae40b 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -1,4 +1,4 @@
-//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===//
+//===- Overload.h - C++ Overloading -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,32 +16,51 @@
#define LLVM_CLANG_SEMA_OVERLOAD_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/TemplateDeduction.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
namespace clang {
- class ASTContext;
- class CXXConstructorDecl;
- class CXXConversionDecl;
- class FunctionDecl;
- class Sema;
+
+class APValue;
+class ASTContext;
+class Sema;
/// OverloadingResult - Capture the result of performing overload
/// resolution.
enum OverloadingResult {
- OR_Success, ///< Overload resolution succeeded.
- OR_No_Viable_Function, ///< No viable function found.
- OR_Ambiguous, ///< Ambiguous candidates found.
- OR_Deleted ///< Succeeded, but refers to a deleted function.
+ /// Overload resolution succeeded.
+ OR_Success,
+
+ /// No viable function found.
+ OR_No_Viable_Function,
+
+ /// Ambiguous candidates found.
+ OR_Ambiguous,
+
+ /// Succeeded, but refers to a deleted function.
+ OR_Deleted
};
enum OverloadCandidateDisplayKind {
@@ -58,36 +77,92 @@ namespace clang {
/// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
/// better conversion kinds have smaller values.
enum ImplicitConversionKind {
- ICK_Identity = 0, ///< Identity conversion (no conversion)
- ICK_Lvalue_To_Rvalue, ///< Lvalue-to-rvalue conversion (C++ 4.1)
- ICK_Array_To_Pointer, ///< Array-to-pointer conversion (C++ 4.2)
- ICK_Function_To_Pointer, ///< Function-to-pointer (C++ 4.3)
- ICK_Function_Conversion, ///< Function pointer conversion (C++17 4.13)
- ICK_Qualification, ///< Qualification conversions (C++ 4.4)
- ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5)
- ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6)
- ICK_Complex_Promotion, ///< Complex promotions (Clang extension)
- ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7)
- ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8)
- ICK_Complex_Conversion, ///< Complex conversions (C99 6.3.1.6)
- ICK_Floating_Integral, ///< Floating-integral conversions (C++ 4.9)
- ICK_Pointer_Conversion, ///< Pointer conversions (C++ 4.10)
- ICK_Pointer_Member, ///< Pointer-to-member conversions (C++ 4.11)
- ICK_Boolean_Conversion, ///< Boolean conversions (C++ 4.12)
- ICK_Compatible_Conversion, ///< Conversions between compatible types in C99
- ICK_Derived_To_Base, ///< Derived-to-base (C++ [over.best.ics])
- ICK_Vector_Conversion, ///< Vector conversions
- ICK_Vector_Splat, ///< A vector splat from an arithmetic type
- ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7)
- ICK_Block_Pointer_Conversion, ///< Block Pointer conversions
- ICK_TransparentUnionConversion, ///< Transparent Union Conversions
- ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion
- ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10)
- ICK_Zero_Queue_Conversion, ///< Zero constant to queue
- ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++
- ICK_Incompatible_Pointer_Conversion, ///< C-only conversion between pointers
- /// with incompatible types
- ICK_Num_Conversion_Kinds, ///< The number of conversion kinds
+ /// Identity conversion (no conversion)
+ ICK_Identity = 0,
+
+ /// Lvalue-to-rvalue conversion (C++ 4.1)
+ ICK_Lvalue_To_Rvalue,
+
+ /// Array-to-pointer conversion (C++ 4.2)
+ ICK_Array_To_Pointer,
+
+ /// Function-to-pointer (C++ 4.3)
+ ICK_Function_To_Pointer,
+
+ /// Function pointer conversion (C++17 4.13)
+ ICK_Function_Conversion,
+
+ /// Qualification conversions (C++ 4.4)
+ ICK_Qualification,
+
+ /// Integral promotions (C++ 4.5)
+ ICK_Integral_Promotion,
+
+ /// Floating point promotions (C++ 4.6)
+ ICK_Floating_Promotion,
+
+ /// Complex promotions (Clang extension)
+ ICK_Complex_Promotion,
+
+ /// Integral conversions (C++ 4.7)
+ ICK_Integral_Conversion,
+
+ /// Floating point conversions (C++ 4.8)
+ ICK_Floating_Conversion,
+
+ /// Complex conversions (C99 6.3.1.6)
+ ICK_Complex_Conversion,
+
+ /// Floating-integral conversions (C++ 4.9)
+ ICK_Floating_Integral,
+
+ /// Pointer conversions (C++ 4.10)
+ ICK_Pointer_Conversion,
+
+ /// Pointer-to-member conversions (C++ 4.11)
+ ICK_Pointer_Member,
+
+ /// Boolean conversions (C++ 4.12)
+ ICK_Boolean_Conversion,
+
+ /// Conversions between compatible types in C99
+ ICK_Compatible_Conversion,
+
+ /// Derived-to-base (C++ [over.best.ics])
+ ICK_Derived_To_Base,
+
+ /// Vector conversions
+ ICK_Vector_Conversion,
+
+ /// A vector splat from an arithmetic type
+ ICK_Vector_Splat,
+
+ /// Complex-real conversions (C99 6.3.1.7)
+ ICK_Complex_Real,
+
+ /// Block Pointer conversions
+ ICK_Block_Pointer_Conversion,
+
+ /// Transparent Union Conversions
+ ICK_TransparentUnionConversion,
+
+ /// Objective-C ARC writeback conversion
+ ICK_Writeback_Conversion,
+
+ /// Zero constant to event (OpenCL1.2 6.12.10)
+ ICK_Zero_Event_Conversion,
+
+ /// Zero constant to queue
+ ICK_Zero_Queue_Conversion,
+
+ /// Conversions allowed in C, but not C++
+ ICK_C_Only_Conversion,
+
+ /// C-only conversion between pointers with incompatible types
+ ICK_Incompatible_Pointer_Conversion,
+
+ /// The number of conversion kinds
+ ICK_Num_Conversion_Kinds,
};
/// ImplicitConversionRank - The rank of an implicit conversion
@@ -95,16 +170,30 @@ namespace clang {
/// 13.3.3.1.1) and are listed such that better conversion ranks
/// have smaller values.
enum ImplicitConversionRank {
- ICR_Exact_Match = 0, ///< Exact Match
- ICR_Promotion, ///< Promotion
- ICR_Conversion, ///< Conversion
- ICR_OCL_Scalar_Widening, ///< OpenCL Scalar Widening
- ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion
- ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion
- ICR_C_Conversion, ///< Conversion only allowed in the C standard.
- /// (e.g. void* to char*)
- ICR_C_Conversion_Extension ///< Conversion not allowed by the C standard,
- /// but that we accept as an extension anyway.
+ /// Exact Match
+ ICR_Exact_Match = 0,
+
+ /// Promotion
+ ICR_Promotion,
+
+ /// Conversion
+ ICR_Conversion,
+
+ /// OpenCL Scalar Widening
+ ICR_OCL_Scalar_Widening,
+
+ /// Complex <-> Real conversion
+ ICR_Complex_Real_Conversion,
+
+ /// ObjC ARC writeback conversion
+ ICR_Writeback_Conversion,
+
+ /// Conversion only allowed in the C standard (e.g. void* to char*).
+ ICR_C_Conversion,
+
+ /// Conversion not allowed by the C standard, but that we accept as an
+ /// extension anyway.
+ ICR_C_Conversion_Extension
};
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
@@ -213,10 +302,12 @@ namespace clang {
DeclAccessPair FoundCopyConstructor;
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
+
void setToType(unsigned Idx, QualType T) {
assert(Idx < 3 && "To type index is out of range");
ToTypePtrs[Idx] = T.getAsOpaquePtr();
}
+
void setAllToTypes(QualType T) {
ToTypePtrs[0] = T.getAsOpaquePtr();
ToTypePtrs[1] = ToTypePtrs[0];
@@ -226,6 +317,7 @@ namespace clang {
QualType getFromType() const {
return QualType::getFromOpaquePtr(FromTypePtr);
}
+
QualType getToType(unsigned Idx) const {
assert(Idx < 3 && "To type index is out of range");
return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
@@ -294,7 +386,8 @@ namespace clang {
/// Represents an ambiguous user-defined conversion sequence.
struct AmbiguousConversionSequence {
- typedef SmallVector<std::pair<NamedDecl*, FunctionDecl*>, 4> ConversionSet;
+ using ConversionSet =
+ SmallVector<std::pair<NamedDecl *, FunctionDecl *>, 4>;
void *FromTypePtr;
void *ToTypePtr;
@@ -303,9 +396,11 @@ namespace clang {
QualType getFromType() const {
return QualType::getFromOpaquePtr(FromTypePtr);
}
+
QualType getToType() const {
return QualType::getFromOpaquePtr(ToTypePtr);
}
+
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
@@ -321,11 +416,13 @@ namespace clang {
conversions().push_back(std::make_pair(Found, D));
}
- typedef ConversionSet::iterator iterator;
+ using iterator = ConversionSet::iterator;
+
iterator begin() { return conversions().begin(); }
iterator end() { return conversions().end(); }
- typedef ConversionSet::const_iterator const_iterator;
+ using const_iterator = ConversionSet::const_iterator;
+
const_iterator begin() const { return conversions().begin(); }
const_iterator end() const { return conversions().end(); }
@@ -362,6 +459,7 @@ namespace clang {
init(K, From->getType(), To);
FromExpr = From;
}
+
void init(FailureKind K, QualType From, QualType To) {
Kind = K;
FromExpr = nullptr;
@@ -376,6 +474,7 @@ namespace clang {
FromExpr = E;
setFromType(E->getType());
}
+
void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
};
@@ -442,13 +541,10 @@ namespace clang {
: ConversionKind(Uninitialized), StdInitializerListElement(false) {
Standard.setAsIdentityConversion();
}
- ~ImplicitConversionSequence() {
- destruct();
- }
+
ImplicitConversionSequence(const ImplicitConversionSequence &Other)
- : ConversionKind(Other.ConversionKind),
- StdInitializerListElement(Other.StdInitializerListElement)
- {
+ : ConversionKind(Other.ConversionKind),
+ StdInitializerListElement(Other.StdInitializerListElement) {
switch (ConversionKind) {
case Uninitialized: break;
case StandardConversion: Standard = Other.Standard; break;
@@ -460,12 +556,16 @@ namespace clang {
}
ImplicitConversionSequence &
- operator=(const ImplicitConversionSequence &Other) {
+ operator=(const ImplicitConversionSequence &Other) {
destruct();
new (this) ImplicitConversionSequence(Other);
return *this;
}
+ ~ImplicitConversionSequence() {
+ destruct();
+ }
+
Kind getKind() const {
assert(isInitialized() && "querying uninitialized conversion");
return Kind(ConversionKind);
@@ -526,6 +626,7 @@ namespace clang {
void setStandard() { setKind(StandardConversion); }
void setEllipsis() { setKind(EllipsisConversion); }
void setUserDefined() { setKind(UserDefinedConversion); }
+
void setAmbiguous() {
if (ConversionKind == AmbiguousConversion) return;
ConversionKind = AmbiguousConversion;
@@ -621,8 +722,8 @@ namespace clang {
/// A list of implicit conversion sequences for the arguments of an
/// OverloadCandidate.
- typedef llvm::MutableArrayRef<ImplicitConversionSequence>
- ConversionSequenceList;
+ using ConversionSequenceList =
+ llvm::MutableArrayRef<ImplicitConversionSequence>;
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
struct OverloadCandidate {
@@ -730,16 +831,19 @@ namespace clang {
enum CandidateSetKind {
/// Normal lookup.
CSK_Normal,
+
/// C++ [over.match.oper]:
/// Lookup of operator function candidates in a call using operator
/// syntax. Candidates that have no parameters of class type will be
/// skipped unless there is a parameter of (reference to) enum type and
/// the corresponding argument is of the same enum type.
CSK_Operator,
+
/// C++ [over.match.copy]:
/// Copy-initialization of an object of class type by user-defined
/// conversion.
CSK_InitByUserDefinedConversion,
+
/// C++ [over.match.ctor], [over.match.list]
/// Initialization of an object of class type by constructor,
/// using either a parenthesized or braced list of arguments.
@@ -759,7 +863,7 @@ namespace clang {
constexpr static unsigned NumInlineBytes =
24 * sizeof(ImplicitConversionSequence);
- unsigned NumInlineBytesUsed;
+ unsigned NumInlineBytesUsed = 0;
llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
/// If we have space, allocates from inline storage. Otherwise, allocates
@@ -788,14 +892,13 @@ namespace clang {
return reinterpret_cast<T *>(FreeSpaceStart);
}
- OverloadCandidateSet(const OverloadCandidateSet &) = delete;
- void operator=(const OverloadCandidateSet &) = delete;
-
void destroyCandidates();
public:
OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
- : Loc(Loc), Kind(CSK), NumInlineBytesUsed(0) {}
+ : Loc(Loc), Kind(CSK) {}
+ OverloadCandidateSet(const OverloadCandidateSet &) = delete;
+ OverloadCandidateSet &operator=(const OverloadCandidateSet &) = delete;
~OverloadCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; }
@@ -810,7 +913,8 @@ namespace clang {
/// \brief Clear out all of the candidates.
void clear(CandidateSetKind CSK);
- typedef SmallVectorImpl<OverloadCandidate>::iterator iterator;
+ using iterator = SmallVectorImpl<OverloadCandidate>::iterator;
+
iterator begin() { return Candidates.begin(); }
iterator end() { return Candidates.end(); }
@@ -869,8 +973,10 @@ namespace clang {
DeclAccessPair FoundDecl;
CXXConstructorDecl *Constructor;
FunctionTemplateDecl *ConstructorTmpl;
+
explicit operator bool() const { return Constructor; }
};
+
// FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload
// that takes one of these.
inline ConstructorInfo getConstructorInfo(NamedDecl *ND) {
@@ -888,6 +994,7 @@ namespace clang {
Info.Constructor = dyn_cast<CXXConstructorDecl>(D);
return Info;
}
-} // end namespace clang
+
+} // namespace clang
#endif // LLVM_CLANG_SEMA_OVERLOAD_H