/// Collect the visible conversions of a base class. /// /// \param Base a base class of the class we're considering /// \param InVirtual whether this base class is a virtual base (or a base /// of a virtual base) /// \param Access the access along the inheritance path to this base /// \param ParentHiddenTypes the conversions provided by the inheritors /// of this base /// \param Output the set to which to add conversions from non-virtual bases /// \param VOutput the set to which to add conversions from virtual bases /// \param HiddenVBaseCs the set of conversions which were hidden in a /// virtual base along some inheritance path static void CollectVisibleConversions(ASTContext &Context, CXXRecordDecl *Record, bool InVirtual, AccessSpecifier Access, const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes, UnresolvedSetImpl &Output, UnresolvedSetImpl &VOutput, llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) { // The set of types which have conversions in this class or its // subclasses. As an optimization, we don't copy the derived set // unless it might change. const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes; llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer; // Collect the direct conversions and figure out which conversions // will be hidden in the subclasses. UnresolvedSetImpl &Cs = *Record->getConversionFunctions(); if (!Cs.empty()) { HiddenTypesBuffer = ParentHiddenTypes; HiddenTypes = &HiddenTypesBuffer; for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) { bool Hidden = !HiddenTypesBuffer.insert(GetConversionType(Context, I.getDecl())); // If this conversion is hidden and we're in a virtual base, // remember that it's hidden along some inheritance path. if (Hidden && InVirtual) HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())); // If this conversion isn't hidden, add it to the appropriate output. else if (!Hidden) { AccessSpecifier IAccess = CXXRecordDecl::MergeAccess(Access, I.getAccess()); if (InVirtual) VOutput.addDecl(I.getDecl(), IAccess); else Output.addDecl(I.getDecl(), IAccess); } } } // Collect information recursively from any base classes. for (CXXRecordDecl::base_class_iterator I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { const RecordType *RT = I->getType()->getAs<RecordType>(); if (!RT) continue; AccessSpecifier BaseAccess = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier()); bool BaseInVirtual = InVirtual || I->isVirtual(); CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl()); CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess, *HiddenTypes, Output, VOutput, HiddenVBaseCs); } }
/// \brief Figure out if an expression could be turned into a call. /// /// Use this when trying to recover from an error where the programmer may have /// written just the name of a function instead of actually calling it. /// /// \param E - The expression to examine. /// \param ZeroArgCallReturnTy - If the expression can be turned into a call /// with no arguments, this parameter is set to the type returned by such a /// call; otherwise, it is set to an empty QualType. /// \param NonTemplateOverloads - If the expression is an overloaded function /// name, this parameter is populated with the decls of the various overloads. bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads) { ZeroArgCallReturnTy = QualType(); NonTemplateOverloads.clear(); if (const OverloadExpr *Overloads = dyn_cast<OverloadExpr>(&E)) { for (OverloadExpr::decls_iterator it = Overloads->decls_begin(), DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) { // Our overload set may include TemplateDecls, which we'll ignore for our // present purpose. if (const FunctionDecl *OverloadDecl = dyn_cast<FunctionDecl>(*it)) { NonTemplateOverloads.addDecl(*it); if (OverloadDecl->getMinRequiredArguments() == 0) ZeroArgCallReturnTy = OverloadDecl->getResultType(); } } return true; } if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(&E)) { if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) { if (Fun->getMinRequiredArguments() == 0) ZeroArgCallReturnTy = Fun->getResultType(); return true; } } // We don't have an expression that's convenient to get a FunctionDecl from, // but we can at least check if the type is "function of 0 arguments". QualType ExprTy = E.getType(); const FunctionType *FunTy = NULL; QualType PointeeTy = ExprTy->getPointeeType(); if (!PointeeTy.isNull()) FunTy = PointeeTy->getAs<FunctionType>(); if (!FunTy) FunTy = ExprTy->getAs<FunctionType>(); if (!FunTy && ExprTy == Context.BoundMemberTy) { // Look for the bound-member type. If it's still overloaded, give up, // although we probably should have fallen into the OverloadExpr case above // if we actually have an overloaded bound member. QualType BoundMemberTy = Expr::findBoundMemberType(&E); if (!BoundMemberTy.isNull()) FunTy = BoundMemberTy->castAs<FunctionType>(); } if (const FunctionProtoType *FPT = dyn_cast_or_null<FunctionProtoType>(FunTy)) { if (FPT->getNumArgs() == 0) ZeroArgCallReturnTy = FunTy->getResultType(); return true; } return false; }
/// Collect the visible conversions of a class. /// /// This would be extremely straightforward if it weren't for virtual /// bases. It might be worth special-casing that, really. static void CollectVisibleConversions(ASTContext &Context, CXXRecordDecl *Record, UnresolvedSetImpl &Output) { // The collection of all conversions in virtual bases that we've // found. These will be added to the output as long as they don't // appear in the hidden-conversions set. UnresolvedSet<8> VBaseCs; // The set of conversions in virtual bases that we've determined to // be hidden. llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs; // The set of types hidden by classes derived from this one. llvm::SmallPtrSet<CanQualType, 8> HiddenTypes; // Go ahead and collect the direct conversions and add them to the // hidden-types set. UnresolvedSetImpl &Cs = *Record->getConversionFunctions(); Output.append(Cs.begin(), Cs.end()); for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) HiddenTypes.insert(GetConversionType(Context, I.getDecl())); // Recursively collect conversions from base classes. for (CXXRecordDecl::base_class_iterator I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { const RecordType *RT = I->getType()->getAs<RecordType>(); if (!RT) continue; CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()), I->isVirtual(), I->getAccessSpecifier(), HiddenTypes, Output, VBaseCs, HiddenVBaseCs); } // Add any unhidden conversions provided by virtual bases. for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end(); I != E; ++I) { if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()))) Output.addDecl(I.getDecl(), I.getAccess()); } }
/// \brief Figure out if an expression could be turned into a call. /// /// Use this when trying to recover from an error where the programmer may have /// written just the name of a function instead of actually calling it. /// /// \param E - The expression to examine. /// \param ZeroArgCallReturnTy - If the expression can be turned into a call /// with no arguments, this parameter is set to the type returned by such a /// call; otherwise, it is set to an empty QualType. /// \param OverloadSet - If the expression is an overloaded function /// name, this parameter is populated with the decls of the various overloads. bool Sema::isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &OverloadSet) { ZeroArgCallReturnTy = QualType(); OverloadSet.clear(); if (E.getType() == Context.OverloadTy) { OverloadExpr::FindResult FR = OverloadExpr::find(const_cast<Expr*>(&E)); const OverloadExpr *Overloads = FR.Expression; for (OverloadExpr::decls_iterator it = Overloads->decls_begin(), DeclsEnd = Overloads->decls_end(); it != DeclsEnd; ++it) { OverloadSet.addDecl(*it); // Check whether the function is a non-template which takes no // arguments. if (const FunctionDecl *OverloadDecl = dyn_cast<FunctionDecl>((*it)->getUnderlyingDecl())) { if (OverloadDecl->getMinRequiredArguments() == 0) ZeroArgCallReturnTy = OverloadDecl->getResultType(); } } // Ignore overloads that are pointer-to-member constants. if (FR.HasFormOfMemberPointer) return false; return true; } if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) { if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) { if (Fun->getMinRequiredArguments() == 0) ZeroArgCallReturnTy = Fun->getResultType(); return true; } } // We don't have an expression that's convenient to get a FunctionDecl from, // but we can at least check if the type is "function of 0 arguments". QualType ExprTy = E.getType(); const FunctionType *FunTy = NULL; QualType PointeeTy = ExprTy->getPointeeType(); if (!PointeeTy.isNull()) FunTy = PointeeTy->getAs<FunctionType>(); if (!FunTy) FunTy = ExprTy->getAs<FunctionType>(); if (!FunTy && ExprTy == Context.BoundMemberTy) { // Look for the bound-member type. If it's still overloaded, give up, // although we probably should have fallen into the OverloadExpr case above // if we actually have an overloaded bound member. QualType BoundMemberTy = Expr::findBoundMemberType(&E); if (!BoundMemberTy.isNull()) FunTy = BoundMemberTy->castAs<FunctionType>(); } if (const FunctionProtoType *FPT = dyn_cast_or_null<FunctionProtoType>(FunTy)) { if (FPT->getNumArgs() == 0) ZeroArgCallReturnTy = FunTy->getResultType(); return true; } return false; }