diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 14f6ade5916f..821bf2d9c3e9 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -1178,7 +1178,8 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S, else { DeclRefExpr *DR = cast(S->getElement()); elementName = DR->getDecl()->getName(); - elementTypeAsString = DR->getDecl()->getType().getAsString(); + elementTypeAsString + = cast(DR->getDecl())->getType().getAsString(); } // struct __objcFastEnumerationState enumState = { 0 }; diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 779f318b5ee0..6ca92df0e590 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -137,7 +137,8 @@ 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, unsigned size_reserve=0); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index a1239deea4a8..fd5ce41495f7 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -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: diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 2ce4956a1d47..ae16d99c8b72 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -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 Functions; + +public: + typedef llvm::SmallVector::iterator function_iterator; + typedef llvm::SmallVector::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 diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index d11c1aa28764..de4f4f75bb1f 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -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); } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index a863e400ae7e..e2ba317d05da 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -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; diff --git a/clang/include/clang/Analysis/Support/ExprDeclBitVector.h b/clang/include/clang/Analysis/Support/ExprDeclBitVector.h index 7b44fd7c6ba1..362ce161ab2e 100644 --- a/clang/include/clang/Analysis/Support/ExprDeclBitVector.h +++ b/clang/include/clang/Analysis/Support/ExprDeclBitVector.h @@ -18,14 +18,14 @@ #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 { class Idx { @@ -49,7 +49,7 @@ struct DeclBitVector_Types { class AnalysisDataTy { public: - typedef llvm::DenseMap DMapTy; + typedef llvm::DenseMap 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++; } diff --git a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h index e24359d4ac34..322070b380a4 100644 --- a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h @@ -37,7 +37,8 @@ class CFGRecStmtDeclVisitor : public CFGRecStmtVisitor { public: void VisitDeclRefExpr(DeclRefExpr* DR) { - for (ScopedDecl* D = DR->getDecl(); D != NULL; D = D->getNextDeclarator()) + for (ScopedDecl* D = dyn_cast(DR->getDecl()); D != NULL; + D = D->getNextDeclarator()) static_cast(this)->VisitScopedDecl(D); } diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 474beeb31cce..352cc91de45c 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -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, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f4266fb90d1d..cbbfe317d5e1 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -182,11 +182,14 @@ 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); LongDoubleComplexTy = getComplexType(LongDoubleTy); - + BuiltinVaListType = QualType(); ObjCIdType = QualType(); IdStructType = 0; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 75d6bc6ce9a7..686aba2460c2 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -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; diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index af89da44cc39..9fd7ff974e91 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -59,3 +59,10 @@ CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD, void *Mem = C.getAllocator().Allocate(); return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl); } + +OverloadedFunctionDecl * +OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id) { + void *Mem = C.getAllocator().Allocate(); + return new (Mem) OverloadedFunctionDecl(DC, Id); +} diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index a0befbdbb085..f2aa3f30276c 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -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" @@ -74,7 +75,11 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) { case Function: 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* 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. //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtSerialization.cpp b/clang/lib/AST/StmtSerialization.cpp index baee03014494..decd9a76c9b2 100644 --- a/clang/lib/AST/StmtSerialization.cpp +++ b/clang/lib/AST/StmtSerialization.cpp @@ -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(D.ReadOwnedPtr(C)); + decl = cast(D.ReadOwnedPtr(C)); return new DeclRefExpr(decl,T,Loc); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 74e52fef88fd..5de44762c39a 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -450,6 +450,7 @@ bool Type::isIntegerType() const { BT->getKind() <= BuiltinType::LongLong; if (const TagType *TT = dyn_cast(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(CanonicalType)) @@ -466,6 +467,7 @@ bool Type::isIntegralType() const { if (const TagType *TT = dyn_cast(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(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 ""; } } diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index b42f210dd83d..2a003335b6ba 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -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(I->first); + NamedDecl* ND = const_cast(I->first); - if (VarDecl* VD = dyn_cast(SD)) { + if (VarDecl* VD = dyn_cast(ND)) { // Punt on static variables for now. if (VD->getStorageClass() == VarDecl::Static) continue; diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 68f10b0d038e..e6780161d7a0 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -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(D)) { diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index f936fff1b9c2..9efcc48c518c 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -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(I->first); + NamedDecl* ND = const_cast(I->first); - if (VarDecl* VD = dyn_cast(SD)) { + if (VarDecl* VD = dyn_cast(ND)) { // Punt on static variables for now. if (VD->getStorageClass() == VarDecl::Static) continue; diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 783bb1c67ad7..5fc513d125c1 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -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(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(E)->getDecl(); + NamedDecl *Decl = cast(E)->getDecl(); if (const FunctionDecl *FD = dyn_cast(Decl)) return CGM.GetAddrOfFunction(FD); if (const VarDecl* VD = dyn_cast(Decl)) { diff --git a/clang/lib/Sema/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp index e97de7381785..8375720e55cd 100644 --- a/clang/lib/Sema/IdentifierResolver.cpp +++ b/clang/lib/Sema/IdentifierResolver.cpp @@ -57,7 +57,9 @@ DeclContext *IdentifierResolver::LookupContext::getContext(Decl *D) { if (EnumConstantDecl *EnumD = dyn_cast(D)) { Ctx = EnumD->getDeclContext()->getParent(); } else if (ScopedDecl *SD = dyn_cast(D)) - Ctx = SD->getDeclContext(); + Ctx = SD->getDeclContext(); + else if (OverloadedFunctionDecl *Ovl = dyn_cast(D)) + Ctx = Ovl->getDeclContext(); else return TUCtx(); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 796ba4ed0416..039571f9fe23 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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" @@ -361,7 +362,46 @@ private: VarDecl *MergeVarDecl(VarDecl *New, Decl *Old); 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); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e32da244de9a..1befc2e2e9a0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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(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(*I) || isa(*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(*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(*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(OldD) && + "Cannot merge with an overloaded function declaration"); + Redeclaration = false; // Verify the old decl was also a function. FunctionDecl *Old = dyn_cast(OldD); @@ -332,17 +374,59 @@ Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, bool &Redeclaration) { Diag(OldD->getLocation(), diag::err_previous_definition); 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(OldQType.getTypePtr())->getResultType(); + QualType NewReturnType + = cast(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(Old); + const CXXMethodDecl* NewMethod = dyn_cast(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(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(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(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(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; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e06761f1ba83..fef205cb11a3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -19,6 +19,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Parse/DeclSpec.h" #include "llvm/Support/Compiler.h" +#include // 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(Decl)) { // C++ [dcl.fct.default]p9 // Default arguments are evaluated each time the function is diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5ff8b0e59fbf..8c63060b6150 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -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(D)) + return new DeclRefExpr(Ovl, Context.OverloadTy, Loc); + ValueDecl *VD = cast(D); // check if referencing an identifier with __attribute__((deprecated)). @@ -1036,16 +1039,67 @@ ActOnCallExpr(ExprTy *fn, SourceLocation LParenLoc, Expr **Args = reinterpret_cast(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(Fn)) + DRExpr = dyn_cast(IcExpr->getSubExpr()); + else + DRExpr = dyn_cast(Fn); + + if (DRExpr) { + FDecl = dyn_cast(DRExpr->getDecl()); + Ovl = dyn_cast(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(Fn)) - if (DeclRefExpr *DRExpr = dyn_cast(IcExpr->getSubExpr())) - FDecl = dyn_cast(DRExpr->getDecl()); - // Make the call expr early, before semantic checks. This guarantees cleanup // of arguments and function on error. llvm::OwningPtr 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(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(E)->getBase()); + NamedDecl *D = getPrimaryDecl(cast(E)->getBase()); + ValueDecl *VD = dyn_cast(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(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 diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp new file mode 100644 index 000000000000..88c209b6e00c --- /dev/null +++ b/clang/lib/Sema/SemaOverload.cpp @@ -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 + +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(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(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(OldQType.getTypePtr()) || + isa(NewQType.getTypePtr())) + return false; + + FunctionTypeProto* OldType = cast(OldQType.getTypePtr()); + FunctionTypeProto* NewType = cast(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(Old); + CXXMethodDecl* NewMethod = dyn_cast(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(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(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 diff --git a/clang/lib/Sema/SemaOverload.h b/clang/lib/Sema/SemaOverload.h new file mode 100644 index 000000000000..8d7ccd2c9533 --- /dev/null +++ b/clang/lib/Sema/SemaOverload.h @@ -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 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 OverloadCandidateSet; +} // end namespace clang + +#endif // LLVM_CLANG_SEMA_OVERLOAD_H diff --git a/clang/test/SemaCXX/overload-call.cpp b/clang/test/SemaCXX/overload-call.cpp new file mode 100644 index 000000000000..311e3d0d3e3e --- /dev/null +++ b/clang/test/SemaCXX/overload-call.cpp @@ -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: }} +} diff --git a/clang/test/SemaCXX/overload-decl.cpp b/clang/test/SemaCXX/overload-decl.cpp new file mode 100644 index 000000000000..872a180e96c6 --- /dev/null +++ b/clang/test/SemaCXX/overload-decl.cpp @@ -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}} +};