forked from OSchip/llvm-project
Preliminary support for function overloading
llvm-svn: 57909
This commit is contained in:
parent
0747e7e025
commit
5251f1b283
|
@ -1178,7 +1178,8 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
|
|||
else {
|
||||
DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
|
||||
elementName = DR->getDecl()->getName();
|
||||
elementTypeAsString = DR->getDecl()->getType().getAsString();
|
||||
elementTypeAsString
|
||||
= cast<ValueDecl>(DR->getDecl())->getType().getAsString();
|
||||
}
|
||||
|
||||
// struct __objcFastEnumerationState enumState = { 0 };
|
||||
|
|
|
@ -137,6 +137,7 @@ public:
|
|||
QualType FloatTy, DoubleTy, LongDoubleTy;
|
||||
QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
|
||||
QualType VoidPtrTy;
|
||||
QualType OverloadTy;
|
||||
|
||||
ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t,
|
||||
IdentifierTable &idents, SelectorTable &sels,
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
CXXField,
|
||||
ObjCIvar,
|
||||
ObjCAtDefsField,
|
||||
OverloadedFunction,
|
||||
ObjCCategory,
|
||||
ObjCCategoryImpl,
|
||||
ObjCImplementation,
|
||||
|
@ -178,6 +179,7 @@ public:
|
|||
case EnumConstant:
|
||||
case ObjCInterface:
|
||||
case ObjCCompatibleAlias:
|
||||
case OverloadedFunction:
|
||||
case CXXField:
|
||||
case CXXMethod:
|
||||
case CXXClassVar:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- DeclCXX.h - Classes for representing C++ declarations *- C++ -*-======//
|
||||
//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -15,6 +15,7 @@
|
|||
#define LLVM_CLANG_AST_DECLCXX_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
class CXXRecordDecl;
|
||||
|
@ -191,6 +192,85 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// OverloadedFunctionDecl - An instance of this class represents a
|
||||
/// set of overloaded functions. All of the functions have the same
|
||||
/// name and occur within the same scope.
|
||||
///
|
||||
/// An OverloadedFunctionDecl has no ownership over the FunctionDecl
|
||||
/// nodes it contains. Rather, the FunctionDecls are owned by the
|
||||
/// enclosing scope (which also owns the OverloadedFunctionDecl
|
||||
/// node). OverloadedFunctionDecl is used primarily to store a set of
|
||||
/// overloaded functions for name lookup.
|
||||
class OverloadedFunctionDecl : public NamedDecl {
|
||||
protected:
|
||||
OverloadedFunctionDecl(DeclContext *DC, IdentifierInfo *Id)
|
||||
: NamedDecl(OverloadedFunction, SourceLocation(), Id) { }
|
||||
|
||||
/// Functions - the set of overloaded functions contained in this
|
||||
/// overload set.
|
||||
llvm::SmallVector<FunctionDecl *, 4> Functions;
|
||||
|
||||
public:
|
||||
typedef llvm::SmallVector<FunctionDecl *, 4>::iterator function_iterator;
|
||||
typedef llvm::SmallVector<FunctionDecl *, 4>::const_iterator
|
||||
function_const_iterator;
|
||||
|
||||
static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
IdentifierInfo *Id);
|
||||
|
||||
/// addOverload - Add an overloaded function FD to this set of
|
||||
/// overloaded functions.
|
||||
void addOverload(FunctionDecl *FD) {
|
||||
assert((!getNumFunctions() || (FD->getDeclContext() == getDeclContext())) &&
|
||||
"Overloaded functions must all be in the same context");
|
||||
assert(FD->getIdentifier() == getIdentifier() &&
|
||||
"Overloaded functions must have the same name.");
|
||||
Functions.push_back(FD);
|
||||
}
|
||||
|
||||
function_iterator function_begin() { return Functions.begin(); }
|
||||
function_iterator function_end() { return Functions.end(); }
|
||||
function_const_iterator function_begin() const { return Functions.begin(); }
|
||||
function_const_iterator function_end() const { return Functions.end(); }
|
||||
|
||||
/// getNumFunctions - the number of overloaded functions stored in
|
||||
/// this set.
|
||||
unsigned getNumFunctions() const { return Functions.size(); }
|
||||
|
||||
/// getFunction - retrieve the ith function in the overload set.
|
||||
const FunctionDecl *getFunction(unsigned i) const {
|
||||
assert(i < getNumFunctions() && "Illegal function #");
|
||||
return Functions[i];
|
||||
}
|
||||
FunctionDecl *getFunction(unsigned i) {
|
||||
assert(i < getNumFunctions() && "Illegal function #");
|
||||
return Functions[i];
|
||||
}
|
||||
|
||||
// getDeclContext - Get the context of these overloaded functions.
|
||||
DeclContext *getDeclContext() {
|
||||
assert(getNumFunctions() > 0 && "Context of an empty overload set");
|
||||
return getFunction(0)->getDeclContext();
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) {
|
||||
return D->getKind() == OverloadedFunction;
|
||||
}
|
||||
static bool classof(const OverloadedFunctionDecl *D) { return true; }
|
||||
|
||||
protected:
|
||||
/// EmitImpl - Serialize this FunctionDecl. Called by Decl::Emit.
|
||||
virtual void EmitImpl(llvm::Serializer& S) const;
|
||||
|
||||
/// CreateImpl - Deserialize an OverloadedFunctionDecl. Called by
|
||||
/// Decl::Create.
|
||||
static OverloadedFunctionDecl* CreateImpl(llvm::Deserializer& D,
|
||||
ASTContext& C);
|
||||
|
||||
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace clang {
|
|||
class Decl;
|
||||
class IdentifierInfo;
|
||||
class ParmVarDecl;
|
||||
class NamedDecl;
|
||||
class ValueDecl;
|
||||
class BlockDecl;
|
||||
|
||||
|
@ -214,19 +215,19 @@ public:
|
|||
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
|
||||
/// enum, etc.
|
||||
class DeclRefExpr : public Expr {
|
||||
ValueDecl *D;
|
||||
NamedDecl *D;
|
||||
SourceLocation Loc;
|
||||
|
||||
protected:
|
||||
DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
|
||||
DeclRefExpr(StmtClass SC, NamedDecl *d, QualType t, SourceLocation l) :
|
||||
Expr(SC, t), D(d), Loc(l) {}
|
||||
|
||||
public:
|
||||
DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) :
|
||||
DeclRefExpr(NamedDecl *d, QualType t, SourceLocation l) :
|
||||
Expr(DeclRefExprClass, t), D(d), Loc(l) {}
|
||||
|
||||
ValueDecl *getDecl() { return D; }
|
||||
const ValueDecl *getDecl() const { return D; }
|
||||
NamedDecl *getDecl() { return D; }
|
||||
const NamedDecl *getDecl() const { return D; }
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
|
||||
|
||||
|
|
|
@ -494,7 +494,9 @@ public:
|
|||
Long,
|
||||
LongLong,
|
||||
|
||||
Float, Double, LongDouble
|
||||
Float, Double, LongDouble,
|
||||
|
||||
Overload // This represents the type of an overloaded function declaration.
|
||||
};
|
||||
private:
|
||||
Kind TypeKind;
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
#define LLVM_CLANG_EXPRDECLBVDVAL_H
|
||||
|
||||
#include "clang/AST/CFG.h"
|
||||
#include "clang/AST/Decl.h" // for ScopedDecl* -> NamedDecl* conversion
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Expr;
|
||||
class ScopedDecl;
|
||||
|
||||
struct DeclBitVector_Types {
|
||||
|
||||
|
@ -49,7 +49,7 @@ struct DeclBitVector_Types {
|
|||
|
||||
class AnalysisDataTy {
|
||||
public:
|
||||
typedef llvm::DenseMap<const ScopedDecl*, unsigned > DMapTy;
|
||||
typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy;
|
||||
typedef DMapTy::const_iterator decl_iterator;
|
||||
|
||||
protected:
|
||||
|
@ -61,16 +61,16 @@ struct DeclBitVector_Types {
|
|||
AnalysisDataTy() : NDecls(0) {}
|
||||
virtual ~AnalysisDataTy() {}
|
||||
|
||||
bool isTracked(const ScopedDecl* SD) { return DMap.find(SD) != DMap.end(); }
|
||||
bool isTracked(const NamedDecl* SD) { return DMap.find(SD) != DMap.end(); }
|
||||
|
||||
Idx getIdx(const ScopedDecl* SD) const {
|
||||
Idx getIdx(const NamedDecl* SD) const {
|
||||
DMapTy::const_iterator I = DMap.find(SD);
|
||||
return I == DMap.end() ? Idx() : Idx(I->second);
|
||||
}
|
||||
|
||||
unsigned getNumDecls() const { return NDecls; }
|
||||
|
||||
void Register(const ScopedDecl* SD) {
|
||||
void Register(const NamedDecl* SD) {
|
||||
if (!isTracked(SD)) DMap[SD] = NDecls++;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor<ImplClass> {
|
|||
public:
|
||||
|
||||
void VisitDeclRefExpr(DeclRefExpr* DR) {
|
||||
for (ScopedDecl* D = DR->getDecl(); D != NULL; D = D->getNextDeclarator())
|
||||
for (ScopedDecl* D = dyn_cast<ScopedDecl>(DR->getDecl()); D != NULL;
|
||||
D = D->getNextDeclarator())
|
||||
static_cast<ImplClass*>(this)->VisitScopedDecl(D);
|
||||
}
|
||||
|
||||
|
|
|
@ -800,6 +800,20 @@ DIAG(err_previous_use, ERROR,
|
|||
DIAG(err_first_label, ERROR,
|
||||
"first label is here")
|
||||
|
||||
// C++ Overloading Semantic Analysis.
|
||||
DIAG(err_ovl_diff_return_type, ERROR,
|
||||
"functions that differ only in their return type cannot be overloaded")
|
||||
DIAG(err_ovl_static_nonstatic_member, ERROR,
|
||||
"static and non-static member functions with the same parameter types cannot be overloaded")
|
||||
DIAG(err_ovl_no_viable_function_in_call, ERROR,
|
||||
"no matching function for call to '%0'.")
|
||||
DIAG(err_ovl_no_viable_function_in_call_with_cands, ERROR,
|
||||
"no matching function for call to '%0'; candidates are:")
|
||||
DIAG(err_ovl_ambiguous_call, ERROR,
|
||||
"call to '%0' is ambiguous; candidates are:")
|
||||
DIAG(err_ovl_candidate, NOTE,
|
||||
"candidate function")
|
||||
|
||||
DIAG(err_unexpected_typedef, ERROR,
|
||||
"unexpected type name '%0': expected expression")
|
||||
DIAG(err_unexpected_namespace, ERROR,
|
||||
|
|
|
@ -182,6 +182,9 @@ void ASTContext::InitBuiltinTypes() {
|
|||
// C++ 3.9.1p5
|
||||
InitBuiltinType(WCharTy, BuiltinType::WChar);
|
||||
|
||||
// Placeholder type for functions.
|
||||
InitBuiltinType(OverloadTy, BuiltinType::Overload);
|
||||
|
||||
// C99 6.2.5p11.
|
||||
FloatComplexTy = getComplexType(FloatTy);
|
||||
DoubleComplexTy = getComplexType(DoubleTy);
|
||||
|
|
|
@ -31,6 +31,7 @@ static unsigned nCXXSUC = 0;
|
|||
static unsigned nEnumConst = 0;
|
||||
static unsigned nEnumDecls = 0;
|
||||
static unsigned nNamespaces = 0;
|
||||
static unsigned nOverFuncs = 0;
|
||||
static unsigned nTypedef = 0;
|
||||
static unsigned nFieldDecls = 0;
|
||||
static unsigned nCXXFieldDecls = 0;
|
||||
|
@ -63,6 +64,7 @@ const char *Decl::getDeclKindName() const {
|
|||
switch (DeclKind) {
|
||||
default: assert(0 && "Unknown decl kind!");
|
||||
case Namespace: return "Namespace";
|
||||
case OverloadedFunction: return "OverloadedFunction";
|
||||
case Typedef: return "Typedef";
|
||||
case Function: return "Function";
|
||||
case Var: return "Var";
|
||||
|
@ -93,10 +95,13 @@ void Decl::PrintStats() {
|
|||
int(nFuncs+nVars+nParmVars+nFieldDecls+nSUC+nCXXFieldDecls+nCXXSUC+
|
||||
nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
|
||||
nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
|
||||
nAtDefsFieldDecls+nNamespaces));
|
||||
nAtDefsFieldDecls+nNamespaces+nOverFuncs));
|
||||
fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n",
|
||||
nNamespaces, (int)sizeof(NamespaceDecl),
|
||||
int(nNamespaces*sizeof(NamespaceDecl)));
|
||||
fprintf(stderr, " %d overloaded function decls, %d each (%d bytes)\n",
|
||||
nOverFuncs, (int)sizeof(OverloadedFunctionDecl),
|
||||
int(nOverFuncs*sizeof(OverloadedFunctionDecl)));
|
||||
fprintf(stderr, " %d function decls, %d each (%d bytes)\n",
|
||||
nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
|
||||
fprintf(stderr, " %d variable decls, %d each (%d bytes)\n",
|
||||
|
@ -192,13 +197,15 @@ void Decl::PrintStats() {
|
|||
nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
|
||||
nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
|
||||
nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
|
||||
nNamespaces*sizeof(NamespaceDecl)));
|
||||
nNamespaces*sizeof(NamespaceDecl)+
|
||||
nOverFuncs*sizeof(OverloadedFunctionDecl)));
|
||||
|
||||
}
|
||||
|
||||
void Decl::addDeclKind(Kind k) {
|
||||
switch (k) {
|
||||
case Namespace: nNamespaces++; break;
|
||||
case OverloadedFunction: nOverFuncs++; break;
|
||||
case Typedef: nTypedef++; break;
|
||||
case Function: nFuncs++; break;
|
||||
case Var: nVars++; break;
|
||||
|
|
|
@ -59,3 +59,10 @@ CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
|
|||
void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();
|
||||
return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);
|
||||
}
|
||||
|
||||
OverloadedFunctionDecl *
|
||||
OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
IdentifierInfo *Id) {
|
||||
void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
|
||||
return new (Mem) OverloadedFunctionDecl(DC, Id);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "llvm/Bitcode/Serialize.h"
|
||||
#include "llvm/Bitcode/Deserialize.h"
|
||||
|
@ -75,6 +76,10 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) {
|
|||
Dcl = FunctionDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case OverloadedFunction:
|
||||
Dcl = OverloadedFunctionDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Record:
|
||||
Dcl = RecordDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
@ -454,6 +459,34 @@ BlockDecl* BlockDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OverloadedFunctionDecl Serialization.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void OverloadedFunctionDecl::EmitImpl(Serializer& S) const {
|
||||
NamedDecl::EmitInRec(S);
|
||||
|
||||
S.EmitInt(getNumFunctions());
|
||||
for (unsigned func = 0; func < getNumFunctions(); ++func)
|
||||
S.EmitPtr(Functions[func]);
|
||||
}
|
||||
|
||||
OverloadedFunctionDecl *
|
||||
OverloadedFunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||
void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
|
||||
OverloadedFunctionDecl* decl = new (Mem)
|
||||
OverloadedFunctionDecl(0, NULL);
|
||||
|
||||
decl->NamedDecl::ReadInRec(D, C);
|
||||
|
||||
unsigned numFunctions = D.ReadInt();
|
||||
decl->Functions.reserve(numFunctions);
|
||||
for (unsigned func = 0; func < numFunctions; ++func)
|
||||
D.ReadPtr(decl->Functions[func]);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// RecordDecl Serialization.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -522,12 +522,12 @@ DeclRefExpr* DeclRefExpr::CreateImpl(Deserializer& D, ASTContext& C) {
|
|||
SourceLocation Loc = SourceLocation::ReadVal(D);
|
||||
QualType T = QualType::ReadVal(D);
|
||||
bool OwnsDecl = D.ReadBool();
|
||||
ValueDecl* decl;
|
||||
NamedDecl* decl;
|
||||
|
||||
if (!OwnsDecl)
|
||||
D.ReadPtr(decl,false); // No backpatching.
|
||||
else
|
||||
decl = cast<ValueDecl>(D.ReadOwnedPtr<Decl>(C));
|
||||
decl = cast<NamedDecl>(D.ReadOwnedPtr<Decl>(C));
|
||||
|
||||
return new DeclRefExpr(decl,T,Loc);
|
||||
}
|
||||
|
|
|
@ -450,6 +450,7 @@ bool Type::isIntegerType() const {
|
|||
BT->getKind() <= BuiltinType::LongLong;
|
||||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
|
||||
// Incomplete enum types are not treated as integer types.
|
||||
// FIXME: In C++, enum types are never integer types.
|
||||
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
|
||||
return true;
|
||||
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
|
||||
|
@ -466,6 +467,7 @@ bool Type::isIntegralType() const {
|
|||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
|
||||
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
|
||||
return true; // Complete enum types are integral.
|
||||
// FIXME: In C++, enum types are never integral.
|
||||
if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
|
||||
return ASQT->getBaseType()->isIntegralType();
|
||||
return false;
|
||||
|
@ -697,6 +699,7 @@ const char *BuiltinType::getName() const {
|
|||
case Double: return "double";
|
||||
case LongDouble: return "long double";
|
||||
case WChar: return "wchar_t";
|
||||
case Overload: return "<overloaded function type>";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -299,9 +299,9 @@ Store BasicStoreManager::getInitialStore() {
|
|||
Store St = VBFactory.GetEmptyMap().getRoot();
|
||||
|
||||
for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
|
||||
ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
|
||||
NamedDecl* ND = const_cast<NamedDecl*>(I->first);
|
||||
|
||||
if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
|
||||
if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
|
||||
// Punt on static variables for now.
|
||||
if (VD->getStorageClass() == VarDecl::Static)
|
||||
continue;
|
||||
|
|
|
@ -823,7 +823,7 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* Ex, NodeTy* Pred, NodeSet& Dst,
|
|||
|
||||
const GRState* St = GetState(Pred);
|
||||
|
||||
const ValueDecl* D = Ex->getDecl();
|
||||
const NamedDecl* D = Ex->getDecl();
|
||||
|
||||
if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
|
||||
|
||||
|
|
|
@ -118,9 +118,9 @@ Store RegionStoreManager::getInitialStore() {
|
|||
Store St = RBFactory.GetEmptyMap().getRoot();
|
||||
|
||||
for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
|
||||
ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
|
||||
NamedDecl* ND = const_cast<NamedDecl*>(I->first);
|
||||
|
||||
if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
|
||||
if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
|
||||
// Punt on static variables for now.
|
||||
if (VD->getStorageClass() == VarDecl::Static)
|
||||
continue;
|
||||
|
|
|
@ -371,7 +371,7 @@ public:
|
|||
}
|
||||
|
||||
llvm::Constant *VisitDeclRefExpr(DeclRefExpr *E) {
|
||||
const ValueDecl *Decl = E->getDecl();
|
||||
const NamedDecl *Decl = E->getDecl();
|
||||
if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(Decl))
|
||||
return llvm::ConstantInt::get(EC->getInitVal());
|
||||
assert(0 && "Unsupported decl ref type!");
|
||||
|
@ -769,7 +769,7 @@ public:
|
|||
return C;
|
||||
}
|
||||
case Expr::DeclRefExprClass: {
|
||||
ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
|
||||
NamedDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
|
||||
return CGM.GetAddrOfFunction(FD);
|
||||
if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
|
||||
|
|
|
@ -58,6 +58,8 @@ DeclContext *IdentifierResolver::LookupContext::getContext(Decl *D) {
|
|||
Ctx = EnumD->getDeclContext()->getParent();
|
||||
} else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
|
||||
Ctx = SD->getDeclContext();
|
||||
else if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
|
||||
Ctx = Ovl->getDeclContext();
|
||||
else
|
||||
return TUCtx();
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "IdentifierResolver.h"
|
||||
#include "CXXFieldCollector.h"
|
||||
#include "SemaOverload.h"
|
||||
#include "clang/Parse/Action.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
|
@ -362,6 +363,45 @@ private:
|
|||
FunctionDecl *MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
|
||||
void CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD);
|
||||
|
||||
/// C++ Overloading.
|
||||
bool IsOverload(FunctionDecl *New, Decl* OldD,
|
||||
OverloadedFunctionDecl::function_iterator &MatchedDecl);
|
||||
ImplicitConversionSequence TryCopyInitialization(Expr* From, QualType ToType);
|
||||
bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
|
||||
bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
|
||||
bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
|
||||
QualType& ConvertedType);
|
||||
|
||||
ImplicitConversionSequence::CompareKind
|
||||
CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
|
||||
const ImplicitConversionSequence& ICS2);
|
||||
|
||||
ImplicitConversionSequence::CompareKind
|
||||
CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
||||
const StandardConversionSequence& SCS2);
|
||||
|
||||
/// 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.
|
||||
};
|
||||
|
||||
void AddOverloadCandidate(FunctionDecl *Function,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet);
|
||||
void AddOverloadCandidates(OverloadedFunctionDecl *Ovl,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet);
|
||||
bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
|
||||
const OverloadCandidate& Cand2);
|
||||
OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
|
||||
OverloadCandidateSet::iterator& Best);
|
||||
void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
||||
bool OnlyViable);
|
||||
|
||||
|
||||
/// Helpers for dealing with function parameters
|
||||
bool CheckParmsForFunctionDef(FunctionDecl *FD);
|
||||
void CheckCXXDefaultArguments(FunctionDecl *FD);
|
||||
|
|
|
@ -93,9 +93,43 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
|
|||
// so swap the order on the shadowed declaration chain.
|
||||
|
||||
IdResolver.AddShadowedDecl(TD, *I);
|
||||
return;
|
||||
}
|
||||
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// We are pushing the name of a function, which might be an
|
||||
// overloaded name.
|
||||
IdentifierResolver::iterator
|
||||
I = IdResolver.begin(FD->getIdentifier(),
|
||||
FD->getDeclContext(), false/*LookInParentCtx*/);
|
||||
if (I != IdResolver.end() &&
|
||||
IdResolver.isDeclInScope(*I, FD->getDeclContext(), S) &&
|
||||
(isa<OverloadedFunctionDecl>(*I) || isa<FunctionDecl>(*I))) {
|
||||
// There is already a declaration with the same name in the same
|
||||
// scope. It must be a function or an overloaded function.
|
||||
OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(*I);
|
||||
if (!Ovl) {
|
||||
// We haven't yet overloaded this function. Take the existing
|
||||
// FunctionDecl and put it into an OverloadedFunctionDecl.
|
||||
Ovl = OverloadedFunctionDecl::Create(Context,
|
||||
FD->getDeclContext(),
|
||||
FD->getIdentifier());
|
||||
Ovl->addOverload(dyn_cast<FunctionDecl>(*I));
|
||||
|
||||
// Remove the name binding to the existing FunctionDecl...
|
||||
IdResolver.RemoveDecl(*I);
|
||||
|
||||
// ... and put the OverloadedFunctionDecl in its place.
|
||||
IdResolver.AddDecl(Ovl);
|
||||
}
|
||||
|
||||
// We have an OverloadedFunctionDecl. Add the new FunctionDecl
|
||||
// to its list of overloads.
|
||||
Ovl->addOverload(FD);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IdResolver.AddDecl(D);
|
||||
}
|
||||
|
||||
|
@ -320,9 +354,17 @@ static void MergeAttributes(Decl *New, Decl *Old) {
|
|||
/// declarator D which has the same name and scope as a previous
|
||||
/// declaration 'Old'. Figure out how to resolve this situation,
|
||||
/// merging decls or emitting diagnostics as appropriate.
|
||||
/// Redeclaration will be set true if thisNew is a redeclaration OldD.
|
||||
/// Redeclaration will be set true if this New is a redeclaration OldD.
|
||||
///
|
||||
/// In C++, New and Old must be declarations that are not
|
||||
/// overloaded. Use IsOverload to determine whether New and Old are
|
||||
/// overloaded, and to select the Old declaration that New should be
|
||||
/// merged with.
|
||||
FunctionDecl *
|
||||
Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
|
||||
assert(!isa<OverloadedFunctionDecl>(OldD) &&
|
||||
"Cannot merge with an overloaded function declaration");
|
||||
|
||||
Redeclaration = false;
|
||||
// Verify the old decl was also a function.
|
||||
FunctionDecl *Old = dyn_cast<FunctionDecl>(OldD);
|
||||
|
@ -333,16 +375,58 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
|
|||
return New;
|
||||
}
|
||||
|
||||
// Determine whether the previous declaration was a definition,
|
||||
// implicit declaration, or a declaration.
|
||||
diag::kind PrevDiag;
|
||||
if (Old->isThisDeclarationADefinition())
|
||||
PrevDiag = diag::err_previous_definition;
|
||||
else if (Old->isImplicit())
|
||||
PrevDiag = diag::err_previous_implicit_declaration;
|
||||
else
|
||||
PrevDiag = diag::err_previous_declaration;
|
||||
|
||||
QualType OldQType = Context.getCanonicalType(Old->getType());
|
||||
QualType NewQType = Context.getCanonicalType(New->getType());
|
||||
|
||||
// C++ [dcl.fct]p3:
|
||||
// All declarations for a function shall agree exactly in both the
|
||||
// return type and the parameter-type-list.
|
||||
if (getLangOptions().CPlusPlus && OldQType == NewQType) {
|
||||
MergeAttributes(New, Old);
|
||||
Redeclaration = true;
|
||||
return MergeCXXFunctionDecl(New, Old);
|
||||
if (getLangOptions().CPlusPlus) {
|
||||
// (C++98 13.1p2):
|
||||
// Certain function declarations cannot be overloaded:
|
||||
// -- Function declarations that differ only in the return type
|
||||
// cannot be overloaded.
|
||||
QualType OldReturnType
|
||||
= cast<FunctionType>(OldQType.getTypePtr())->getResultType();
|
||||
QualType NewReturnType
|
||||
= cast<FunctionType>(NewQType.getTypePtr())->getResultType();
|
||||
if (OldReturnType != NewReturnType) {
|
||||
Diag(New->getLocation(), diag::err_ovl_diff_return_type);
|
||||
Diag(Old->getLocation(), PrevDiag);
|
||||
return New;
|
||||
}
|
||||
|
||||
const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
|
||||
const CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
|
||||
if (OldMethod && NewMethod) {
|
||||
// -- Member function declarations with the same name and the
|
||||
// same parameter types cannot be overloaded if any of them
|
||||
// is a static member function declaration.
|
||||
if (OldMethod->isStatic() || NewMethod->isStatic()) {
|
||||
Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member);
|
||||
Diag(Old->getLocation(), PrevDiag);
|
||||
return New;
|
||||
}
|
||||
}
|
||||
|
||||
// (C++98 8.3.5p3):
|
||||
// All declarations for a function shall agree exactly in both the
|
||||
// return type and the parameter-type-list.
|
||||
if (OldQType == NewQType) {
|
||||
// We have a redeclaration.
|
||||
MergeAttributes(New, Old);
|
||||
Redeclaration = true;
|
||||
return MergeCXXFunctionDecl(New, Old);
|
||||
}
|
||||
|
||||
// Fall through for conflicting redeclarations and redefinitions.
|
||||
}
|
||||
|
||||
// C: Function types need to be compatible, not identical. This handles
|
||||
|
@ -356,13 +440,6 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) {
|
|||
|
||||
// A function that has already been declared has been redeclared or defined
|
||||
// with a different type- show appropriate diagnostic
|
||||
diag::kind PrevDiag;
|
||||
if (Old->isThisDeclarationADefinition())
|
||||
PrevDiag = diag::err_previous_definition;
|
||||
else if (Old->isImplicit())
|
||||
PrevDiag = diag::err_previous_implicit_declaration;
|
||||
else
|
||||
PrevDiag = diag::err_previous_declaration;
|
||||
|
||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
||||
// TODO: This is totally simplistic. It should handle merging functions
|
||||
|
@ -717,10 +794,49 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
|||
if (PrevDecl &&
|
||||
(!getLangOptions().CPlusPlus||isDeclInScope(PrevDecl, CurContext, S))) {
|
||||
bool Redeclaration = false;
|
||||
NewFD = MergeFunctionDecl(NewFD, PrevDecl, Redeclaration);
|
||||
if (NewFD == 0) return 0;
|
||||
if (Redeclaration) {
|
||||
NewFD->setPreviousDeclaration(cast<FunctionDecl>(PrevDecl));
|
||||
|
||||
// If C++, determine whether NewFD is an overload of PrevDecl or
|
||||
// a declaration that requires merging. If it's an overload,
|
||||
// there's no more work to do here; we'll just add the new
|
||||
// function to the scope.
|
||||
OverloadedFunctionDecl::function_iterator MatchedDecl;
|
||||
if (!getLangOptions().CPlusPlus ||
|
||||
!IsOverload(NewFD, PrevDecl, MatchedDecl)) {
|
||||
Decl *OldDecl = PrevDecl;
|
||||
|
||||
// If PrevDecl was an overloaded function, extract the
|
||||
// FunctionDecl that matched.
|
||||
if (isa<OverloadedFunctionDecl>(PrevDecl))
|
||||
OldDecl = *MatchedDecl;
|
||||
|
||||
// NewFD and PrevDecl represent declarations that need to be
|
||||
// merged.
|
||||
NewFD = MergeFunctionDecl(NewFD, OldDecl, Redeclaration);
|
||||
|
||||
if (NewFD == 0) return 0;
|
||||
if (Redeclaration) {
|
||||
NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
|
||||
|
||||
if (OldDecl == PrevDecl) {
|
||||
// Remove the name binding for the previous
|
||||
// declaration. We'll add the binding back later, but then
|
||||
// it will refer to the new declaration (which will
|
||||
// contain more information).
|
||||
IdResolver.RemoveDecl(cast<NamedDecl>(PrevDecl));
|
||||
} else {
|
||||
// We need to update the OverloadedFunctionDecl with the
|
||||
// latest declaration of this function, so that name
|
||||
// lookup will always refer to the latest declaration of
|
||||
// this function.
|
||||
*MatchedDecl = NewFD;
|
||||
|
||||
// Add the redeclaration to the current scope, since we'll
|
||||
// be skipping PushOnScopeChains.
|
||||
S->AddDecl(NewFD);
|
||||
|
||||
return NewFD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
New = NewFD;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <algorithm> // for std::equal
|
||||
|
||||
using namespace clang;
|
||||
|
||||
|
@ -58,7 +59,7 @@ namespace {
|
|||
/// determine whether this declaration can be used in the default
|
||||
/// argument expression.
|
||||
bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(DeclRefExpr *DRE) {
|
||||
ValueDecl *Decl = DRE->getDecl();
|
||||
NamedDecl *Decl = DRE->getDecl();
|
||||
if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Decl)) {
|
||||
// C++ [dcl.fct.default]p9
|
||||
// Default arguments are evaluated each time the function is
|
||||
|
|
|
@ -418,6 +418,9 @@ Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
|
|||
return Diag(Loc, diag::err_unexpected_namespace, II.getName());
|
||||
|
||||
// Make the DeclRefExpr or BlockDeclRefExpr for the decl.
|
||||
if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
|
||||
return new DeclRefExpr(Ovl, Context.OverloadTy, Loc);
|
||||
|
||||
ValueDecl *VD = cast<ValueDecl>(D);
|
||||
|
||||
// check if referencing an identifier with __attribute__((deprecated)).
|
||||
|
@ -1036,16 +1039,67 @@ ActOnCallExpr(ExprTy *fn, SourceLocation LParenLoc,
|
|||
Expr **Args = reinterpret_cast<Expr**>(args);
|
||||
assert(Fn && "no function call expression");
|
||||
FunctionDecl *FDecl = NULL;
|
||||
OverloadedFunctionDecl *Ovl = NULL;
|
||||
|
||||
// If we're directly calling a function or a set of overloaded
|
||||
// functions, get the appropriate declaration.
|
||||
{
|
||||
DeclRefExpr *DRExpr = NULL;
|
||||
if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
|
||||
DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr());
|
||||
else
|
||||
DRExpr = dyn_cast<DeclRefExpr>(Fn);
|
||||
|
||||
if (DRExpr) {
|
||||
FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
|
||||
Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a set of overloaded functions, perform overload
|
||||
// resolution to pick the function.
|
||||
if (Ovl) {
|
||||
OverloadCandidateSet CandidateSet;
|
||||
OverloadCandidateSet::iterator Best;
|
||||
AddOverloadCandidates(Ovl, Args, NumArgs, CandidateSet);
|
||||
switch (BestViableFunction(CandidateSet, Best)) {
|
||||
case OR_Success:
|
||||
{
|
||||
// Success! Let the remainder of this function build a call to
|
||||
// the function selected by overload resolution.
|
||||
FDecl = Best->Function;
|
||||
Expr *NewFn = new DeclRefExpr(FDecl, FDecl->getType(),
|
||||
Fn->getSourceRange().getBegin());
|
||||
delete Fn;
|
||||
Fn = NewFn;
|
||||
}
|
||||
break;
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
if (CandidateSet.empty())
|
||||
Diag(Fn->getSourceRange().getBegin(),
|
||||
diag::err_ovl_no_viable_function_in_call, Ovl->getName(),
|
||||
Fn->getSourceRange());
|
||||
else {
|
||||
Diag(Fn->getSourceRange().getBegin(),
|
||||
diag::err_ovl_no_viable_function_in_call_with_cands,
|
||||
Ovl->getName(), Fn->getSourceRange());
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
|
||||
}
|
||||
return true;
|
||||
|
||||
case OR_Ambiguous:
|
||||
Diag(Fn->getSourceRange().getBegin(),
|
||||
diag::err_ovl_ambiguous_call, Ovl->getName(),
|
||||
Fn->getSourceRange());
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Promote the function operand.
|
||||
UsualUnaryConversions(Fn);
|
||||
|
||||
// If we're directly calling a function, get the declaration for
|
||||
// that function.
|
||||
if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
|
||||
if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr()))
|
||||
FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
|
||||
|
||||
// Make the call expr early, before semantic checks. This guarantees cleanup
|
||||
// of arguments and function on error.
|
||||
llvm::OwningPtr<CallExpr> TheCall(new CallExpr(Fn, Args, NumArgs,
|
||||
|
@ -2338,7 +2392,7 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) {
|
|||
/// - *(x + 1) -> x, if x is an array
|
||||
/// - &"123"[2] -> 0
|
||||
/// - & __real__ x -> x
|
||||
static ValueDecl *getPrimaryDecl(Expr *E) {
|
||||
static NamedDecl *getPrimaryDecl(Expr *E) {
|
||||
switch (E->getStmtClass()) {
|
||||
case Stmt::DeclRefExprClass:
|
||||
return cast<DeclRefExpr>(E)->getDecl();
|
||||
|
@ -2351,7 +2405,8 @@ static ValueDecl *getPrimaryDecl(Expr *E) {
|
|||
case Stmt::ArraySubscriptExprClass: {
|
||||
// &X[4] and &4[X] refers to X if X is not a pointer.
|
||||
|
||||
ValueDecl *VD = getPrimaryDecl(cast<ArraySubscriptExpr>(E)->getBase());
|
||||
NamedDecl *D = getPrimaryDecl(cast<ArraySubscriptExpr>(E)->getBase());
|
||||
ValueDecl *VD = dyn_cast<ValueDecl>(D);
|
||||
if (!VD || VD->getType()->isPointerType())
|
||||
return 0;
|
||||
else
|
||||
|
@ -2363,10 +2418,13 @@ static ValueDecl *getPrimaryDecl(Expr *E) {
|
|||
switch(UO->getOpcode()) {
|
||||
case UnaryOperator::Deref: {
|
||||
// *(X + 1) refers to X if X is not a pointer.
|
||||
ValueDecl *VD = getPrimaryDecl(UO->getSubExpr());
|
||||
if (!VD || VD->getType()->isPointerType())
|
||||
return 0;
|
||||
return VD;
|
||||
if (NamedDecl *D = getPrimaryDecl(UO->getSubExpr())) {
|
||||
ValueDecl *VD = dyn_cast<ValueDecl>(D);
|
||||
if (!VD || VD->getType()->isPointerType())
|
||||
return 0;
|
||||
return VD;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case UnaryOperator::Real:
|
||||
case UnaryOperator::Imag:
|
||||
|
@ -2420,7 +2478,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
|||
// Technically, there should be a check for array subscript
|
||||
// expressions here, but the result of one is always an lvalue anyway.
|
||||
}
|
||||
ValueDecl *dcl = getPrimaryDecl(op);
|
||||
NamedDecl *dcl = getPrimaryDecl(op);
|
||||
Expr::isLvalueResult lval = op->isLvalue(Context);
|
||||
|
||||
if (lval != Expr::LV_Valid) { // C99 6.5.3.2p1
|
||||
|
|
|
@ -0,0 +1,903 @@
|
|||
//===--- SemaOverload.cpp - C++ Overloading ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides Sema routines for C++ overloading.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Sema.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// GetConversionCategory - Retrieve the implicit conversion
|
||||
/// category corresponding to the given implicit conversion kind.
|
||||
ImplicitConversionCategory
|
||||
GetConversionCategory(ImplicitConversionKind Kind) {
|
||||
static const ImplicitConversionCategory
|
||||
Category[(int)ICK_Num_Conversion_Kinds] = {
|
||||
ICC_Identity,
|
||||
ICC_Lvalue_Transformation,
|
||||
ICC_Lvalue_Transformation,
|
||||
ICC_Lvalue_Transformation,
|
||||
ICC_Qualification_Adjustment,
|
||||
ICC_Promotion,
|
||||
ICC_Promotion,
|
||||
ICC_Conversion,
|
||||
ICC_Conversion,
|
||||
ICC_Conversion,
|
||||
ICC_Conversion,
|
||||
ICC_Conversion,
|
||||
ICC_Conversion
|
||||
};
|
||||
return Category[(int)Kind];
|
||||
}
|
||||
|
||||
/// GetConversionRank - Retrieve the implicit conversion rank
|
||||
/// corresponding to the given implicit conversion kind.
|
||||
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) {
|
||||
static const ImplicitConversionRank
|
||||
Rank[(int)ICK_Num_Conversion_Kinds] = {
|
||||
ICR_Exact_Match,
|
||||
ICR_Exact_Match,
|
||||
ICR_Exact_Match,
|
||||
ICR_Exact_Match,
|
||||
ICR_Exact_Match,
|
||||
ICR_Promotion,
|
||||
ICR_Promotion,
|
||||
ICR_Conversion,
|
||||
ICR_Conversion,
|
||||
ICR_Conversion,
|
||||
ICR_Conversion,
|
||||
ICR_Conversion,
|
||||
ICR_Conversion
|
||||
};
|
||||
return Rank[(int)Kind];
|
||||
}
|
||||
|
||||
/// GetImplicitConversionName - Return the name of this kind of
|
||||
/// implicit conversion.
|
||||
const char* GetImplicitConversionName(ImplicitConversionKind Kind) {
|
||||
static const char* Name[(int)ICK_Num_Conversion_Kinds] = {
|
||||
"No conversion",
|
||||
"Lvalue-to-rvalue",
|
||||
"Array-to-pointer",
|
||||
"Function-to-pointer",
|
||||
"Qualification",
|
||||
"Integral promotion",
|
||||
"Floating point promotion",
|
||||
"Integral conversion",
|
||||
"Floating conversion",
|
||||
"Floating-integral conversion",
|
||||
"Pointer conversion",
|
||||
"Pointer-to-member conversion",
|
||||
"Boolean conversion"
|
||||
};
|
||||
return Name[Kind];
|
||||
}
|
||||
|
||||
/// getRank - Retrieve the rank of this standard conversion sequence
|
||||
/// (C++ 13.3.3.1.1p3). The rank is the largest rank of each of the
|
||||
/// implicit conversions.
|
||||
ImplicitConversionRank StandardConversionSequence::getRank() const {
|
||||
ImplicitConversionRank Rank = ICR_Exact_Match;
|
||||
if (GetConversionRank(First) > Rank)
|
||||
Rank = GetConversionRank(First);
|
||||
if (GetConversionRank(Second) > Rank)
|
||||
Rank = GetConversionRank(Second);
|
||||
if (GetConversionRank(Third) > Rank)
|
||||
Rank = GetConversionRank(Third);
|
||||
return Rank;
|
||||
}
|
||||
|
||||
/// isPointerConversionToBool - Determines whether this conversion is
|
||||
/// a conversion of a pointer or pointer-to-member to bool. This is
|
||||
/// used as part of the ranking of standard conversion sequences
|
||||
/// (C++ 13.3.3.2p4).
|
||||
bool StandardConversionSequence::isPointerConversionToBool() const
|
||||
{
|
||||
QualType FromType = QualType::getFromOpaquePtr(FromTypePtr);
|
||||
QualType ToType = QualType::getFromOpaquePtr(ToTypePtr);
|
||||
|
||||
// Note that FromType has not necessarily been transformed by the
|
||||
// array-to-pointer or function-to-pointer implicit conversions, so
|
||||
// check for their presence as well as checking whether FromType is
|
||||
// a pointer.
|
||||
if (ToType->isBooleanType() &&
|
||||
(FromType->isPointerType() ||
|
||||
First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// DebugPrint - Print this standard conversion sequence to standard
|
||||
/// error. Useful for debugging overloading issues.
|
||||
void StandardConversionSequence::DebugPrint() const {
|
||||
bool PrintedSomething = false;
|
||||
if (First != ICK_Identity) {
|
||||
fprintf(stderr, "%s", GetImplicitConversionName(First));
|
||||
PrintedSomething = true;
|
||||
}
|
||||
|
||||
if (Second != ICK_Identity) {
|
||||
if (PrintedSomething) {
|
||||
fprintf(stderr, " -> ");
|
||||
}
|
||||
fprintf(stderr, "%s", GetImplicitConversionName(Second));
|
||||
PrintedSomething = true;
|
||||
}
|
||||
|
||||
if (Third != ICK_Identity) {
|
||||
if (PrintedSomething) {
|
||||
fprintf(stderr, " -> ");
|
||||
}
|
||||
fprintf(stderr, "%s", GetImplicitConversionName(Third));
|
||||
PrintedSomething = true;
|
||||
}
|
||||
|
||||
if (!PrintedSomething) {
|
||||
fprintf(stderr, "No conversions required");
|
||||
}
|
||||
}
|
||||
|
||||
/// DebugPrint - Print this user-defined conversion sequence to standard
|
||||
/// error. Useful for debugging overloading issues.
|
||||
void UserDefinedConversionSequence::DebugPrint() const {
|
||||
if (Before.First || Before.Second || Before.Third) {
|
||||
Before.DebugPrint();
|
||||
fprintf(stderr, " -> ");
|
||||
}
|
||||
fprintf(stderr, "'%s'", ConversionFunction->getName());
|
||||
if (After.First || After.Second || After.Third) {
|
||||
fprintf(stderr, " -> ");
|
||||
After.DebugPrint();
|
||||
}
|
||||
}
|
||||
|
||||
/// DebugPrint - Print this implicit conversion sequence to standard
|
||||
/// error. Useful for debugging overloading issues.
|
||||
void ImplicitConversionSequence::DebugPrint() const {
|
||||
switch (ConversionKind) {
|
||||
case StandardConversion:
|
||||
fprintf(stderr, "Standard conversion: ");
|
||||
Standard.DebugPrint();
|
||||
break;
|
||||
case UserDefinedConversion:
|
||||
fprintf(stderr, "User-defined conversion: ");
|
||||
UserDefined.DebugPrint();
|
||||
break;
|
||||
case EllipsisConversion:
|
||||
fprintf(stderr, "Ellipsis conversion");
|
||||
break;
|
||||
case BadConversion:
|
||||
fprintf(stderr, "Bad conversion");
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
// IsOverload - Determine whether the given New declaration is an
|
||||
// overload of the Old declaration. This routine returns false if New
|
||||
// and Old cannot be overloaded, e.g., if they are functions with the
|
||||
// same signature (C++ 1.3.10) or if the Old declaration isn't a
|
||||
// function (or overload set). When it does return false and Old is an
|
||||
// OverloadedFunctionDecl, MatchedDecl will be set to point to the
|
||||
// FunctionDecl that New cannot be overloaded with.
|
||||
//
|
||||
// Example: Given the following input:
|
||||
//
|
||||
// void f(int, float); // #1
|
||||
// void f(int, int); // #2
|
||||
// int f(int, int); // #3
|
||||
//
|
||||
// When we process #1, there is no previous declaration of "f",
|
||||
// so IsOverload will not be used.
|
||||
//
|
||||
// When we process #2, Old is a FunctionDecl for #1. By comparing the
|
||||
// parameter types, we see that #1 and #2 are overloaded (since they
|
||||
// have different signatures), so this routine returns false;
|
||||
// MatchedDecl is unchanged.
|
||||
//
|
||||
// When we process #3, Old is an OverloadedFunctionDecl containing #1
|
||||
// and #2. We compare the signatures of #3 to #1 (they're overloaded,
|
||||
// so we do nothing) and then #3 to #2. Since the signatures of #3 and
|
||||
// #2 are identical (return types of functions are not part of the
|
||||
// signature), IsOverload returns false and MatchedDecl will be set to
|
||||
// point to the FunctionDecl for #2.
|
||||
bool
|
||||
Sema::IsOverload(FunctionDecl *New, Decl* OldD,
|
||||
OverloadedFunctionDecl::function_iterator& MatchedDecl)
|
||||
{
|
||||
if (OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(OldD)) {
|
||||
// Is this new function an overload of every function in the
|
||||
// overload set?
|
||||
OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
|
||||
FuncEnd = Ovl->function_end();
|
||||
for (; Func != FuncEnd; ++Func) {
|
||||
if (!IsOverload(New, *Func, MatchedDecl)) {
|
||||
MatchedDecl = Func;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This function overloads every function in the overload set.
|
||||
return true;
|
||||
} else if (FunctionDecl* Old = dyn_cast<FunctionDecl>(OldD)) {
|
||||
// Is the function New an overload of the function Old?
|
||||
QualType OldQType = Context.getCanonicalType(Old->getType());
|
||||
QualType NewQType = Context.getCanonicalType(New->getType());
|
||||
|
||||
// Compare the signatures (C++ 1.3.10) of the two functions to
|
||||
// determine whether they are overloads. If we find any mismatch
|
||||
// in the signature, they are overloads.
|
||||
|
||||
// If either of these functions is a K&R-style function (no
|
||||
// prototype), then we consider them to have matching signatures.
|
||||
if (isa<FunctionTypeNoProto>(OldQType.getTypePtr()) ||
|
||||
isa<FunctionTypeNoProto>(NewQType.getTypePtr()))
|
||||
return false;
|
||||
|
||||
FunctionTypeProto* OldType = cast<FunctionTypeProto>(OldQType.getTypePtr());
|
||||
FunctionTypeProto* NewType = cast<FunctionTypeProto>(NewQType.getTypePtr());
|
||||
|
||||
// The signature of a function includes the types of its
|
||||
// parameters (C++ 1.3.10), which includes the presence or absence
|
||||
// of the ellipsis; see C++ DR 357).
|
||||
if (OldQType != NewQType &&
|
||||
(OldType->getNumArgs() != NewType->getNumArgs() ||
|
||||
OldType->isVariadic() != NewType->isVariadic() ||
|
||||
!std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
|
||||
NewType->arg_type_begin())))
|
||||
return true;
|
||||
|
||||
// If the function is a class member, its signature includes the
|
||||
// cv-qualifiers (if any) on the function itself.
|
||||
//
|
||||
// As part of this, also check whether one of the member functions
|
||||
// is static, in which case they are not overloads (C++
|
||||
// 13.1p2). While not part of the definition of the signature,
|
||||
// this check is important to determine whether these functions
|
||||
// can be overloaded.
|
||||
CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
|
||||
CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
|
||||
if (OldMethod && NewMethod &&
|
||||
!OldMethod->isStatic() && !NewMethod->isStatic() &&
|
||||
OldQType.getCVRQualifiers() != NewQType.getCVRQualifiers())
|
||||
return true;
|
||||
|
||||
// The signatures match; this is not an overload.
|
||||
return false;
|
||||
} else {
|
||||
// (C++ 13p1):
|
||||
// Only function declarations can be overloaded; object and type
|
||||
// declarations cannot be overloaded.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// TryCopyInitialization - Attempt to copy-initialize a value of the
|
||||
/// given type (ToType) from the given expression (Expr), as one would
|
||||
/// do when copy-initializing a function parameter. This function
|
||||
/// returns an implicit conversion sequence that can be used to
|
||||
/// perform the initialization. Given
|
||||
///
|
||||
/// void f(float f);
|
||||
/// void g(int i) { f(i); }
|
||||
///
|
||||
/// this routine would produce an implicit conversion sequence to
|
||||
/// describe the initialization of f from i, which will be a standard
|
||||
/// conversion sequence containing an lvalue-to-rvalue conversion (C++
|
||||
/// 4.1) followed by a floating-integral conversion (C++ 4.9).
|
||||
//
|
||||
/// Note that this routine only determines how the conversion can be
|
||||
/// performed; it does not actually perform the conversion. As such,
|
||||
/// it will not produce any diagnostics if no conversion is available,
|
||||
/// but will instead return an implicit conversion sequence of kind
|
||||
/// "BadConversion".
|
||||
ImplicitConversionSequence
|
||||
Sema::TryCopyInitialization(Expr* From, QualType ToType)
|
||||
{
|
||||
ImplicitConversionSequence ICS;
|
||||
|
||||
QualType FromType = From->getType();
|
||||
|
||||
// Standard conversions (C++ 4)
|
||||
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS.Standard.Deprecated = false;
|
||||
ICS.Standard.FromTypePtr = FromType.getAsOpaquePtr();
|
||||
|
||||
// The first conversion can be an lvalue-to-rvalue conversion,
|
||||
// array-to-pointer conversion, or function-to-pointer conversion
|
||||
// (C++ 4p1).
|
||||
|
||||
// Lvalue-to-rvalue conversion (C++ 4.1):
|
||||
// An lvalue (3.10) of a non-function, non-array type T can be
|
||||
// converted to an rvalue.
|
||||
Expr::isLvalueResult argIsLvalue = From->isLvalue(Context);
|
||||
if (argIsLvalue == Expr::LV_Valid &&
|
||||
!FromType->isFunctionType() && !FromType->isArrayType()) {
|
||||
ICS.Standard.First = ICK_Lvalue_To_Rvalue;
|
||||
|
||||
// If T is a non-class type, the type of the rvalue is the
|
||||
// cv-unqualified version of T. Otherwise, the type of the rvalue
|
||||
// is T (C++ 4.1p1).
|
||||
if (!FromType->isRecordType())
|
||||
FromType = FromType.getUnqualifiedType();
|
||||
}
|
||||
// Array-to-pointer conversion (C++ 4.2)
|
||||
else if (FromType->isArrayType()) {
|
||||
ICS.Standard.First = ICK_Array_To_Pointer;
|
||||
|
||||
// An lvalue or rvalue of type "array of N T" or "array of unknown
|
||||
// bound of T" can be converted to an rvalue of type "pointer to
|
||||
// T" (C++ 4.2p1).
|
||||
FromType = Context.getArrayDecayedType(FromType);
|
||||
|
||||
if (IsStringLiteralToNonConstPointerConversion(From, ToType)) {
|
||||
// This conversion is deprecated. (C++ D.4).
|
||||
ICS.Standard.Deprecated = true;
|
||||
|
||||
// For the purpose of ranking in overload resolution
|
||||
// (13.3.3.1.1), this conversion is considered an
|
||||
// array-to-pointer conversion followed by a qualification
|
||||
// conversion (4.4). (C++ 4.2p2)
|
||||
ICS.Standard.Second = ICK_Identity;
|
||||
ICS.Standard.Third = ICK_Qualification;
|
||||
ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr();
|
||||
return ICS;
|
||||
}
|
||||
}
|
||||
// Function-to-pointer conversion (C++ 4.3).
|
||||
else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
|
||||
ICS.Standard.First = ICK_Function_To_Pointer;
|
||||
|
||||
// An lvalue of function type T can be converted to an rvalue of
|
||||
// type "pointer to T." The result is a pointer to the
|
||||
// function. (C++ 4.3p1).
|
||||
FromType = Context.getPointerType(FromType);
|
||||
|
||||
// FIXME: Deal with overloaded functions here (C++ 4.3p2).
|
||||
}
|
||||
// We don't require any conversions for the first step.
|
||||
else {
|
||||
ICS.Standard.First = ICK_Identity;
|
||||
}
|
||||
|
||||
// The second conversion can be an integral promotion, floating
|
||||
// point promotion, integral conversion, floating point conversion,
|
||||
// floating-integral conversion, pointer conversion,
|
||||
// pointer-to-member conversion, or boolean conversion (C++ 4p1).
|
||||
if (Context.getCanonicalType(FromType).getUnqualifiedType() ==
|
||||
Context.getCanonicalType(ToType).getUnqualifiedType()) {
|
||||
// The unqualified versions of the types are the same: there's no
|
||||
// conversion to do.
|
||||
ICS.Standard.Second = ICK_Identity;
|
||||
}
|
||||
// Integral promotion (C++ 4.5).
|
||||
else if (IsIntegralPromotion(From, FromType, ToType)) {
|
||||
ICS.Standard.Second = ICK_Integral_Promotion;
|
||||
FromType = ToType.getUnqualifiedType();
|
||||
}
|
||||
// Floating point promotion (C++ 4.6).
|
||||
else if (IsFloatingPointPromotion(FromType, ToType)) {
|
||||
ICS.Standard.Second = ICK_Floating_Promotion;
|
||||
FromType = ToType.getUnqualifiedType();
|
||||
}
|
||||
// Integral conversions (C++ 4.7).
|
||||
else if ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
|
||||
(ToType->isIntegralType() || ToType->isEnumeralType())) {
|
||||
ICS.Standard.Second = ICK_Integral_Conversion;
|
||||
FromType = ToType.getUnqualifiedType();
|
||||
}
|
||||
// Floating point conversions (C++ 4.8).
|
||||
else if (FromType->isFloatingType() && ToType->isFloatingType()) {
|
||||
ICS.Standard.Second = ICK_Floating_Conversion;
|
||||
FromType = ToType.getUnqualifiedType();
|
||||
}
|
||||
// Floating-integral conversions (C++ 4.9).
|
||||
else if ((FromType->isFloatingType() &&
|
||||
ToType->isIntegralType() && !ToType->isBooleanType()) ||
|
||||
((FromType->isIntegralType() || FromType->isEnumeralType()) &&
|
||||
ToType->isFloatingType())) {
|
||||
ICS.Standard.Second = ICK_Floating_Integral;
|
||||
FromType = ToType.getUnqualifiedType();
|
||||
}
|
||||
// Pointer conversions (C++ 4.10).
|
||||
else if (IsPointerConversion(From, FromType, ToType, FromType))
|
||||
ICS.Standard.Second = ICK_Pointer_Conversion;
|
||||
// FIXME: Pointer to member conversions (4.11).
|
||||
// Boolean conversions (C++ 4.12).
|
||||
// FIXME: pointer-to-member type
|
||||
else if (ToType->isBooleanType() &&
|
||||
(FromType->isArithmeticType() ||
|
||||
FromType->isEnumeralType() ||
|
||||
FromType->isPointerType())) {
|
||||
ICS.Standard.Second = ICK_Boolean_Conversion;
|
||||
FromType = Context.BoolTy;
|
||||
} else {
|
||||
// No second conversion required.
|
||||
ICS.Standard.Second = ICK_Identity;
|
||||
}
|
||||
|
||||
// The third conversion can be a qualification conversion (C++ 4p1).
|
||||
// FIXME: CheckPointerTypesForAssignment isn't the right way to
|
||||
// determine whether we have a qualification conversion.
|
||||
if (Context.getCanonicalType(FromType) != Context.getCanonicalType(ToType)
|
||||
&& CheckPointerTypesForAssignment(ToType, FromType) == Compatible) {
|
||||
ICS.Standard.Third = ICK_Qualification;
|
||||
FromType = ToType;
|
||||
} else {
|
||||
// No conversion required
|
||||
ICS.Standard.Third = ICK_Identity;
|
||||
}
|
||||
|
||||
// If we have not converted the argument type to the parameter type,
|
||||
// this is a bad conversion sequence.
|
||||
if (Context.getCanonicalType(FromType) != Context.getCanonicalType(ToType))
|
||||
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
|
||||
ICS.Standard.ToTypePtr = FromType.getAsOpaquePtr();
|
||||
return ICS;
|
||||
}
|
||||
|
||||
/// IsIntegralPromotion - Determines whether the conversion from the
|
||||
/// expression From (whose potentially-adjusted type is FromType) to
|
||||
/// ToType is an integral promotion (C++ 4.5). If so, returns true and
|
||||
/// sets PromotedType to the promoted type.
|
||||
bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
|
||||
{
|
||||
const BuiltinType *To = ToType->getAsBuiltinType();
|
||||
|
||||
// An rvalue of type char, signed char, unsigned char, short int, or
|
||||
// unsigned short int can be converted to an rvalue of type int if
|
||||
// int can represent all the values of the source type; otherwise,
|
||||
// the source rvalue can be converted to an rvalue of type unsigned
|
||||
// int (C++ 4.5p1).
|
||||
if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() && To) {
|
||||
if (// We can promote any signed, promotable integer type to an int
|
||||
(FromType->isSignedIntegerType() ||
|
||||
// We can promote any unsigned integer type whose size is
|
||||
// less than int to an int.
|
||||
(!FromType->isSignedIntegerType() &&
|
||||
Context.getTypeSize(FromType) < Context.getTypeSize(ToType))))
|
||||
return To->getKind() == BuiltinType::Int;
|
||||
|
||||
return To->getKind() == BuiltinType::UInt;
|
||||
}
|
||||
|
||||
// An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2)
|
||||
// can be converted to an rvalue of the first of the following types
|
||||
// that can represent all the values of its underlying type: int,
|
||||
// unsigned int, long, or unsigned long (C++ 4.5p2).
|
||||
if ((FromType->isEnumeralType() || FromType->isWideCharType())
|
||||
&& ToType->isIntegerType()) {
|
||||
// Determine whether the type we're converting from is signed or
|
||||
// unsigned.
|
||||
bool FromIsSigned;
|
||||
uint64_t FromSize = Context.getTypeSize(FromType);
|
||||
if (const EnumType *FromEnumType = FromType->getAsEnumType()) {
|
||||
QualType UnderlyingType = FromEnumType->getDecl()->getIntegerType();
|
||||
FromIsSigned = UnderlyingType->isSignedIntegerType();
|
||||
} else {
|
||||
// FIXME: Is wchar_t signed or unsigned? We assume it's signed for now.
|
||||
FromIsSigned = true;
|
||||
}
|
||||
|
||||
// The types we'll try to promote to, in the appropriate
|
||||
// order. Try each of these types.
|
||||
QualType PromoteTypes[4] = {
|
||||
Context.IntTy, Context.UnsignedIntTy,
|
||||
Context.LongTy, Context.UnsignedLongTy
|
||||
};
|
||||
for (int Idx = 0; Idx < 0; ++Idx) {
|
||||
uint64_t ToSize = Context.getTypeSize(PromoteTypes[Idx]);
|
||||
if (FromSize < ToSize ||
|
||||
(FromSize == ToSize &&
|
||||
FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) {
|
||||
// We found the type that we can promote to. If this is the
|
||||
// type we wanted, we have a promotion. Otherwise, no
|
||||
// promotion.
|
||||
return Context.getCanonicalType(FromType).getUnqualifiedType()
|
||||
== Context.getCanonicalType(PromoteTypes[Idx]).getUnqualifiedType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An rvalue for an integral bit-field (9.6) can be converted to an
|
||||
// rvalue of type int if int can represent all the values of the
|
||||
// bit-field; otherwise, it can be converted to unsigned int if
|
||||
// unsigned int can represent all the values of the bit-field. If
|
||||
// the bit-field is larger yet, no integral promotion applies to
|
||||
// it. If the bit-field has an enumerated type, it is treated as any
|
||||
// other value of that type for promotion purposes (C++ 4.5p3).
|
||||
if (MemberExpr *MemRef = dyn_cast<MemberExpr>(From)) {
|
||||
using llvm::APSInt;
|
||||
FieldDecl *MemberDecl = MemRef->getMemberDecl();
|
||||
APSInt BitWidth;
|
||||
if (MemberDecl->isBitField() &&
|
||||
FromType->isIntegralType() && !FromType->isEnumeralType() &&
|
||||
From->isIntegerConstantExpr(BitWidth, Context)) {
|
||||
APSInt ToSize(Context.getTypeSize(ToType));
|
||||
|
||||
// Are we promoting to an int from a bitfield that fits in an int?
|
||||
if (BitWidth < ToSize ||
|
||||
(FromType->isSignedIntegerType() && BitWidth <= ToSize))
|
||||
return To->getKind() == BuiltinType::Int;
|
||||
|
||||
// Are we promoting to an unsigned int from an unsigned bitfield
|
||||
// that fits into an unsigned int?
|
||||
if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize)
|
||||
return To->getKind() == BuiltinType::UInt;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// An rvalue of type bool can be converted to an rvalue of type int,
|
||||
// with false becoming zero and true becoming one (C++ 4.5p4).
|
||||
if (FromType->isBooleanType() && To && To->getKind() == BuiltinType::Int)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// IsFloatingPointPromotion - Determines whether the conversion from
|
||||
/// FromType to ToType is a floating point promotion (C++ 4.6). If so,
|
||||
/// returns true and sets PromotedType to the promoted type.
|
||||
bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType)
|
||||
{
|
||||
/// An rvalue of type float can be converted to an rvalue of type
|
||||
/// double. (C++ 4.6p1).
|
||||
if (const BuiltinType *FromBuiltin = FromType->getAsBuiltinType())
|
||||
if (const BuiltinType *ToBuiltin = ToType->getAsBuiltinType())
|
||||
if (FromBuiltin->getKind() == BuiltinType::Float &&
|
||||
ToBuiltin->getKind() == BuiltinType::Double)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// IsPointerConversion - Determines whether the conversion of the
|
||||
/// expression From, which has the (possibly adjusted) type FromType,
|
||||
/// can be converted to the type ToType via a pointer conversion (C++
|
||||
/// 4.10). If so, returns true and places the converted type (that
|
||||
/// might differ from ToType in its cv-qualifiers at some level) into
|
||||
/// ConvertedType.
|
||||
bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
|
||||
QualType& ConvertedType)
|
||||
{
|
||||
const PointerType* ToTypePtr = ToType->getAsPointerType();
|
||||
if (!ToTypePtr)
|
||||
return false;
|
||||
|
||||
// A null pointer constant can be converted to a pointer type (C++ 4.10p1).
|
||||
if (From->isNullPointerConstant(Context)) {
|
||||
ConvertedType = ToType;
|
||||
return true;
|
||||
}
|
||||
|
||||
// An rvalue of type "pointer to cv T," where T is an object type,
|
||||
// can be converted to an rvalue of type "pointer to cv void" (C++
|
||||
// 4.10p2).
|
||||
if (FromType->isPointerType() &&
|
||||
FromType->getAsPointerType()->getPointeeType()->isObjectType() &&
|
||||
ToTypePtr->getPointeeType()->isVoidType()) {
|
||||
// We need to produce a pointer to cv void, where cv is the same
|
||||
// set of cv-qualifiers as we had on the incoming pointee type.
|
||||
QualType toPointee = ToTypePtr->getPointeeType();
|
||||
unsigned Quals = Context.getCanonicalType(FromType)->getAsPointerType()
|
||||
->getPointeeType().getCVRQualifiers();
|
||||
|
||||
if (Context.getCanonicalType(ToTypePtr->getPointeeType()).getCVRQualifiers()
|
||||
== Quals) {
|
||||
// ToType is exactly the type we want. Use it.
|
||||
ConvertedType = ToType;
|
||||
} else {
|
||||
// Build a new type with the right qualifiers.
|
||||
ConvertedType
|
||||
= Context.getPointerType(Context.VoidTy.getQualifiedType(Quals));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME: An rvalue of type "pointer to cv D," where D is a class
|
||||
// type, can be converted to an rvalue of type "pointer to cv B,"
|
||||
// where B is a base class (clause 10) of D (C++ 4.10p3).
|
||||
return false;
|
||||
}
|
||||
|
||||
/// CompareImplicitConversionSequences - Compare two implicit
|
||||
/// conversion sequences to determine whether one is better than the
|
||||
/// other or if they are indistinguishable (C++ 13.3.3.2).
|
||||
ImplicitConversionSequence::CompareKind
|
||||
Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
|
||||
const ImplicitConversionSequence& ICS2)
|
||||
{
|
||||
// (C++ 13.3.3.2p2): When comparing the basic forms of implicit
|
||||
// conversion sequences (as defined in 13.3.3.1)
|
||||
// -- a standard conversion sequence (13.3.3.1.1) is a better
|
||||
// conversion sequence than a user-defined conversion sequence or
|
||||
// an ellipsis conversion sequence, and
|
||||
// -- a user-defined conversion sequence (13.3.3.1.2) is a better
|
||||
// conversion sequence than an ellipsis conversion sequence
|
||||
// (13.3.3.1.3).
|
||||
//
|
||||
if (ICS1.ConversionKind < ICS2.ConversionKind)
|
||||
return ImplicitConversionSequence::Better;
|
||||
else if (ICS2.ConversionKind < ICS1.ConversionKind)
|
||||
return ImplicitConversionSequence::Worse;
|
||||
|
||||
// Two implicit conversion sequences of the same form are
|
||||
// indistinguishable conversion sequences unless one of the
|
||||
// following rules apply: (C++ 13.3.3.2p3):
|
||||
if (ICS1.ConversionKind == ImplicitConversionSequence::StandardConversion)
|
||||
return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
|
||||
else if (ICS1.ConversionKind ==
|
||||
ImplicitConversionSequence::UserDefinedConversion) {
|
||||
// User-defined conversion sequence U1 is a better conversion
|
||||
// sequence than another user-defined conversion sequence U2 if
|
||||
// they contain the same user-defined conversion function or
|
||||
// constructor and if the second standard conversion sequence of
|
||||
// U1 is better than the second standard conversion sequence of
|
||||
// U2 (C++ 13.3.3.2p3).
|
||||
if (ICS1.UserDefined.ConversionFunction ==
|
||||
ICS2.UserDefined.ConversionFunction)
|
||||
return CompareStandardConversionSequences(ICS1.UserDefined.After,
|
||||
ICS2.UserDefined.After);
|
||||
}
|
||||
|
||||
return ImplicitConversionSequence::Indistinguishable;
|
||||
}
|
||||
|
||||
/// CompareStandardConversionSequences - Compare two standard
|
||||
/// conversion sequences to determine whether one is better than the
|
||||
/// other or if they are indistinguishable (C++ 13.3.3.2p3).
|
||||
ImplicitConversionSequence::CompareKind
|
||||
Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
||||
const StandardConversionSequence& SCS2)
|
||||
{
|
||||
// Standard conversion sequence S1 is a better conversion sequence
|
||||
// than standard conversion sequence S2 if (C++ 13.3.3.2p3):
|
||||
|
||||
// -- S1 is a proper subsequence of S2 (comparing the conversion
|
||||
// sequences in the canonical form defined by 13.3.3.1.1,
|
||||
// excluding any Lvalue Transformation; the identity conversion
|
||||
// sequence is considered to be a subsequence of any
|
||||
// non-identity conversion sequence) or, if not that,
|
||||
if (SCS1.Second == SCS2.Second && SCS1.Third == SCS2.Third)
|
||||
// Neither is a proper subsequence of the other. Do nothing.
|
||||
;
|
||||
else if ((SCS1.Second == ICK_Identity && SCS1.Third == SCS2.Third) ||
|
||||
(SCS1.Third == ICK_Identity && SCS1.Second == SCS2.Second) ||
|
||||
(SCS1.Second == ICK_Identity &&
|
||||
SCS1.Third == ICK_Identity))
|
||||
// SCS1 is a proper subsequence of SCS2.
|
||||
return ImplicitConversionSequence::Better;
|
||||
else if ((SCS2.Second == ICK_Identity && SCS2.Third == SCS1.Third) ||
|
||||
(SCS2.Third == ICK_Identity && SCS2.Second == SCS1.Second) ||
|
||||
(SCS2.Second == ICK_Identity &&
|
||||
SCS2.Third == ICK_Identity))
|
||||
// SCS2 is a proper subsequence of SCS1.
|
||||
return ImplicitConversionSequence::Worse;
|
||||
|
||||
// -- the rank of S1 is better than the rank of S2 (by the rules
|
||||
// defined below), or, if not that,
|
||||
ImplicitConversionRank Rank1 = SCS1.getRank();
|
||||
ImplicitConversionRank Rank2 = SCS2.getRank();
|
||||
if (Rank1 < Rank2)
|
||||
return ImplicitConversionSequence::Better;
|
||||
else if (Rank2 < Rank1)
|
||||
return ImplicitConversionSequence::Worse;
|
||||
else {
|
||||
// (C++ 13.3.3.2p4): Two conversion sequences with the same rank
|
||||
// are indistinguishable unless one of the following rules
|
||||
// applies:
|
||||
|
||||
// A conversion that is not a conversion of a pointer, or
|
||||
// pointer to member, to bool is better than another conversion
|
||||
// that is such a conversion.
|
||||
if (SCS1.isPointerConversionToBool() != SCS2.isPointerConversionToBool())
|
||||
return SCS2.isPointerConversionToBool()
|
||||
? ImplicitConversionSequence::Better
|
||||
: ImplicitConversionSequence::Worse;
|
||||
|
||||
// FIXME: The other bullets in (C++ 13.3.3.2p4) require support
|
||||
// for derived classes.
|
||||
}
|
||||
|
||||
// FIXME: Handle comparison by qualifications.
|
||||
// FIXME: Handle comparison of reference bindings.
|
||||
return ImplicitConversionSequence::Indistinguishable;
|
||||
}
|
||||
|
||||
/// AddOverloadCandidate - Adds the given function to the set of
|
||||
/// candidate functions, using the given function call arguments.
|
||||
void
|
||||
Sema::AddOverloadCandidate(FunctionDecl *Function,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet)
|
||||
{
|
||||
const FunctionTypeProto* Proto
|
||||
= dyn_cast<FunctionTypeProto>(Function->getType()->getAsFunctionType());
|
||||
assert(Proto && "Functions without a prototype cannot be overloaded");
|
||||
|
||||
// Add this candidate
|
||||
CandidateSet.push_back(OverloadCandidate());
|
||||
OverloadCandidate& Candidate = CandidateSet.back();
|
||||
Candidate.Function = Function;
|
||||
|
||||
unsigned NumArgsInProto = Proto->getNumArgs();
|
||||
|
||||
// (C++ 13.3.2p2): A candidate function having fewer than m
|
||||
// parameters is viable only if it has an ellipsis in its parameter
|
||||
// list (8.3.5).
|
||||
if (NumArgs > NumArgsInProto && !Proto->isVariadic()) {
|
||||
Candidate.Viable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// (C++ 13.3.2p2): A candidate function having more than m parameters
|
||||
// is viable only if the (m+1)st parameter has a default argument
|
||||
// (8.3.6). For the purposes of overload resolution, the
|
||||
// parameter list is truncated on the right, so that there are
|
||||
// exactly m parameters.
|
||||
unsigned MinRequiredArgs = Function->getMinRequiredArguments();
|
||||
if (NumArgs < MinRequiredArgs) {
|
||||
// Not enough arguments.
|
||||
Candidate.Viable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine the implicit conversion sequences for each of the
|
||||
// arguments.
|
||||
Candidate.Viable = true;
|
||||
Candidate.Conversions.resize(NumArgs);
|
||||
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
|
||||
if (ArgIdx < NumArgsInProto) {
|
||||
// (C++ 13.3.2p3): for F to be a viable function, there shall
|
||||
// exist for each argument an implicit conversion sequence
|
||||
// (13.3.3.1) that converts that argument to the corresponding
|
||||
// parameter of F.
|
||||
QualType ParamType = Proto->getArgType(ArgIdx);
|
||||
Candidate.Conversions[ArgIdx]
|
||||
= TryCopyInitialization(Args[ArgIdx], ParamType);
|
||||
if (Candidate.Conversions[ArgIdx].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion)
|
||||
Candidate.Viable = false;
|
||||
} else {
|
||||
// (C++ 13.3.2p2): For the purposes of overload resolution, any
|
||||
// argument for which there is no corresponding parameter is
|
||||
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
|
||||
Candidate.Conversions[ArgIdx].ConversionKind
|
||||
= ImplicitConversionSequence::EllipsisConversion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AddOverloadCandidates - Add all of the function overloads in Ovl
|
||||
/// to the candidate set.
|
||||
void
|
||||
Sema::AddOverloadCandidates(OverloadedFunctionDecl *Ovl,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet& CandidateSet)
|
||||
{
|
||||
for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin();
|
||||
Func != Ovl->function_end(); ++Func)
|
||||
AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet);
|
||||
}
|
||||
|
||||
/// isBetterOverloadCandidate - Determines whether the first overload
|
||||
/// candidate is a better candidate than the second (C++ 13.3.3p1).
|
||||
bool
|
||||
Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
|
||||
const OverloadCandidate& Cand2)
|
||||
{
|
||||
// Define viable functions to be better candidates than non-viable
|
||||
// functions.
|
||||
if (!Cand2.Viable)
|
||||
return Cand1.Viable;
|
||||
else if (!Cand1.Viable)
|
||||
return false;
|
||||
|
||||
// FIXME: Deal with the implicit object parameter for static member
|
||||
// functions. (C++ 13.3.3p1).
|
||||
|
||||
// (C++ 13.3.3p1): a viable function F1 is defined to be a better
|
||||
// function than another viable function F2 if for all arguments i,
|
||||
// ICSi(F1) is not a worse conversion sequence than ICSi(F2), and
|
||||
// then...
|
||||
unsigned NumArgs = Cand1.Conversions.size();
|
||||
assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
|
||||
bool HasBetterConversion = false;
|
||||
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
|
||||
switch (CompareImplicitConversionSequences(Cand1.Conversions[ArgIdx],
|
||||
Cand2.Conversions[ArgIdx])) {
|
||||
case ImplicitConversionSequence::Better:
|
||||
// Cand1 has a better conversion sequence.
|
||||
HasBetterConversion = true;
|
||||
break;
|
||||
|
||||
case ImplicitConversionSequence::Worse:
|
||||
// Cand1 can't be better than Cand2.
|
||||
return false;
|
||||
|
||||
case ImplicitConversionSequence::Indistinguishable:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasBetterConversion)
|
||||
return true;
|
||||
|
||||
// FIXME: Several other bullets in (C++ 13.3.3p1) need to be implemented.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// BestViableFunction - Computes the best viable function (C++ 13.3.3)
|
||||
/// within an overload candidate set. If overloading is successful,
|
||||
/// the result will be OR_Success and Best will be set to point to the
|
||||
/// best viable function within the candidate set. Otherwise, one of
|
||||
/// several kinds of errors will be returned; see
|
||||
/// Sema::OverloadingResult.
|
||||
Sema::OverloadingResult
|
||||
Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
|
||||
OverloadCandidateSet::iterator& Best)
|
||||
{
|
||||
// Find the best viable function.
|
||||
Best = CandidateSet.end();
|
||||
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
|
||||
Cand != CandidateSet.end(); ++Cand) {
|
||||
if (Cand->Viable) {
|
||||
if (Best == CandidateSet.end() || isBetterOverloadCandidate(*Cand, *Best))
|
||||
Best = Cand;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find any viable functions, abort.
|
||||
if (Best == CandidateSet.end())
|
||||
return OR_No_Viable_Function;
|
||||
|
||||
// Make sure that this function is better than every other viable
|
||||
// function. If not, we have an ambiguity.
|
||||
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
|
||||
Cand != CandidateSet.end(); ++Cand) {
|
||||
if (Cand->Viable &&
|
||||
Cand != Best &&
|
||||
!isBetterOverloadCandidate(*Best, *Cand))
|
||||
return OR_Ambiguous;
|
||||
}
|
||||
|
||||
// Best is the best viable function.
|
||||
return OR_Success;
|
||||
}
|
||||
|
||||
/// PrintOverloadCandidates - When overload resolution fails, prints
|
||||
/// diagnostic messages containing the candidates in the candidate
|
||||
/// set. If OnlyViable is true, only viable candidates will be printed.
|
||||
void
|
||||
Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
||||
bool OnlyViable)
|
||||
{
|
||||
OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
|
||||
LastCand = CandidateSet.end();
|
||||
for (; Cand != LastCand; ++Cand) {
|
||||
if (Cand->Viable ||!OnlyViable)
|
||||
Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace clang
|
|
@ -0,0 +1,199 @@
|
|||
//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the data structures and types used in C++
|
||||
// overload resolution.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SEMA_OVERLOAD_H
|
||||
#define LLVM_CLANG_SEMA_OVERLOAD_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
class FunctionDecl;
|
||||
|
||||
/// ImplicitConversionKind - The kind of implicit conversion used to
|
||||
/// convert an argument to a parameter's type. The enumerator values
|
||||
/// 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_Qualification, ///< Qualification conversions (C++ 4.4)
|
||||
ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5)
|
||||
ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6)
|
||||
ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7)
|
||||
ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8)
|
||||
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_Num_Conversion_Kinds ///< The number of conversion kinds
|
||||
};
|
||||
|
||||
/// ImplicitConversionCategory - The category of an implicit
|
||||
/// conversion kind. The enumerator values match with Table 9 of
|
||||
/// (C++ 13.3.3.1.1) and are listed such that better conversion
|
||||
/// categories have smaller values.
|
||||
enum ImplicitConversionCategory {
|
||||
ICC_Identity = 0, ///< Identity
|
||||
ICC_Lvalue_Transformation, ///< Lvalue transformation
|
||||
ICC_Qualification_Adjustment, ///< Qualification adjustment
|
||||
ICC_Promotion, ///< Promotion
|
||||
ICC_Conversion ///< Conversion
|
||||
};
|
||||
|
||||
ImplicitConversionCategory
|
||||
GetConversionCategory(ImplicitConversionKind Kind);
|
||||
|
||||
/// ImplicitConversionRank - The rank of an implicit conversion
|
||||
/// kind. The enumerator values match with Table 9 of (C++
|
||||
/// 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
|
||||
};
|
||||
|
||||
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
|
||||
|
||||
/// StandardConversionSequence - represents a standard conversion
|
||||
/// sequence (C++ 13.3.3.1.1). A standard conversion sequence
|
||||
/// contains between zero and three conversions. If a particular
|
||||
/// conversion is not needed, it will be set to the identity conversion
|
||||
/// (ICK_Identity). Note that the three conversions are
|
||||
/// specified as separate members (rather than in an array) so that
|
||||
/// we can keep the size of a standard conversion sequence to a
|
||||
/// single word.
|
||||
struct StandardConversionSequence {
|
||||
/// First -- The first conversion can be an lvalue-to-rvalue
|
||||
/// conversion, array-to-pointer conversion, or
|
||||
/// function-to-pointer conversion.
|
||||
ImplicitConversionKind First : 8;
|
||||
|
||||
/// Second - The second conversion can be an integral promotion,
|
||||
/// floating point promotion, integral conversion, floating point
|
||||
/// conversion, floating-integral conversion, pointer conversion,
|
||||
/// pointer-to-member conversion, or boolean conversion.
|
||||
ImplicitConversionKind Second : 8;
|
||||
|
||||
/// Third - The third conversion can be a qualification conversion.
|
||||
ImplicitConversionKind Third : 8;
|
||||
|
||||
/// Deprecated - Whether this is a deprecated conversion, such as
|
||||
/// converting a string literal to a pointer to non-const
|
||||
/// character data (C++ 4.2p2).
|
||||
bool Deprecated : 1;
|
||||
|
||||
/// FromType - The type that this conversion is converting
|
||||
/// from. This is an opaque pointer for that can be translated
|
||||
/// into a QualType.
|
||||
void *FromTypePtr;
|
||||
|
||||
/// ToType - The type that this conversion is converting to. This
|
||||
/// is an opaque pointer for that can be translated into a
|
||||
/// QualType.
|
||||
void *ToTypePtr;
|
||||
|
||||
ImplicitConversionRank getRank() const;
|
||||
bool isPointerConversionToBool() const;
|
||||
void DebugPrint() const;
|
||||
};
|
||||
|
||||
/// UserDefinedConversionSequence - Represents a user-defined
|
||||
/// conversion sequence (C++ 13.3.3.1.2).
|
||||
struct UserDefinedConversionSequence {
|
||||
/// Before - Represents the standard conversion that occurs before
|
||||
/// the actual user-defined conversion. (C++ 13.3.3.1.2p1):
|
||||
///
|
||||
/// If the user-defined conversion is specified by a constructor
|
||||
/// (12.3.1), the initial standard conversion sequence converts
|
||||
/// the source type to the type required by the argument of the
|
||||
/// constructor. If the user-defined conversion is specified by
|
||||
/// a conversion function (12.3.2), the initial standard
|
||||
/// conversion sequence converts the source type to the implicit
|
||||
/// object parameter of the conversion function.
|
||||
StandardConversionSequence Before;
|
||||
|
||||
/// After - Represents the standard conversion that occurs after
|
||||
/// the actual user-defined conversion.
|
||||
StandardConversionSequence After;
|
||||
|
||||
/// ConversionFunction - The function that will perform the
|
||||
/// user-defined conversion.
|
||||
FunctionDecl* ConversionFunction;
|
||||
|
||||
void DebugPrint() const;
|
||||
};
|
||||
|
||||
/// ImplicitConversionSequence - Represents an implicit conversion
|
||||
/// sequence, which may be a standard conversion sequence
|
||||
// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
|
||||
/// or an ellipsis conversion sequence (C++ 13.3.3.1.3).
|
||||
struct ImplicitConversionSequence {
|
||||
/// Kind - The kind of implicit conversion sequence. BadConversion
|
||||
/// specifies that there is no conversion from the source type to
|
||||
/// the target type. The enumerator values are ordered such that
|
||||
/// better implicit conversions have smaller values.
|
||||
enum Kind {
|
||||
StandardConversion = 0,
|
||||
UserDefinedConversion,
|
||||
EllipsisConversion,
|
||||
BadConversion
|
||||
};
|
||||
|
||||
/// ConversionKind - The kind of implicit conversion sequence.
|
||||
Kind ConversionKind;
|
||||
|
||||
union {
|
||||
/// When ConversionKind == StandardConversion, provides the
|
||||
/// details of the standard conversion sequence.
|
||||
StandardConversionSequence Standard;
|
||||
|
||||
/// When ConversionKind == UserDefinedConversion, provides the
|
||||
/// details of the user-defined conversion sequence.
|
||||
UserDefinedConversionSequence UserDefined;
|
||||
};
|
||||
|
||||
// The result of a comparison between implicit conversion
|
||||
// sequences. Use Sema::CompareImplicitConversionSequences to
|
||||
// actually perform the comparison.
|
||||
enum CompareKind {
|
||||
Better,
|
||||
Indistinguishable,
|
||||
Worse
|
||||
};
|
||||
|
||||
void DebugPrint() const;
|
||||
};
|
||||
|
||||
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
|
||||
struct OverloadCandidate {
|
||||
/// Function - The actual function that this candidate represents.
|
||||
FunctionDecl *Function;
|
||||
|
||||
/// Conversions - The conversion sequences used to convert the
|
||||
/// function arguments to the function parameters.
|
||||
llvm::SmallVector<ImplicitConversionSequence, 4> Conversions;
|
||||
|
||||
/// Viable - True to indicate that this overload candidate is viable.
|
||||
bool Viable;
|
||||
};
|
||||
|
||||
/// OverloadCandidateSet - A set of overload candidates, used in C++
|
||||
/// overload resolution (C++ 13.3).
|
||||
typedef llvm::SmallVector<OverloadCandidate, 4> OverloadCandidateSet;
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
|
|
@ -0,0 +1,137 @@
|
|||
// RUN: clang -fsyntax-only -pedantic -verify %s
|
||||
int* f(int);
|
||||
float* f(float);
|
||||
void f();
|
||||
|
||||
void test_f(int iv, float fv) {
|
||||
float* fp = f(fv);
|
||||
int* ip = f(iv);
|
||||
}
|
||||
|
||||
int* g(int, float, int); // expected-note {{ candidate function }}
|
||||
float* g(int, int, int); // expected-note {{ candidate function }}
|
||||
double* g(int, float, float); // expected-note {{ candidate function }}
|
||||
char* g(int, float, ...); // expected-note {{ candidate function }}
|
||||
void g();
|
||||
|
||||
void test_g(int iv, float fv) {
|
||||
int* ip1 = g(iv, fv, 0);
|
||||
float* fp1 = g(iv, iv, 0);
|
||||
double* dp1 = g(iv, fv, fv);
|
||||
char* cp1 = g(0, 0);
|
||||
char* cp2 = g(0, 0, 0, iv, fv);
|
||||
|
||||
double* dp2 = g(0, fv, 1.5); // expected-error {{ call to 'g' is ambiguous; candidates are: }}
|
||||
}
|
||||
|
||||
double* h(double f);
|
||||
int* h(int);
|
||||
|
||||
void test_h(float fv, unsigned char cv) {
|
||||
double* dp = h(fv);
|
||||
int* ip = h(cv);
|
||||
}
|
||||
|
||||
int* i(int);
|
||||
double* i(long);
|
||||
|
||||
void test_i(short sv, int iv, long lv, unsigned char ucv) {
|
||||
int* ip1 = i(sv);
|
||||
int* ip2 = i(iv);
|
||||
int* ip3 = i(ucv);
|
||||
double* dp1 = i(lv);
|
||||
}
|
||||
|
||||
int* j(void*);
|
||||
double* j(bool);
|
||||
|
||||
void test_j(int* ip) {
|
||||
int* ip1 = j(ip);
|
||||
}
|
||||
|
||||
int* k(char*);
|
||||
double* k(bool);
|
||||
|
||||
void test_k() {
|
||||
int* ip1 = k("foo");
|
||||
double* dp1 = k(L"foo");
|
||||
}
|
||||
|
||||
int* l(wchar_t*);
|
||||
double* l(bool);
|
||||
|
||||
void test_l() {
|
||||
int* ip1 = l(L"foo");
|
||||
double* dp1 = l("foo");
|
||||
}
|
||||
|
||||
int* m(const char*);
|
||||
double* m(char*);
|
||||
|
||||
void test_m() {
|
||||
int* ip = m("foo");
|
||||
}
|
||||
|
||||
int* n(char*);
|
||||
double* n(void*);
|
||||
|
||||
void test_n() {
|
||||
char ca[7];
|
||||
int* ip1 = n(ca);
|
||||
int* ip2 = n("foo");
|
||||
|
||||
float fa[7];
|
||||
double* dp1 = n(fa);
|
||||
}
|
||||
|
||||
enum PromotesToInt {
|
||||
PromotesToIntValue = 1
|
||||
};
|
||||
|
||||
enum PromotesToUnsignedInt {
|
||||
PromotesToUnsignedIntValue = (unsigned int)-1
|
||||
};
|
||||
|
||||
int* o(int);
|
||||
double* o(unsigned int);
|
||||
float* o(long);
|
||||
|
||||
void test_o() {
|
||||
int* ip1 = o(PromotesToIntValue);
|
||||
double* dp1 = o(PromotesToUnsignedIntValue);
|
||||
}
|
||||
|
||||
int* p(int);
|
||||
double* p(double);
|
||||
|
||||
void test_p() {
|
||||
int* ip = p((short)1);
|
||||
double* dp = p(1.0f);
|
||||
}
|
||||
|
||||
struct Bits {
|
||||
signed short int_bitfield : 5;
|
||||
unsigned int uint_bitfield : 8;
|
||||
};
|
||||
|
||||
int* bitfields(int, int);
|
||||
float* bitfields(unsigned int, int);
|
||||
|
||||
void test_bitfield(Bits bits, int x) {
|
||||
int* ip = bitfields(bits.int_bitfield, 0);
|
||||
float* fp = bitfields(bits.uint_bitfield, 0u);
|
||||
}
|
||||
|
||||
int* multiparm(long, int, long); // expected-note {{ candidate function }}
|
||||
float* multiparm(int, int, int); // expected-note {{ candidate function }}
|
||||
double* multiparm(int, int, short); // expected-note {{ candidate function }}
|
||||
|
||||
void test_multiparm(long lv, short sv, int iv) {
|
||||
int* ip1 = multiparm(lv, iv, lv);
|
||||
int* ip2 = multiparm(lv, sv, lv);
|
||||
float* fp1 = multiparm(iv, iv, iv);
|
||||
float* fp2 = multiparm(sv, iv, iv);
|
||||
double* dp1 = multiparm(sv, sv, sv);
|
||||
double* dp2 = multiparm(iv, sv, sv);
|
||||
multiparm(sv, sv, lv); // expected-error {{ call to 'multiparm' is ambiguous; candidates are: }}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
void f();
|
||||
void f(int);
|
||||
void f(int, float);
|
||||
void f(int, int);
|
||||
void f(int, ...);
|
||||
|
||||
typedef float Float;
|
||||
void f(int, Float); // expected-error {{error: previous declaration is here}}
|
||||
|
||||
int f(int, Float); // expected-error {{error: functions that differ only in their return type cannot be overloaded}}
|
||||
|
||||
void g(void); // expected-error {{error: previous declaration is here}}
|
||||
int g(); // expected-error {{error: functions that differ only in their return type cannot be overloaded}}
|
||||
|
||||
class X {
|
||||
void f();
|
||||
void f(int);
|
||||
|
||||
// FIXME: can't test this until we can handle const methods.
|
||||
// void f() const;
|
||||
|
||||
void g(int); // expected-error {{error: previous declaration is here}}
|
||||
void g(int, float); // expected-error {{error: previous declaration is here}}
|
||||
int g(int, Float); // expected-error {{error: functions that differ only in their return type cannot be overloaded}}
|
||||
|
||||
static void g(float);
|
||||
static void g(int); // expected-error {{error: static and non-static member functions with the same parameter types cannot be overloaded}}
|
||||
};
|
Loading…
Reference in New Issue