forked from OSchip/llvm-project
"Incremental" progress on using expressions, by which I mean totally ripping
into pretty much everything about overload resolution in order to wean BuildDeclarationNameExpr off LookupResult::getAsSingleDecl(). Replace UnresolvedFunctionNameExpr with UnresolvedLookupExpr, which generalizes the idea of a non-member lookup that we haven't totally resolved yet, whether by overloading, argument-dependent lookup, or (eventually) the presence of a function template in the lookup results. Incidentally fixes a problem with argument-dependent lookup where we were still performing ADL even when the lookup results contained something from a block scope. Incidentally improves a diagnostic when using an ObjC ivar from a class method. This just fell out from rewriting BuildDeclarationNameExpr's interaction with lookup, and I'm too apathetic to break it out. The only remaining uses of OverloadedFunctionDecl that I know of are in TemplateName and MemberExpr. llvm-svn: 89544
This commit is contained in:
parent
96d5c76498
commit
d14a86427f
|
@ -88,6 +88,28 @@ namespace llvm {
|
|||
|
||||
namespace clang {
|
||||
|
||||
/// UnresolvedSet - A set of unresolved declarations.
|
||||
class UnresolvedSet {
|
||||
typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
|
||||
DeclsTy Decls;
|
||||
|
||||
public:
|
||||
void addDecl(NamedDecl *D) {
|
||||
Decls.push_back(D);
|
||||
}
|
||||
|
||||
bool replace(const NamedDecl* Old, NamedDecl *New) {
|
||||
for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
|
||||
if (*I == Old)
|
||||
return (*I = New, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef DeclsTy::const_iterator iterator;
|
||||
iterator begin() const { return Decls.begin(); }
|
||||
iterator end() const { return Decls.end(); }
|
||||
};
|
||||
|
||||
/// 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.
|
||||
|
@ -376,13 +398,13 @@ class CXXRecordDecl : public RecordDecl {
|
|||
/// of this C++ class (but not its inherited conversion
|
||||
/// functions). Each of the entries in this overload set is a
|
||||
/// CXXConversionDecl.
|
||||
OverloadedFunctionDecl Conversions;
|
||||
UnresolvedSet Conversions;
|
||||
|
||||
/// VisibleConversions - Overload set containing the conversion functions
|
||||
/// of this C++ class and all those inherited conversion functions that
|
||||
/// are visible in this class. Each of the entries in this overload set is
|
||||
/// a CXXConversionDecl or a FunctionTemplateDecl.
|
||||
OverloadedFunctionDecl VisibleConversions;
|
||||
UnresolvedSet VisibleConversions;
|
||||
|
||||
/// \brief The template or declaration that this declaration
|
||||
/// describes or was instantiated from, respectively.
|
||||
|
@ -400,7 +422,7 @@ class CXXRecordDecl : public RecordDecl {
|
|||
const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet,
|
||||
const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes);
|
||||
void collectConversionFunctions(
|
||||
llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet);
|
||||
llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const;
|
||||
|
||||
protected:
|
||||
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
|
||||
|
@ -581,22 +603,34 @@ public:
|
|||
|
||||
/// getConversions - Retrieve the overload set containing all of the
|
||||
/// conversion functions in this class.
|
||||
OverloadedFunctionDecl *getConversionFunctions() {
|
||||
UnresolvedSet *getConversionFunctions() {
|
||||
assert((this->isDefinition() ||
|
||||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
|
||||
"getConversionFunctions() called on incomplete type");
|
||||
return &Conversions;
|
||||
}
|
||||
const OverloadedFunctionDecl *getConversionFunctions() const {
|
||||
const UnresolvedSet *getConversionFunctions() const {
|
||||
assert((this->isDefinition() ||
|
||||
cast<RecordType>(getTypeForDecl())->isBeingDefined()) &&
|
||||
"getConversionFunctions() called on incomplete type");
|
||||
return &Conversions;
|
||||
}
|
||||
|
||||
typedef UnresolvedSet::iterator conversion_iterator;
|
||||
conversion_iterator conversion_begin() const { return Conversions.begin(); }
|
||||
conversion_iterator conversion_end() const { return Conversions.end(); }
|
||||
|
||||
/// Replaces a conversion function with a new declaration.
|
||||
///
|
||||
/// Returns true if the old conversion was found.
|
||||
bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
|
||||
return Conversions.replace(Old, New);
|
||||
}
|
||||
|
||||
/// getVisibleConversionFunctions - get all conversion functions visible
|
||||
/// in current class; including conversion function templates.
|
||||
OverloadedFunctionDecl *getVisibleConversionFunctions();
|
||||
const UnresolvedSet *getVisibleConversionFunctions();
|
||||
|
||||
/// addVisibleConversionFunction - Add a new conversion function to the
|
||||
/// list of visible conversion functions.
|
||||
void addVisibleConversionFunction(CXXConversionDecl *ConvDecl);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "clang/Basic/TypeTraits.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
|
@ -975,52 +976,6 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// \brief Represents the name of a function that has not been
|
||||
/// resolved to any declaration.
|
||||
///
|
||||
/// Unresolved function names occur when a function name is
|
||||
/// encountered prior to an open parentheses ('(') in a C++ function
|
||||
/// call, and the function name itself did not resolve to a
|
||||
/// declaration. These function names can only be resolved when they
|
||||
/// form the postfix-expression of a function call, so that
|
||||
/// argument-dependent lookup finds declarations corresponding to
|
||||
/// these functions.
|
||||
|
||||
/// @code
|
||||
/// template<typename T> void f(T x) {
|
||||
/// g(x); // g is an unresolved function name (that is also a dependent name)
|
||||
/// }
|
||||
/// @endcode
|
||||
class UnresolvedFunctionNameExpr : public Expr {
|
||||
/// The name that was present in the source
|
||||
DeclarationName Name;
|
||||
|
||||
/// The location of this name in the source code
|
||||
SourceLocation Loc;
|
||||
|
||||
public:
|
||||
UnresolvedFunctionNameExpr(DeclarationName N, QualType T, SourceLocation L)
|
||||
: Expr(UnresolvedFunctionNameExprClass, T, false, false), Name(N), Loc(L) { }
|
||||
|
||||
/// \brief Retrieves the name that occurred in the source code.
|
||||
DeclarationName getName() const { return Name; }
|
||||
|
||||
/// getLocation - Retrieves the location in the source code where
|
||||
/// the name occurred.
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
|
||||
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == UnresolvedFunctionNameExprClass;
|
||||
}
|
||||
static bool classof(const UnresolvedFunctionNameExpr *) { return true; }
|
||||
|
||||
// Iterators
|
||||
virtual child_iterator child_begin();
|
||||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// UnaryTypeTraitExpr - A GCC or MS unary type trait, as used in the
|
||||
/// implementation of TR1/C++0x type trait templates.
|
||||
/// Example:
|
||||
|
@ -1063,10 +1018,101 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// \brief A reference to a name which we were able to look up during
|
||||
/// parsing but could not resolve to a specific declaration. This
|
||||
/// arises in several ways:
|
||||
/// * we might be waiting for argument-dependent lookup
|
||||
/// * the name might resolve to an overloaded function
|
||||
/// and eventually:
|
||||
/// * the lookup might have included a function template
|
||||
/// These never include UnresolvedUsingValueDecls, which are always
|
||||
/// class members and therefore appear only in
|
||||
/// UnresolvedMemberLookupExprs.
|
||||
class UnresolvedLookupExpr : public Expr {
|
||||
/// The results. These are undesugared, which is to say, they may
|
||||
/// include UsingShadowDecls.
|
||||
UnresolvedSet Results;
|
||||
|
||||
/// The name declared.
|
||||
DeclarationName Name;
|
||||
|
||||
/// The qualifier given, if any.
|
||||
NestedNameSpecifier *Qualifier;
|
||||
|
||||
/// The source range of the nested name specifier.
|
||||
SourceRange QualifierRange;
|
||||
|
||||
/// The location of the name.
|
||||
SourceLocation NameLoc;
|
||||
|
||||
/// True if these lookup results should be extended by
|
||||
/// argument-dependent lookup if this is the operand of a function
|
||||
/// call.
|
||||
bool RequiresADL;
|
||||
|
||||
UnresolvedLookupExpr(QualType T,
|
||||
NestedNameSpecifier *Qualifier, SourceRange QRange,
|
||||
DeclarationName Name, SourceLocation NameLoc,
|
||||
bool RequiresADL)
|
||||
: Expr(UnresolvedLookupExprClass, T, false, false),
|
||||
Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
|
||||
NameLoc(NameLoc), RequiresADL(RequiresADL)
|
||||
{}
|
||||
|
||||
public:
|
||||
static UnresolvedLookupExpr *Create(ASTContext &C,
|
||||
NestedNameSpecifier *Qualifier,
|
||||
SourceRange QualifierRange,
|
||||
DeclarationName Name,
|
||||
SourceLocation NameLoc,
|
||||
bool ADL) {
|
||||
return new(C) UnresolvedLookupExpr(C.OverloadTy, Qualifier, QualifierRange,
|
||||
Name, NameLoc, ADL);
|
||||
}
|
||||
|
||||
void addDecl(NamedDecl *Decl) {
|
||||
Results.addDecl(Decl);
|
||||
}
|
||||
|
||||
typedef UnresolvedSet::iterator decls_iterator;
|
||||
decls_iterator decls_begin() const { return Results.begin(); }
|
||||
decls_iterator decls_end() const { return Results.end(); }
|
||||
|
||||
/// True if this declaration should be extended by
|
||||
/// argument-dependent lookup.
|
||||
bool requiresADL() const { return RequiresADL; }
|
||||
|
||||
/// Fetches the name looked up.
|
||||
DeclarationName getName() const { return Name; }
|
||||
|
||||
/// Gets the location of the name.
|
||||
SourceLocation getNameLoc() const { return NameLoc; }
|
||||
|
||||
/// Fetches the nested-name qualifier, if one was given.
|
||||
NestedNameSpecifier *getQualifier() const { return Qualifier; }
|
||||
|
||||
/// Fetches the range of the nested-name qualifier.
|
||||
SourceRange getQualifierRange() const { return QualifierRange; }
|
||||
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
if (Qualifier) return SourceRange(QualifierRange.getBegin(), NameLoc);
|
||||
return SourceRange(NameLoc, NameLoc);
|
||||
}
|
||||
|
||||
virtual StmtIterator child_begin();
|
||||
virtual StmtIterator child_end();
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == UnresolvedLookupExprClass;
|
||||
}
|
||||
static bool classof(const UnresolvedLookupExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// \brief A qualified reference to a name whose declaration cannot
|
||||
/// yet be resolved.
|
||||
///
|
||||
/// DependentScopeDeclRefExpr is similar to eclRefExpr in that
|
||||
/// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
|
||||
/// it expresses a reference to a declaration such as
|
||||
/// X<T>::value. The difference, however, is that an
|
||||
/// DependentScopeDeclRefExpr node is used only within C++ templates when
|
||||
|
@ -1377,9 +1423,9 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ member access expression where the actual member
|
||||
/// referenced could not be resolved, e.g., because the base expression or the
|
||||
/// member name was dependent.
|
||||
/// \brief Represents a C++ member access expression where the actual
|
||||
/// member referenced could not be resolved because the base
|
||||
/// expression or the member name was dependent.
|
||||
class CXXDependentScopeMemberExpr : public Expr {
|
||||
/// \brief The expression for the base pointer or class reference,
|
||||
/// e.g., the \c x in x.f.
|
||||
|
|
|
@ -125,7 +125,7 @@ EXPR(CXXConditionDeclExpr , DeclRefExpr)
|
|||
EXPR(CXXNewExpr , Expr)
|
||||
EXPR(CXXDeleteExpr , Expr)
|
||||
EXPR(CXXPseudoDestructorExpr, Expr)
|
||||
EXPR(UnresolvedFunctionNameExpr , Expr)
|
||||
EXPR(UnresolvedLookupExpr , Expr)
|
||||
EXPR(UnaryTypeTraitExpr , Expr)
|
||||
EXPR(DependentScopeDeclRefExpr , Expr)
|
||||
EXPR(TemplateIdRefExpr , Expr)
|
||||
|
|
|
@ -36,8 +36,6 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
|
|||
HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
|
||||
HasTrivialDestructor(true), ComputedVisibleConversions(false),
|
||||
Bases(0), NumBases(0), VBases(0), NumVBases(0),
|
||||
Conversions(DC, DeclarationName()),
|
||||
VisibleConversions(DC, DeclarationName()),
|
||||
TemplateOrInstantiation() { }
|
||||
|
||||
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
|
||||
|
@ -299,14 +297,11 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
|
|||
|
||||
void
|
||||
CXXRecordDecl::collectConversionFunctions(
|
||||
llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet)
|
||||
llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const
|
||||
{
|
||||
OverloadedFunctionDecl *TopConversions = getConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator
|
||||
TFunc = TopConversions->function_begin(),
|
||||
TFuncEnd = TopConversions->function_end();
|
||||
TFunc != TFuncEnd; ++TFunc) {
|
||||
NamedDecl *TopConv = TFunc->get();
|
||||
const UnresolvedSet *Cs = getConversionFunctions();
|
||||
for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
|
||||
NamedDecl *TopConv = *I;
|
||||
CanQualType TConvType;
|
||||
if (FunctionTemplateDecl *TConversionTemplate =
|
||||
dyn_cast<FunctionTemplateDecl>(TopConv))
|
||||
|
@ -336,14 +331,11 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
|
|||
bool inTopClass = (RD == this);
|
||||
QualType ClassType = getASTContext().getTypeDeclType(this);
|
||||
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
|
||||
OverloadedFunctionDecl *Conversions
|
||||
const UnresolvedSet *Cs
|
||||
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
|
||||
|
||||
for (OverloadedFunctionDecl::function_iterator
|
||||
Func = Conversions->function_begin(),
|
||||
FuncEnd = Conversions->function_end();
|
||||
Func != FuncEnd; ++Func) {
|
||||
NamedDecl *Conv = Func->get();
|
||||
for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
|
||||
NamedDecl *Conv = *I;
|
||||
// Only those conversions not exact match of conversions in current
|
||||
// class are candidateconversion routines.
|
||||
CanQualType ConvType;
|
||||
|
@ -405,8 +397,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
|
|||
|
||||
/// getVisibleConversionFunctions - get all conversion functions visible
|
||||
/// in current class; including conversion function templates.
|
||||
OverloadedFunctionDecl *
|
||||
CXXRecordDecl::getVisibleConversionFunctions() {
|
||||
const UnresolvedSet *CXXRecordDecl::getVisibleConversionFunctions() {
|
||||
// If root class, all conversions are visible.
|
||||
if (bases_begin() == bases_end())
|
||||
return &Conversions;
|
||||
|
@ -425,26 +416,26 @@ void CXXRecordDecl::addVisibleConversionFunction(
|
|||
CXXConversionDecl *ConvDecl) {
|
||||
assert(!ConvDecl->getDescribedFunctionTemplate() &&
|
||||
"Conversion function templates should cast to FunctionTemplateDecl.");
|
||||
VisibleConversions.addOverload(ConvDecl);
|
||||
VisibleConversions.addDecl(ConvDecl);
|
||||
}
|
||||
|
||||
void CXXRecordDecl::addVisibleConversionFunction(
|
||||
FunctionTemplateDecl *ConvDecl) {
|
||||
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
|
||||
"Function template is not a conversion function template");
|
||||
VisibleConversions.addOverload(ConvDecl);
|
||||
VisibleConversions.addDecl(ConvDecl);
|
||||
}
|
||||
|
||||
void CXXRecordDecl::addConversionFunction(CXXConversionDecl *ConvDecl) {
|
||||
assert(!ConvDecl->getDescribedFunctionTemplate() &&
|
||||
"Conversion function templates should cast to FunctionTemplateDecl.");
|
||||
Conversions.addOverload(ConvDecl);
|
||||
Conversions.addDecl(ConvDecl);
|
||||
}
|
||||
|
||||
void CXXRecordDecl::addConversionFunction(FunctionTemplateDecl *ConvDecl) {
|
||||
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
|
||||
"Function template is not a conversion function template");
|
||||
Conversions.addOverload(ConvDecl);
|
||||
Conversions.addDecl(ConvDecl);
|
||||
}
|
||||
|
||||
CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
|
||||
|
|
|
@ -46,6 +46,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
|
|||
(HasExplicitTemplateArgumentList?
|
||||
HasExplicitTemplateArgumentListFlag : 0)),
|
||||
Loc(NameLoc) {
|
||||
assert(!isa<OverloadedFunctionDecl>(D));
|
||||
if (Qualifier) {
|
||||
NameQualifier *NQ = getNameQualifier();
|
||||
NQ->NNS = Qualifier;
|
||||
|
@ -1096,6 +1097,8 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {
|
|||
return LV_Valid;
|
||||
case PredefinedExprClass:
|
||||
return LV_Valid;
|
||||
case UnresolvedLookupExprClass:
|
||||
return LV_Valid;
|
||||
case CXXDefaultArgExprClass:
|
||||
return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx);
|
||||
case CXXConditionDeclExprClass:
|
||||
|
@ -1500,7 +1503,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
|
|||
case Expr::CXXNewExprClass:
|
||||
case Expr::CXXDeleteExprClass:
|
||||
case Expr::CXXPseudoDestructorExprClass:
|
||||
case Expr::UnresolvedFunctionNameExprClass:
|
||||
case Expr::UnresolvedLookupExprClass:
|
||||
case Expr::DependentScopeDeclRefExprClass:
|
||||
case Expr::TemplateIdRefExprClass:
|
||||
case Expr::CXXConstructExprClass:
|
||||
|
|
|
@ -121,11 +121,11 @@ Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
|
|||
return &Base + 1;
|
||||
}
|
||||
|
||||
// UnresolvedFunctionNameExpr
|
||||
Stmt::child_iterator UnresolvedFunctionNameExpr::child_begin() {
|
||||
// UnresolvedLookupExpr
|
||||
Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
|
||||
return child_iterator();
|
||||
}
|
||||
Stmt::child_iterator UnresolvedFunctionNameExpr::child_end() {
|
||||
Stmt::child_iterator UnresolvedLookupExpr::child_end() {
|
||||
return child_iterator();
|
||||
}
|
||||
// UnaryTypeTraitExpr
|
||||
|
|
|
@ -489,6 +489,10 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr(
|
|||
OS << Node->getDeclName().getAsString();
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
|
||||
OS << Node->getName().getAsString();
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
|
||||
if (Node->getQualifier())
|
||||
Node->getQualifier()->print(OS, Policy);
|
||||
|
@ -1119,10 +1123,6 @@ void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
|||
OS << TypeS;
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *E) {
|
||||
OS << E->getName().getAsString();
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
||||
// Nothing to print.
|
||||
}
|
||||
|
|
|
@ -515,7 +515,7 @@ void StmtProfiler::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *S) {
|
|||
}
|
||||
|
||||
void
|
||||
StmtProfiler::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *S) {
|
||||
StmtProfiler::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *S) {
|
||||
VisitExpr(S);
|
||||
VisitName(S->getName());
|
||||
}
|
||||
|
|
|
@ -280,6 +280,12 @@ public:
|
|||
/// ambiguous and overloaded lookups.
|
||||
NamedDecl *getAsSingleDecl(ASTContext &Context) const;
|
||||
|
||||
template <class DeclClass>
|
||||
DeclClass *getAsSingle() const {
|
||||
if (getResultKind() != Found) return 0;
|
||||
return dyn_cast<DeclClass>(getFoundDecl());
|
||||
}
|
||||
|
||||
/// \brief Fetch the unique decl found by this lookup. Asserts
|
||||
/// that one was found.
|
||||
///
|
||||
|
|
|
@ -959,7 +959,7 @@ public:
|
|||
bool Complain);
|
||||
Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
|
||||
|
||||
void AddOverloadedCallCandidates(NamedDecl *Callee,
|
||||
void AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*>& Callees,
|
||||
DeclarationName &UnqualifiedName,
|
||||
bool &ArgumentDependentLookup,
|
||||
bool HasExplicitTemplateArgs,
|
||||
|
@ -969,7 +969,8 @@ public:
|
|||
OverloadCandidateSet &CandidateSet,
|
||||
bool PartialOverloading = false);
|
||||
|
||||
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
|
||||
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn,
|
||||
llvm::SmallVectorImpl<NamedDecl*> &Fns,
|
||||
DeclarationName UnqualifiedName,
|
||||
bool HasExplicitTemplateArgs,
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs,
|
||||
|
@ -1415,10 +1416,18 @@ public:
|
|||
bool HasTrailingLParen,
|
||||
const CXXScopeSpec *SS,
|
||||
bool isAddressOfOperand = false);
|
||||
OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
|
||||
bool HasTrailingLParen,
|
||||
const CXXScopeSpec *SS,
|
||||
OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
|
||||
LookupResult &R, bool ADL,
|
||||
bool isAddressOfOperand);
|
||||
OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
|
||||
SourceLocation Loc,
|
||||
DeclarationName Name,
|
||||
bool NeedsADL,
|
||||
NamedDecl * const *Decls,
|
||||
unsigned NumDecls);
|
||||
OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
|
||||
SourceLocation Loc,
|
||||
NamedDecl *D);
|
||||
|
||||
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
|
||||
tok::TokenKind Kind);
|
||||
|
@ -1517,7 +1526,7 @@ public:
|
|||
SourceLocation RParenLoc);
|
||||
|
||||
void DeconstructCallFunction(Expr *FnExpr,
|
||||
NamedDecl *&Function,
|
||||
llvm::SmallVectorImpl<NamedDecl*>& Fns,
|
||||
DeclarationName &Name,
|
||||
NestedNameSpecifier *&Qualifier,
|
||||
SourceRange &QualifierRange,
|
||||
|
|
|
@ -1467,7 +1467,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
|
|||
Expr::hasAnyTypeDependentArguments(Args, NumArgs))
|
||||
return;
|
||||
|
||||
NamedDecl *Function;
|
||||
llvm::SmallVector<NamedDecl*,8> Fns;
|
||||
DeclarationName UnqualifiedName;
|
||||
NestedNameSpecifier *Qualifier;
|
||||
SourceRange QualifierRange;
|
||||
|
@ -1476,8 +1476,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
|
|||
const TemplateArgumentLoc *ExplicitTemplateArgs;
|
||||
unsigned NumExplicitTemplateArgs;
|
||||
|
||||
DeconstructCallFunction(Fn,
|
||||
Function, UnqualifiedName, Qualifier, QualifierRange,
|
||||
DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
|
||||
ArgumentDependentLookup, HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs, NumExplicitTemplateArgs);
|
||||
|
||||
|
@ -1488,7 +1487,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
|
|||
|
||||
// Build an overload candidate set based on the functions we find.
|
||||
OverloadCandidateSet CandidateSet;
|
||||
AddOverloadedCallCandidates(Function, UnqualifiedName,
|
||||
AddOverloadedCallCandidates(Fns, UnqualifiedName,
|
||||
ArgumentDependentLookup, HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs, NumExplicitTemplateArgs,
|
||||
Args, NumArgs,
|
||||
|
|
|
@ -2601,16 +2601,8 @@ Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
|
|||
if (FunctionTemplateDecl *ConversionTemplate
|
||||
= Conversion->getDescribedFunctionTemplate())
|
||||
ExpectedPrevDecl = ConversionTemplate->getPreviousDeclaration();
|
||||
OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator
|
||||
Conv = Conversions->function_begin(),
|
||||
ConvEnd = Conversions->function_end();
|
||||
Conv != ConvEnd; ++Conv) {
|
||||
if (*Conv == ExpectedPrevDecl) {
|
||||
*Conv = Conversion;
|
||||
return DeclPtrTy::make(Conversion);
|
||||
}
|
||||
}
|
||||
if (ClassDecl->replaceConversion(ExpectedPrevDecl, Conversion))
|
||||
return DeclPtrTy::make(Conversion);
|
||||
assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
|
||||
} else if (FunctionTemplateDecl *ConversionTemplate
|
||||
= Conversion->getDescribedFunctionTemplate())
|
||||
|
@ -3895,18 +3887,17 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
= dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
|
||||
|
||||
OverloadCandidateSet CandidateSet;
|
||||
OverloadedFunctionDecl *Conversions
|
||||
const UnresolvedSet *Conversions
|
||||
= T2RecordDecl->getVisibleConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator Func
|
||||
= Conversions->function_begin();
|
||||
Func != Conversions->function_end(); ++Func) {
|
||||
for (UnresolvedSet::iterator I = Conversions->begin(),
|
||||
E = Conversions->end(); I != E; ++I) {
|
||||
FunctionTemplateDecl *ConvTemplate
|
||||
= dyn_cast<FunctionTemplateDecl>(*Func);
|
||||
= dyn_cast<FunctionTemplateDecl>(*I);
|
||||
CXXConversionDecl *Conv;
|
||||
if (ConvTemplate)
|
||||
Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
|
||||
else
|
||||
Conv = cast<CXXConversionDecl>(*Func);
|
||||
Conv = cast<CXXConversionDecl>(*I);
|
||||
|
||||
// If the conversion function doesn't return a reference type,
|
||||
// it can't be considered for this conversion.
|
||||
|
|
|
@ -417,6 +417,8 @@ Sema::OwningExprResult
|
|||
Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
|
||||
bool TypeDependent, bool ValueDependent,
|
||||
const CXXScopeSpec *SS) {
|
||||
assert(!isa<OverloadedFunctionDecl>(D));
|
||||
|
||||
if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
|
||||
Diag(Loc,
|
||||
diag::err_auto_variable_cannot_appear_in_own_initializer)
|
||||
|
@ -688,8 +690,6 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
if (Lookup.isAmbiguous())
|
||||
return ExprError();
|
||||
|
||||
NamedDecl *D = Lookup.getAsSingleDecl(Context);
|
||||
|
||||
// If this reference is in an Objective-C method, then ivar lookup happens as
|
||||
// well.
|
||||
IdentifierInfo *II = Name.getAsIdentifierInfo();
|
||||
|
@ -699,44 +699,58 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
// found a decl, but that decl is outside the current instance method (i.e.
|
||||
// a global variable). In these two cases, we do a lookup for an ivar with
|
||||
// this name, if the lookup sucedes, we replace it our current decl.
|
||||
if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
|
||||
|
||||
// FIXME: we should change lookup to do this.
|
||||
|
||||
// If we're in a class method, we don't normally want to look for
|
||||
// ivars. But if we don't find anything else, and there's an
|
||||
// ivar, that's an error.
|
||||
bool IsClassMethod = getCurMethodDecl()->isClassMethod();
|
||||
|
||||
bool LookForIvars;
|
||||
if (Lookup.empty())
|
||||
LookForIvars = true;
|
||||
else if (IsClassMethod)
|
||||
LookForIvars = false;
|
||||
else
|
||||
LookForIvars = (Lookup.isSingleResult() &&
|
||||
Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
|
||||
|
||||
if (LookForIvars) {
|
||||
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
|
||||
ObjCInterfaceDecl *ClassDeclared;
|
||||
if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
|
||||
// Check if referencing a field with __attribute__((deprecated)).
|
||||
if (DiagnoseUseOfDecl(IV, Loc))
|
||||
return ExprError();
|
||||
// Diagnose using an ivar in a class method.
|
||||
if (IsClassMethod)
|
||||
return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
|
||||
<< IV->getDeclName());
|
||||
|
||||
// If we're referencing an invalid decl, just return this as a silent
|
||||
// error node. The error diagnostic was already emitted on the decl.
|
||||
if (IV->isInvalidDecl())
|
||||
return ExprError();
|
||||
|
||||
bool IsClsMethod = getCurMethodDecl()->isClassMethod();
|
||||
// If a class method attemps to use a free standing ivar, this is
|
||||
// an error.
|
||||
if (IsClsMethod && D && !D->isDefinedOutsideFunctionOrMethod())
|
||||
return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
|
||||
<< IV->getDeclName());
|
||||
// If a class method uses a global variable, even if an ivar with
|
||||
// same name exists, use the global.
|
||||
if (!IsClsMethod) {
|
||||
if (IV->getAccessControl() == ObjCIvarDecl::Private &&
|
||||
ClassDeclared != IFace)
|
||||
Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
|
||||
// FIXME: This should use a new expr for a direct reference, don't
|
||||
// turn this into Self->ivar, just return a BareIVarExpr or something.
|
||||
IdentifierInfo &II = Context.Idents.get("self");
|
||||
UnqualifiedId SelfName;
|
||||
SelfName.setIdentifier(&II, SourceLocation());
|
||||
CXXScopeSpec SelfScopeSpec;
|
||||
OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
|
||||
SelfName, false, false);
|
||||
MarkDeclarationReferenced(Loc, IV);
|
||||
return Owned(new (Context)
|
||||
ObjCIvarRefExpr(IV, IV->getType(), Loc,
|
||||
SelfExpr.takeAs<Expr>(), true, true));
|
||||
}
|
||||
// Check if referencing a field with __attribute__((deprecated)).
|
||||
if (DiagnoseUseOfDecl(IV, Loc))
|
||||
return ExprError();
|
||||
|
||||
// Diagnose the use of an ivar outside of the declaring class.
|
||||
if (IV->getAccessControl() == ObjCIvarDecl::Private &&
|
||||
ClassDeclared != IFace)
|
||||
Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
|
||||
|
||||
// FIXME: This should use a new expr for a direct reference, don't
|
||||
// turn this into Self->ivar, just return a BareIVarExpr or something.
|
||||
IdentifierInfo &II = Context.Idents.get("self");
|
||||
UnqualifiedId SelfName;
|
||||
SelfName.setIdentifier(&II, SourceLocation());
|
||||
CXXScopeSpec SelfScopeSpec;
|
||||
OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
|
||||
SelfName, false, false);
|
||||
MarkDeclarationReferenced(Loc, IV);
|
||||
return Owned(new (Context)
|
||||
ObjCIvarRefExpr(IV, IV->getType(), Loc,
|
||||
SelfExpr.takeAs<Expr>(), true, true));
|
||||
}
|
||||
} else if (getCurMethodDecl()->isInstanceMethod()) {
|
||||
// We should warn if a local variable hides an ivar.
|
||||
|
@ -749,7 +763,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
}
|
||||
}
|
||||
// Needed to implement property "super.method" notation.
|
||||
if (D == 0 && II->isStr("super")) {
|
||||
if (Lookup.empty() && II->isStr("super")) {
|
||||
QualType T;
|
||||
|
||||
if (getCurMethodDecl()->isInstanceMethod())
|
||||
|
@ -766,26 +780,14 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
|
||||
HasTrailingLParen;
|
||||
|
||||
if (ADL && D == 0) {
|
||||
// We've seen something of the form
|
||||
//
|
||||
// identifier(
|
||||
//
|
||||
// and we did not find any entity by the name
|
||||
// "identifier". However, this identifier is still subject to
|
||||
// argument-dependent lookup, so keep track of the name.
|
||||
return Owned(new (Context) UnresolvedFunctionNameExpr(Name,
|
||||
Context.OverloadTy,
|
||||
Loc));
|
||||
}
|
||||
|
||||
if (D == 0) {
|
||||
if (Lookup.empty() && !ADL) {
|
||||
// Otherwise, this could be an implicitly declared function reference (legal
|
||||
// in C90, extension in C99).
|
||||
if (HasTrailingLParen && II &&
|
||||
!getLangOptions().CPlusPlus) // Not in C++.
|
||||
D = ImplicitlyDefineFunction(Loc, *II, S);
|
||||
else {
|
||||
!getLangOptions().CPlusPlus) { // Not in C++.
|
||||
NamedDecl *D = ImplicitlyDefineFunction(Loc, *II, S);
|
||||
if (D) Lookup.addDecl(D);
|
||||
} else {
|
||||
// If this name wasn't predeclared and if this is not a function call,
|
||||
// diagnose the problem.
|
||||
if (SS && !SS->isEmpty())
|
||||
|
@ -801,7 +803,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
}
|
||||
}
|
||||
|
||||
if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
||||
if (VarDecl *Var = Lookup.getAsSingle<VarDecl>()) {
|
||||
// Warn about constructs like:
|
||||
// if (void *X = foo()) { ... } else { X }.
|
||||
// In the else block, the pointer is always false.
|
||||
|
@ -824,7 +826,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
CheckS = CheckS->getParent();
|
||||
}
|
||||
}
|
||||
} else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
|
||||
} else if (FunctionDecl *Func = Lookup.getAsSingle<FunctionDecl>()) {
|
||||
if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
|
||||
// C99 DR 316 says that, if a function type comes from a
|
||||
// function definition (without a prototype), that type is only
|
||||
|
@ -842,8 +844,10 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
|
|||
}
|
||||
}
|
||||
|
||||
return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand);
|
||||
return BuildDeclarationNameExpr(SS, Lookup, HasTrailingLParen,
|
||||
isAddressOfOperand);
|
||||
}
|
||||
|
||||
/// \brief Cast member's object to its own class if necessary.
|
||||
bool
|
||||
Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) {
|
||||
|
@ -887,53 +891,28 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
|
|||
return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty);
|
||||
}
|
||||
|
||||
/// \brief Complete semantic analysis for a reference to the given declaration.
|
||||
Sema::OwningExprResult
|
||||
Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
|
||||
bool HasTrailingLParen,
|
||||
const CXXScopeSpec *SS,
|
||||
bool isAddressOfOperand) {
|
||||
assert(D && "Cannot refer to a NULL declaration");
|
||||
DeclarationName Name = D->getDeclName();
|
||||
|
||||
// If this is an expression of the form &Class::member, don't build an
|
||||
// implicit member ref, because we want a pointer to the member in general,
|
||||
// not any specific instance's member.
|
||||
if (isAddressOfOperand && SS && !SS->isEmpty() && !HasTrailingLParen) {
|
||||
DeclContext *DC = computeDeclContext(*SS);
|
||||
if (D && isa<CXXRecordDecl>(DC)) {
|
||||
QualType DType;
|
||||
if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
|
||||
DType = FD->getType().getNonReferenceType();
|
||||
} else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
|
||||
DType = Method->getType();
|
||||
} else if (isa<OverloadedFunctionDecl>(D)) {
|
||||
DType = Context.OverloadTy;
|
||||
}
|
||||
// Could be an inner type. That's diagnosed below, so ignore it here.
|
||||
if (!DType.isNull()) {
|
||||
// The pointer is type- and value-dependent if it points into something
|
||||
// dependent.
|
||||
bool Dependent = DC->isDependentContext();
|
||||
return BuildDeclRefExpr(D, DType, Loc, Dependent, Dependent, SS);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Builds an implicit member access expression from the given
|
||||
/// unqualified lookup set, which is known to contain only class
|
||||
/// members.
|
||||
Sema::OwningExprResult BuildImplicitMemberExpr(Sema &S, LookupResult &R,
|
||||
const CXXScopeSpec *SS) {
|
||||
NamedDecl *D = R.getAsSingleDecl(S.Context);
|
||||
SourceLocation Loc = R.getNameLoc();
|
||||
|
||||
// We may have found a field within an anonymous union or struct
|
||||
// (C++ [class.union]).
|
||||
// FIXME: This needs to happen post-isImplicitMemberReference?
|
||||
if (FieldDecl *FD = dyn_cast<FieldDecl>(D))
|
||||
if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
|
||||
return BuildAnonymousStructUnionMemberReference(Loc, FD);
|
||||
return S.BuildAnonymousStructUnionMemberReference(Loc, FD);
|
||||
|
||||
// Cope with an implicit member access in a C++ non-static member function.
|
||||
QualType ThisType, MemberType;
|
||||
if (isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
|
||||
Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
|
||||
MarkDeclarationReferenced(Loc, D);
|
||||
if (PerformObjectMemberConversion(This, D))
|
||||
return ExprError();
|
||||
QualType ThisType;
|
||||
QualType MemberType;
|
||||
if (S.isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
|
||||
Expr *This = new (S.Context) CXXThisExpr(SourceLocation(), ThisType);
|
||||
S.MarkDeclarationReferenced(Loc, D);
|
||||
if (S.PerformObjectMemberConversion(This, D))
|
||||
return S.ExprError();
|
||||
|
||||
bool ShouldCheckUse = true;
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
|
||||
|
@ -943,45 +922,196 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
|
|||
ShouldCheckUse = false;
|
||||
}
|
||||
|
||||
if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc))
|
||||
return ExprError();
|
||||
return Owned(BuildMemberExpr(Context, This, true, SS, D,
|
||||
Loc, MemberType));
|
||||
if (ShouldCheckUse && S.DiagnoseUseOfDecl(D, Loc))
|
||||
return S.ExprError();
|
||||
return S.Owned(BuildMemberExpr(S.Context, This, true, SS, D,
|
||||
Loc, MemberType));
|
||||
}
|
||||
|
||||
if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
|
||||
if (MD->isStatic())
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
|
||||
if (!Method->isStatic()) {
|
||||
S.Diag(Loc, diag::err_member_call_without_object);
|
||||
return S.ExprError();
|
||||
}
|
||||
}
|
||||
|
||||
if (isa<FieldDecl>(D)) {
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S.CurContext)) {
|
||||
if (MD->isStatic()) {
|
||||
// "invalid use of member 'x' in static member function"
|
||||
return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method)
|
||||
<< FD->getDeclName());
|
||||
S.Diag(Loc,diag::err_invalid_member_use_in_static_method)
|
||||
<< D->getDeclName();
|
||||
return S.ExprError();
|
||||
}
|
||||
}
|
||||
|
||||
// Any other ways we could have found the field in a well-formed
|
||||
// program would have been turned into implicit member expressions
|
||||
// above.
|
||||
return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use)
|
||||
<< FD->getDeclName());
|
||||
S.Diag(Loc, diag::err_invalid_non_static_member_use)
|
||||
<< D->getDeclName();
|
||||
return S.ExprError();
|
||||
}
|
||||
|
||||
if (isa<TypedefDecl>(D))
|
||||
return ExprError(Diag(Loc, diag::err_unexpected_typedef) << Name);
|
||||
if (isa<ObjCInterfaceDecl>(D))
|
||||
return ExprError(Diag(Loc, diag::err_unexpected_interface) << Name);
|
||||
if (isa<NamespaceDecl>(D))
|
||||
return ExprError(Diag(Loc, diag::err_unexpected_namespace) << Name);
|
||||
return S.BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
|
||||
/*ADL*/ false,
|
||||
R.begin(), R.end() - R.begin());
|
||||
}
|
||||
|
||||
static bool UseArgumentDependentLookup(Sema &SemaRef,
|
||||
const CXXScopeSpec *SS,
|
||||
bool HasTrailingLParen,
|
||||
const LookupResult &R) {
|
||||
// Only when used directly as the postfix-expression of a call.
|
||||
if (!HasTrailingLParen)
|
||||
return false;
|
||||
|
||||
// Never if a scope specifier was provided.
|
||||
if (SS && SS->isSet())
|
||||
return false;
|
||||
|
||||
// Only in C++ or ObjC++.
|
||||
if (!SemaRef.getLangOptions().CPlusPlus)
|
||||
return false;
|
||||
|
||||
// Turn off ADL when we find certain kinds of declarations during
|
||||
// normal lookup:
|
||||
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
|
||||
NamedDecl *D = *I;
|
||||
|
||||
// C++0x [basic.lookup.argdep]p3:
|
||||
// -- a declaration of a class member
|
||||
// Since using decls preserve this property, we check this on the
|
||||
// original decl.
|
||||
if (D->getDeclContext()->isRecord())
|
||||
return false;
|
||||
|
||||
// C++0x [basic.lookup.argdep]p3:
|
||||
// -- a block-scope function declaration that is not a
|
||||
// using-declaration
|
||||
// NOTE: we also trigger this for function templates (in fact, we
|
||||
// don't check the decl type at all, since all other decl types
|
||||
// turn off ADL anyway).
|
||||
if (isa<UsingShadowDecl>(D))
|
||||
D = cast<UsingShadowDecl>(D)->getTargetDecl();
|
||||
else if (D->getDeclContext()->isFunctionOrMethod())
|
||||
return false;
|
||||
|
||||
// C++0x [basic.lookup.argdep]p3:
|
||||
// -- a declaration that is neither a function or a function
|
||||
// template
|
||||
// And also for builtin functions.
|
||||
if (isa<FunctionDecl>(D)) {
|
||||
FunctionDecl *FDecl = cast<FunctionDecl>(D);
|
||||
|
||||
// But also builtin functions.
|
||||
if (FDecl->getBuiltinID() && FDecl->isImplicit())
|
||||
return false;
|
||||
} else if (!isa<FunctionTemplateDecl>(D))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Complete semantic analysis for a reference to the given
|
||||
/// lookup results.
|
||||
Sema::OwningExprResult
|
||||
Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
|
||||
LookupResult &R,
|
||||
bool HasTrailingLParen,
|
||||
bool isAddressOfOperand) {
|
||||
assert(!R.isAmbiguous() && "results are ambiguous");
|
||||
|
||||
// &SomeClass::foo is an abstract member reference, regardless of
|
||||
// the nature of foo, but &SomeClass::foo(...) is not.
|
||||
bool isAbstractMemberPointer =
|
||||
(isAddressOfOperand && !HasTrailingLParen && SS && !SS->isEmpty());
|
||||
|
||||
// If we're *not* an abstract member reference, and any of the
|
||||
// results are class members (i.e. they're all class members), then
|
||||
// we make an implicit member reference instead.
|
||||
if (!isAbstractMemberPointer && !R.empty() &&
|
||||
isa<CXXRecordDecl>((*R.begin())->getDeclContext())) {
|
||||
return BuildImplicitMemberExpr(*this, R, SS);
|
||||
}
|
||||
|
||||
assert(R.getResultKind() != LookupResult::FoundUnresolvedValue &&
|
||||
"found UnresolvedUsingValueDecl in non-class scope");
|
||||
|
||||
bool ADL = UseArgumentDependentLookup(*this, SS, HasTrailingLParen, R);
|
||||
|
||||
return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(), ADL,
|
||||
R.begin(), R.end() - R.begin());
|
||||
}
|
||||
|
||||
/// Diagnoses obvious problems with the use of the given declaration
|
||||
/// as an expression. This is only actually called for lookups that
|
||||
/// were not overloaded, and it doesn't promise that the declaration
|
||||
/// will in fact be used.
|
||||
static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
|
||||
if (isa<TypedefDecl>(D)) {
|
||||
S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isa<ObjCInterfaceDecl>(D)) {
|
||||
S.Diag(Loc, diag::err_unexpected_interface) << D->getDeclName();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isa<NamespaceDecl>(D)) {
|
||||
S.Diag(Loc, diag::err_unexpected_namespace) << D->getDeclName();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Sema::OwningExprResult
|
||||
Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
|
||||
SourceLocation Loc,
|
||||
DeclarationName Name,
|
||||
bool NeedsADL,
|
||||
NamedDecl * const *Decls,
|
||||
unsigned NumDecls) {
|
||||
if (!NeedsADL && NumDecls == 1)
|
||||
return BuildDeclarationNameExpr(SS, Loc, Decls[0]->getUnderlyingDecl());
|
||||
|
||||
// We only need to check the declaration if there's exactly one
|
||||
// result, because in the overloaded case the results can only be
|
||||
// functions and function templates.
|
||||
if (NumDecls == 1 &&
|
||||
CheckDeclInExpr(*this, Loc, Decls[0]->getUnderlyingDecl()))
|
||||
return ExprError();
|
||||
|
||||
UnresolvedLookupExpr *ULE
|
||||
= UnresolvedLookupExpr::Create(Context,
|
||||
SS ? (NestedNameSpecifier *)SS->getScopeRep() : 0,
|
||||
SS ? SS->getRange() : SourceRange(),
|
||||
Name, Loc, NeedsADL);
|
||||
for (unsigned I = 0; I != NumDecls; ++I)
|
||||
ULE->addDecl(Decls[I]);
|
||||
|
||||
return Owned(ULE);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Complete semantic analysis for a reference to the given declaration.
|
||||
Sema::OwningExprResult
|
||||
Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
|
||||
SourceLocation Loc, NamedDecl *D) {
|
||||
assert(D && "Cannot refer to a NULL declaration");
|
||||
DeclarationName Name = D->getDeclName();
|
||||
|
||||
if (CheckDeclInExpr(*this, Loc, D))
|
||||
return ExprError();
|
||||
|
||||
// Make the DeclRefExpr or BlockDeclRefExpr for the decl.
|
||||
if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
|
||||
return BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc,
|
||||
false, false, SS);
|
||||
else if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
|
||||
if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
|
||||
return BuildDeclRefExpr(Template, Context.OverloadTy, Loc,
|
||||
false, false, SS);
|
||||
else if (UnresolvedUsingValueDecl *UD = dyn_cast<UnresolvedUsingValueDecl>(D))
|
||||
return BuildDeclRefExpr(UD, Context.DependentTy, Loc,
|
||||
/*TypeDependent=*/true,
|
||||
/*ValueDependent=*/true, SS);
|
||||
|
||||
ValueDecl *VD = cast<ValueDecl>(D);
|
||||
|
||||
|
@ -989,9 +1119,7 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
|
|||
// this check when we're going to perform argument-dependent lookup
|
||||
// on this function name, because this might not be the function
|
||||
// that overload resolution actually selects.
|
||||
bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
|
||||
HasTrailingLParen;
|
||||
if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
|
||||
if (DiagnoseUseOfDecl(VD, Loc))
|
||||
return ExprError();
|
||||
|
||||
// Only create DeclRefExpr's for valid Decl's.
|
||||
|
@ -1038,9 +1166,8 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
|
|||
TypeDependent = true;
|
||||
// - a nested-name-specifier that contains a class-name that
|
||||
// names a dependent type.
|
||||
else if (SS && !SS->isEmpty()) {
|
||||
for (DeclContext *DC = computeDeclContext(*SS);
|
||||
DC; DC = DC->getParent()) {
|
||||
else {
|
||||
for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {
|
||||
// FIXME: could stop early at namespace scope.
|
||||
if (DC->isRecord()) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
|
||||
|
@ -2557,7 +2684,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
|
|||
/// whether argument-dependent lookup is available, whether it has explicit
|
||||
/// template arguments, etc.
|
||||
void Sema::DeconstructCallFunction(Expr *FnExpr,
|
||||
NamedDecl *&Function,
|
||||
llvm::SmallVectorImpl<NamedDecl*> &Fns,
|
||||
DeclarationName &Name,
|
||||
NestedNameSpecifier *&Qualifier,
|
||||
SourceRange &QualifierRange,
|
||||
|
@ -2566,7 +2693,6 @@ void Sema::DeconstructCallFunction(Expr *FnExpr,
|
|||
const TemplateArgumentLoc *&ExplicitTemplateArgs,
|
||||
unsigned &NumExplicitTemplateArgs) {
|
||||
// Set defaults for all of the output parameters.
|
||||
Function = 0;
|
||||
Name = DeclarationName();
|
||||
Qualifier = 0;
|
||||
QualifierRange = SourceRange();
|
||||
|
@ -2589,21 +2715,29 @@ void Sema::DeconstructCallFunction(Expr *FnExpr,
|
|||
== UnaryOperator::AddrOf) {
|
||||
FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
|
||||
} else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
|
||||
Function = dyn_cast<NamedDecl>(DRExpr->getDecl());
|
||||
if ((Qualifier = DRExpr->getQualifier())) {
|
||||
ArgumentDependentLookup = false;
|
||||
Fns.push_back(cast<NamedDecl>(DRExpr->getDecl()));
|
||||
ArgumentDependentLookup = false;
|
||||
if ((Qualifier = DRExpr->getQualifier()))
|
||||
QualifierRange = DRExpr->getQualifierRange();
|
||||
}
|
||||
break;
|
||||
} else if (UnresolvedFunctionNameExpr *DepName
|
||||
= dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
|
||||
Name = DepName->getName();
|
||||
} else if (UnresolvedLookupExpr *UnresLookup
|
||||
= dyn_cast<UnresolvedLookupExpr>(FnExpr)) {
|
||||
Name = UnresLookup->getName();
|
||||
Fns.append(UnresLookup->decls_begin(), UnresLookup->decls_end());
|
||||
ArgumentDependentLookup = UnresLookup->requiresADL();
|
||||
if ((Qualifier = UnresLookup->getQualifier()))
|
||||
QualifierRange = UnresLookup->getQualifierRange();
|
||||
break;
|
||||
} else if (TemplateIdRefExpr *TemplateIdRef
|
||||
= dyn_cast<TemplateIdRefExpr>(FnExpr)) {
|
||||
Function = TemplateIdRef->getTemplateName().getAsTemplateDecl();
|
||||
if (!Function)
|
||||
Function = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
|
||||
if (NamedDecl *Function
|
||||
= TemplateIdRef->getTemplateName().getAsTemplateDecl())
|
||||
Fns.push_back(Function);
|
||||
else {
|
||||
OverloadedFunctionDecl *Overload
|
||||
= TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
|
||||
Fns.append(Overload->function_begin(), Overload->function_end());
|
||||
}
|
||||
HasExplicitTemplateArguments = true;
|
||||
ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
|
||||
NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
|
||||
|
@ -2653,9 +2787,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
|
|||
Expr *Fn = fn.takeAs<Expr>();
|
||||
Expr **Args = reinterpret_cast<Expr**>(args.release());
|
||||
assert(Fn && "no function call expression");
|
||||
FunctionDecl *FDecl = NULL;
|
||||
NamedDecl *NDecl = NULL;
|
||||
DeclarationName UnqualifiedName;
|
||||
|
||||
if (getLangOptions().CPlusPlus) {
|
||||
// If this is a pseudo-destructor expression, build the call immediately.
|
||||
|
@ -2742,39 +2873,43 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
|
|||
// If we're directly calling a function, get the appropriate declaration.
|
||||
// Also, in C++, keep track of whether we should perform argument-dependent
|
||||
// lookup and whether there were any explicitly-specified template arguments.
|
||||
llvm::SmallVector<NamedDecl*,8> Fns;
|
||||
DeclarationName UnqualifiedName;
|
||||
bool ADL = true;
|
||||
bool HasExplicitTemplateArgs = 0;
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
|
||||
unsigned NumExplicitTemplateArgs = 0;
|
||||
NestedNameSpecifier *Qualifier = 0;
|
||||
SourceRange QualifierRange;
|
||||
DeconstructCallFunction(Fn, NDecl, UnqualifiedName, Qualifier, QualifierRange,
|
||||
DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
|
||||
ADL,HasExplicitTemplateArgs, ExplicitTemplateArgs,
|
||||
NumExplicitTemplateArgs);
|
||||
|
||||
OverloadedFunctionDecl *Ovl = 0;
|
||||
NamedDecl *NDecl = 0; // the specific declaration we're calling, if applicable
|
||||
FunctionDecl *FDecl = 0; // same, if it's a function or function template
|
||||
FunctionTemplateDecl *FunctionTemplate = 0;
|
||||
if (NDecl) {
|
||||
|
||||
if (Fns.size() == 1) {
|
||||
NDecl = Fns[0];
|
||||
FDecl = dyn_cast<FunctionDecl>(NDecl);
|
||||
if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl)))
|
||||
FDecl = FunctionTemplate->getTemplatedDecl();
|
||||
else
|
||||
FDecl = dyn_cast<FunctionDecl>(NDecl);
|
||||
Ovl = dyn_cast<OverloadedFunctionDecl>(NDecl);
|
||||
}
|
||||
|
||||
if (Ovl || FunctionTemplate ||
|
||||
if (Fns.size() > 1 || FunctionTemplate ||
|
||||
(getLangOptions().CPlusPlus && (FDecl || UnqualifiedName))) {
|
||||
// We don't perform ADL for implicit declarations of builtins.
|
||||
if (FDecl && FDecl->getBuiltinID() && FDecl->isImplicit())
|
||||
ADL = false;
|
||||
assert(!ADL); // this should be guaranteed earlier
|
||||
|
||||
// We don't perform ADL in C.
|
||||
if (!getLangOptions().CPlusPlus)
|
||||
ADL = false;
|
||||
assert(!ADL); // ditto
|
||||
|
||||
if (Ovl || FunctionTemplate || ADL) {
|
||||
FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName,
|
||||
if (Fns.size() > 1 || FunctionTemplate || ADL) {
|
||||
FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName,
|
||||
HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs,
|
||||
NumExplicitTemplateArgs,
|
||||
|
@ -2784,6 +2919,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
|
|||
return ExprError();
|
||||
|
||||
Fn = FixOverloadedFunctionReference(Fn, FDecl);
|
||||
|
||||
NDecl = FDecl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5123,6 +5260,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
|||
// FIXME: Can LHS ever be null here?
|
||||
if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull())
|
||||
return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc);
|
||||
} else if (isa<UnresolvedLookupExpr>(op)) {
|
||||
return Context.OverloadTy;
|
||||
} else if (dcl) { // C99 6.5.3.2p1
|
||||
// We have an lvalue with a decl. Make sure the decl is not declared
|
||||
// with the register storage-class specifier.
|
||||
|
@ -5132,8 +5271,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
|||
<< "register variable" << op->getSourceRange();
|
||||
return QualType();
|
||||
}
|
||||
} else if (isa<OverloadedFunctionDecl>(dcl) ||
|
||||
isa<FunctionTemplateDecl>(dcl)) {
|
||||
} else if (isa<FunctionTemplateDecl>(dcl)) {
|
||||
return Context.OverloadTy;
|
||||
} else if (FieldDecl *FD = dyn_cast<FieldDecl>(dcl)) {
|
||||
// Okay: we can take the address of a field.
|
||||
|
|
|
@ -855,18 +855,15 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|||
if (const RecordType *Record = Type->getAs<RecordType>()) {
|
||||
llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
|
||||
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
|
||||
OverloadedFunctionDecl *Conversions =
|
||||
RD->getVisibleConversionFunctions();
|
||||
const UnresolvedSet *Conversions = RD->getVisibleConversionFunctions();
|
||||
|
||||
for (OverloadedFunctionDecl::function_iterator
|
||||
Func = Conversions->function_begin(),
|
||||
FuncEnd = Conversions->function_end();
|
||||
Func != FuncEnd; ++Func) {
|
||||
for (UnresolvedSet::iterator I = Conversions->begin(),
|
||||
E = Conversions->end(); I != E; ++I) {
|
||||
// Skip over templated conversion functions; they aren't considered.
|
||||
if (isa<FunctionTemplateDecl>(*Func))
|
||||
if (isa<FunctionTemplateDecl>(*I))
|
||||
continue;
|
||||
|
||||
CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
|
||||
CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
|
||||
|
||||
QualType ConvType = Conv->getConversionType().getNonReferenceType();
|
||||
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
|
||||
|
@ -2310,6 +2307,9 @@ bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D,
|
|||
MemberType
|
||||
= Context.getQualifiedType(MemberType,
|
||||
Qualifiers::fromCVRMask(MD->getTypeQualifiers()));
|
||||
} else if (isa<UnresolvedUsingValueDecl>(D)) {
|
||||
Ctx = D->getDeclContext();
|
||||
MemberType = Context.DependentTy;
|
||||
} else {
|
||||
for (OverloadIterator Ovl(D), OvlEnd; Ovl != OvlEnd; ++Ovl) {
|
||||
CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Ovl);
|
||||
|
|
|
@ -1525,33 +1525,29 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
|
|||
// in which the function or function template is defined and the
|
||||
// classes and namespaces associated with its (non-dependent)
|
||||
// parameter types and return type.
|
||||
DeclRefExpr *DRE = 0;
|
||||
TemplateIdRefExpr *TIRE = 0;
|
||||
Arg = Arg->IgnoreParens();
|
||||
if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg)) {
|
||||
if (unaryOp->getOpcode() == UnaryOperator::AddrOf) {
|
||||
DRE = dyn_cast<DeclRefExpr>(unaryOp->getSubExpr());
|
||||
TIRE = dyn_cast<TemplateIdRefExpr>(unaryOp->getSubExpr());
|
||||
}
|
||||
} else {
|
||||
DRE = dyn_cast<DeclRefExpr>(Arg);
|
||||
TIRE = dyn_cast<TemplateIdRefExpr>(Arg);
|
||||
}
|
||||
if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
|
||||
if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
|
||||
Arg = unaryOp->getSubExpr();
|
||||
|
||||
OverloadedFunctionDecl *Ovl = 0;
|
||||
if (DRE)
|
||||
Ovl = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
|
||||
else if (TIRE)
|
||||
Ovl = TIRE->getTemplateName().getAsOverloadedFunctionDecl();
|
||||
if (!Ovl)
|
||||
// TODO: avoid the copies. This should be easy when the cases
|
||||
// share a storage implementation.
|
||||
llvm::SmallVector<NamedDecl*, 8> Functions;
|
||||
|
||||
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg))
|
||||
Functions.append(ULE->decls_begin(), ULE->decls_end());
|
||||
else if (TemplateIdRefExpr *TIRE = dyn_cast<TemplateIdRefExpr>(Arg)) {
|
||||
TemplateName TName = TIRE->getTemplateName();
|
||||
OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl();
|
||||
Functions.append(Ovl->function_begin(), Ovl->function_end());
|
||||
} else
|
||||
continue;
|
||||
|
||||
for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
|
||||
FuncEnd = Ovl->function_end();
|
||||
Func != FuncEnd; ++Func) {
|
||||
FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*Func);
|
||||
for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(),
|
||||
E = Functions.end(); I != E; ++I) {
|
||||
FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I);
|
||||
if (!FDecl)
|
||||
FDecl = cast<FunctionTemplateDecl>(*Func)->getTemplatedDecl();
|
||||
FDecl = cast<FunctionTemplateDecl>(*I)->getTemplatedDecl();
|
||||
|
||||
// Add the namespace in which this function was defined. Note
|
||||
// that, if this is a member function, we do *not* consider the
|
||||
|
|
|
@ -1353,18 +1353,6 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
|
|||
return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
|
||||
}
|
||||
|
||||
/// \brief Given a function template or function, extract the function template
|
||||
/// declaration (if any) and the underlying function declaration.
|
||||
template<typename T>
|
||||
static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function,
|
||||
FunctionTemplateDecl *&FunctionTemplate) {
|
||||
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(Orig);
|
||||
if (FunctionTemplate)
|
||||
Function = cast<T>(FunctionTemplate->getTemplatedDecl());
|
||||
else
|
||||
Function = cast<T>(Orig);
|
||||
}
|
||||
|
||||
/// Determines whether there is a user-defined conversion sequence
|
||||
/// (C++ [over.ics.user]) that converts expression From to the type
|
||||
/// ToType. If such a conversion exists, User will contain the
|
||||
|
@ -1455,18 +1443,16 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
|
|||
if (CXXRecordDecl *FromRecordDecl
|
||||
= dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
|
||||
// Add all of the conversion functions as candidates.
|
||||
OverloadedFunctionDecl *Conversions
|
||||
const UnresolvedSet *Conversions
|
||||
= FromRecordDecl->getVisibleConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator Func
|
||||
= Conversions->function_begin();
|
||||
Func != Conversions->function_end(); ++Func) {
|
||||
for (UnresolvedSet::iterator I = Conversions->begin(),
|
||||
E = Conversions->end(); I != E; ++I) {
|
||||
CXXConversionDecl *Conv;
|
||||
FunctionTemplateDecl *ConvTemplate;
|
||||
GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
|
||||
if (ConvTemplate)
|
||||
if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(*I)))
|
||||
Conv = dyn_cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
|
||||
else
|
||||
Conv = dyn_cast<CXXConversionDecl>(*Func);
|
||||
Conv = dyn_cast<CXXConversionDecl>(*I);
|
||||
|
||||
if (AllowExplicit || !Conv->isExplicit()) {
|
||||
if (ConvTemplate)
|
||||
|
@ -3144,20 +3130,17 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
|
|||
}
|
||||
|
||||
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
|
||||
OverloadedFunctionDecl *Conversions
|
||||
const UnresolvedSet *Conversions
|
||||
= ClassDecl->getVisibleConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator Func
|
||||
= Conversions->function_begin();
|
||||
Func != Conversions->function_end(); ++Func) {
|
||||
CXXConversionDecl *Conv;
|
||||
FunctionTemplateDecl *ConvTemplate;
|
||||
GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
|
||||
for (UnresolvedSet::iterator I = Conversions->begin(),
|
||||
E = Conversions->end(); I != E; ++I) {
|
||||
|
||||
// Skip conversion function templates; they don't tell us anything
|
||||
// about which builtin types we can convert to.
|
||||
if (ConvTemplate)
|
||||
if (isa<FunctionTemplateDecl>(*I))
|
||||
continue;
|
||||
|
||||
CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
|
||||
if (AllowExplicitConversions || !Conv->isExplicit()) {
|
||||
AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false,
|
||||
VisibleQuals);
|
||||
|
@ -3211,13 +3194,12 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
|
|||
}
|
||||
|
||||
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
|
||||
OverloadedFunctionDecl *Conversions =
|
||||
const UnresolvedSet *Conversions =
|
||||
ClassDecl->getVisibleConversionFunctions();
|
||||
|
||||
for (OverloadedFunctionDecl::function_iterator Func
|
||||
= Conversions->function_begin();
|
||||
Func != Conversions->function_end(); ++Func) {
|
||||
if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*Func)) {
|
||||
for (UnresolvedSet::iterator I = Conversions->begin(),
|
||||
E = Conversions->end(); I != E; ++I) {
|
||||
if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) {
|
||||
QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
|
||||
if (const ReferenceType *ResTypeRef = CanTy->getAs<ReferenceType>())
|
||||
CanTy = ResTypeRef->getPointeeType();
|
||||
|
@ -4336,7 +4318,6 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
return 0;
|
||||
|
||||
// Find the actual overloaded function declaration.
|
||||
OverloadedFunctionDecl *Ovl = 0;
|
||||
|
||||
// C++ [over.over]p1:
|
||||
// [...] [Note: any redundant set of parentheses surrounding the
|
||||
|
@ -4354,15 +4335,21 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
bool HasExplicitTemplateArgs = false;
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
|
||||
unsigned NumExplicitTemplateArgs = 0;
|
||||
|
||||
llvm::SmallVector<NamedDecl*,8> Fns;
|
||||
|
||||
// Try to dig out the overloaded function.
|
||||
OverloadedFunctionDecl *Ovl = 0;
|
||||
FunctionTemplateDecl *FunctionTemplate = 0;
|
||||
if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OvlExpr)) {
|
||||
Ovl = dyn_cast<OverloadedFunctionDecl>(DR->getDecl());
|
||||
assert(!isa<OverloadedFunctionDecl>(DR->getDecl()));
|
||||
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl());
|
||||
HasExplicitTemplateArgs = DR->hasExplicitTemplateArgumentList();
|
||||
ExplicitTemplateArgs = DR->getTemplateArgs();
|
||||
NumExplicitTemplateArgs = DR->getNumTemplateArgs();
|
||||
} else if (UnresolvedLookupExpr *UL
|
||||
= dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
|
||||
Fns.append(UL->decls_begin(), UL->decls_end());
|
||||
} else if (MemberExpr *ME = dyn_cast<MemberExpr>(OvlExpr)) {
|
||||
Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl());
|
||||
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl());
|
||||
|
@ -4379,23 +4366,20 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
ExplicitTemplateArgs = TIRE->getTemplateArgs();
|
||||
NumExplicitTemplateArgs = TIRE->getNumTemplateArgs();
|
||||
}
|
||||
|
||||
// If there's no overloaded function declaration or function template,
|
||||
// we're done.
|
||||
if (!Ovl && !FunctionTemplate)
|
||||
return 0;
|
||||
|
||||
OverloadIterator Fun;
|
||||
if (Ovl)
|
||||
Fun = Ovl;
|
||||
else
|
||||
Fun = FunctionTemplate;
|
||||
if (Ovl) Fns.append(Ovl->function_begin(), Ovl->function_end());
|
||||
if (FunctionTemplate) Fns.push_back(FunctionTemplate);
|
||||
|
||||
// If we didn't actually find anything, we're done.
|
||||
if (Fns.empty())
|
||||
return 0;
|
||||
|
||||
// Look through all of the overloaded functions, searching for one
|
||||
// whose type matches exactly.
|
||||
llvm::SmallPtrSet<FunctionDecl *, 4> Matches;
|
||||
bool FoundNonTemplateFunction = false;
|
||||
for (OverloadIterator FunEnd; Fun != FunEnd; ++Fun) {
|
||||
for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(),
|
||||
E = Fns.end(); I != E; ++I) {
|
||||
// C++ [over.over]p3:
|
||||
// Non-member functions and static member functions match
|
||||
// targets of type "pointer-to-function" or "reference-to-function."
|
||||
|
@ -4404,7 +4388,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
// Note that according to DR 247, the containing class does not matter.
|
||||
|
||||
if (FunctionTemplateDecl *FunctionTemplate
|
||||
= dyn_cast<FunctionTemplateDecl>(*Fun)) {
|
||||
= dyn_cast<FunctionTemplateDecl>(*I)) {
|
||||
if (CXXMethodDecl *Method
|
||||
= dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
|
||||
// Skip non-static function templates when converting to pointer, and
|
||||
|
@ -4438,9 +4422,11 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
Matches.insert(
|
||||
cast<FunctionDecl>(Specialization->getCanonicalDecl()));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Fun)) {
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) {
|
||||
// Skip non-static functions when converting to pointer, and static
|
||||
// when converting to member pointer.
|
||||
if (Method->isStatic() == IsMember)
|
||||
|
@ -4452,9 +4438,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
} else if (IsMember)
|
||||
continue;
|
||||
|
||||
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Fun)) {
|
||||
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*I)) {
|
||||
if (FunctionType == Context.getCanonicalType(FunDecl->getType())) {
|
||||
Matches.insert(cast<FunctionDecl>(Fun->getCanonicalDecl()));
|
||||
Matches.insert(cast<FunctionDecl>(FunDecl->getCanonicalDecl()));
|
||||
FoundNonTemplateFunction = true;
|
||||
}
|
||||
}
|
||||
|
@ -4522,7 +4508,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
|
||||
/// \brief Add a single candidate to the overload set.
|
||||
static void AddOverloadedCallCandidate(Sema &S,
|
||||
AnyFunctionDecl Callee,
|
||||
NamedDecl *Callee,
|
||||
bool &ArgumentDependentLookup,
|
||||
bool HasExplicitTemplateArgs,
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs,
|
||||
|
@ -4530,6 +4516,9 @@ static void AddOverloadedCallCandidate(Sema &S,
|
|||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet &CandidateSet,
|
||||
bool PartialOverloading) {
|
||||
if (isa<UsingShadowDecl>(Callee))
|
||||
Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
|
||||
|
||||
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
|
||||
assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
|
||||
S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false,
|
||||
|
@ -4539,21 +4528,28 @@ static void AddOverloadedCallCandidate(Sema &S,
|
|||
Func->getDeclContext()->isFunctionOrMethod())
|
||||
ArgumentDependentLookup = false;
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionTemplateDecl *FuncTemplate = cast<FunctionTemplateDecl>(Callee);
|
||||
S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs,
|
||||
NumExplicitTemplateArgs,
|
||||
Args, NumArgs, CandidateSet);
|
||||
|
||||
if (FuncTemplate->getDeclContext()->isRecord())
|
||||
ArgumentDependentLookup = false;
|
||||
}
|
||||
|
||||
if (FunctionTemplateDecl *FuncTemplate
|
||||
= dyn_cast<FunctionTemplateDecl>(Callee)) {
|
||||
S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs,
|
||||
NumExplicitTemplateArgs,
|
||||
Args, NumArgs, CandidateSet);
|
||||
|
||||
if (FuncTemplate->getDeclContext()->isRecord())
|
||||
ArgumentDependentLookup = false;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(false && "unhandled case in overloaded call candidate");
|
||||
|
||||
// do nothing?
|
||||
}
|
||||
|
||||
/// \brief Add the overload candidates named by callee and/or found by argument
|
||||
/// dependent lookup to the given overload set.
|
||||
void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
|
||||
void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns,
|
||||
DeclarationName &UnqualifiedName,
|
||||
bool &ArgumentDependentLookup,
|
||||
bool HasExplicitTemplateArgs,
|
||||
|
@ -4562,11 +4558,11 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
|
|||
Expr **Args, unsigned NumArgs,
|
||||
OverloadCandidateSet &CandidateSet,
|
||||
bool PartialOverloading) {
|
||||
// Add the functions denoted by Callee to the set of candidate
|
||||
// functions. While we're doing so, track whether argument-dependent
|
||||
// lookup still applies, per:
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Verify that ArgumentDependentLookup is consistent with the rules
|
||||
// in C++0x [basic.lookup.argdep]p3:
|
||||
//
|
||||
// C++0x [basic.lookup.argdep]p3:
|
||||
// Let X be the lookup set produced by unqualified lookup (3.4.1)
|
||||
// and let Y be the lookup set produced by argument dependent
|
||||
// lookup (defined as follows). If X contains
|
||||
|
@ -4574,38 +4570,31 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
|
|||
// -- a declaration of a class member, or
|
||||
//
|
||||
// -- a block-scope function declaration that is not a
|
||||
// using-declaration (FIXME: check for using declaration), or
|
||||
// using-declaration, or
|
||||
//
|
||||
// -- a declaration that is neither a function or a function
|
||||
// template
|
||||
//
|
||||
// then Y is empty.
|
||||
if (!Callee) {
|
||||
// Nothing to do.
|
||||
} else if (OverloadedFunctionDecl *Ovl
|
||||
= dyn_cast<OverloadedFunctionDecl>(Callee)) {
|
||||
for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
|
||||
FuncEnd = Ovl->function_end();
|
||||
Func != FuncEnd; ++Func)
|
||||
AddOverloadedCallCandidate(*this, *Func, ArgumentDependentLookup,
|
||||
HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs, NumExplicitTemplateArgs,
|
||||
Args, NumArgs, CandidateSet,
|
||||
PartialOverloading);
|
||||
} else if (isa<FunctionDecl>(Callee) || isa<FunctionTemplateDecl>(Callee))
|
||||
AddOverloadedCallCandidate(*this,
|
||||
AnyFunctionDecl::getFromNamedDecl(Callee),
|
||||
ArgumentDependentLookup,
|
||||
|
||||
if (ArgumentDependentLookup) {
|
||||
for (unsigned I = 0; I < Fns.size(); ++I) {
|
||||
assert(!Fns[I]->getDeclContext()->isRecord());
|
||||
assert(isa<UsingShadowDecl>(Fns[I]) ||
|
||||
!Fns[I]->getDeclContext()->isFunctionOrMethod());
|
||||
assert(Fns[I]->getUnderlyingDecl()->isFunctionOrFunctionTemplate());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(),
|
||||
E = Fns.end(); I != E; ++I)
|
||||
AddOverloadedCallCandidate(*this, *I, ArgumentDependentLookup,
|
||||
HasExplicitTemplateArgs,
|
||||
ExplicitTemplateArgs, NumExplicitTemplateArgs,
|
||||
Args, NumArgs, CandidateSet,
|
||||
Args, NumArgs, CandidateSet,
|
||||
PartialOverloading);
|
||||
// FIXME: assert isa<FunctionDecl> || isa<FunctionTemplateDecl> rather than
|
||||
// checking dynamically.
|
||||
|
||||
if (Callee)
|
||||
UnqualifiedName = Callee->getDeclName();
|
||||
|
||||
|
||||
if (ArgumentDependentLookup)
|
||||
AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
|
||||
HasExplicitTemplateArgs,
|
||||
|
@ -4622,7 +4611,8 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
|
|||
/// the function declaration produced by overload
|
||||
/// resolution. Otherwise, emits diagnostics, deletes all of the
|
||||
/// arguments and Fn, and returns NULL.
|
||||
FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
|
||||
FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn,
|
||||
llvm::SmallVectorImpl<NamedDecl*> &Fns,
|
||||
DeclarationName UnqualifiedName,
|
||||
bool HasExplicitTemplateArgs,
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs,
|
||||
|
@ -4636,7 +4626,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
|
|||
|
||||
// Add the functions denoted by Callee to the set of candidate
|
||||
// functions.
|
||||
AddOverloadedCallCandidates(Callee, UnqualifiedName, ArgumentDependentLookup,
|
||||
AddOverloadedCallCandidates(Fns, UnqualifiedName, ArgumentDependentLookup,
|
||||
HasExplicitTemplateArgs, ExplicitTemplateArgs,
|
||||
NumExplicitTemplateArgs, Args, NumArgs,
|
||||
CandidateSet);
|
||||
|
@ -4716,15 +4706,13 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
|
|||
}
|
||||
|
||||
if (Input->isTypeDependent()) {
|
||||
OverloadedFunctionDecl *Overloads
|
||||
= OverloadedFunctionDecl::Create(Context, CurContext, OpName);
|
||||
UnresolvedLookupExpr *Fn
|
||||
= UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc,
|
||||
/*ADL*/ true);
|
||||
for (FunctionSet::iterator Func = Functions.begin(),
|
||||
FuncEnd = Functions.end();
|
||||
Func != FuncEnd; ++Func)
|
||||
Overloads->addOverload(*Func);
|
||||
|
||||
DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
|
||||
OpLoc, false, false);
|
||||
Fn->addDecl(*Func);
|
||||
|
||||
input.release();
|
||||
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
|
||||
|
@ -4874,15 +4862,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
|||
OpLoc));
|
||||
}
|
||||
|
||||
OverloadedFunctionDecl *Overloads
|
||||
= OverloadedFunctionDecl::Create(Context, CurContext, OpName);
|
||||
UnresolvedLookupExpr *Fn
|
||||
= UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc,
|
||||
/* ADL */ true);
|
||||
|
||||
for (FunctionSet::iterator Func = Functions.begin(),
|
||||
FuncEnd = Functions.end();
|
||||
Func != FuncEnd; ++Func)
|
||||
Overloads->addOverload(*Func);
|
||||
|
||||
DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
|
||||
OpLoc, false, false);
|
||||
Fn->addDecl(*Func);
|
||||
|
||||
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
|
||||
Args, 2,
|
||||
|
@ -5040,11 +5027,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
|
|||
// expression.
|
||||
if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
|
||||
|
||||
OverloadedFunctionDecl *Overloads
|
||||
= OverloadedFunctionDecl::Create(Context, CurContext, OpName);
|
||||
|
||||
DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
|
||||
LLoc, false, false);
|
||||
UnresolvedLookupExpr *Fn
|
||||
= UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, LLoc,
|
||||
/*ADL*/ true);
|
||||
// Can't add an actual overloads yet
|
||||
|
||||
Base.release();
|
||||
Idx.release();
|
||||
|
@ -5334,21 +5320,17 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
|
|||
// accessible base class provided the function is not hidden
|
||||
// within T by another intervening declaration.
|
||||
// FIXME: Look in base classes for more conversion operators!
|
||||
OverloadedFunctionDecl *Conversions
|
||||
const UnresolvedSet *Conversions
|
||||
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
|
||||
for (OverloadedFunctionDecl::function_iterator
|
||||
Func = Conversions->function_begin(),
|
||||
FuncEnd = Conversions->function_end();
|
||||
Func != FuncEnd; ++Func) {
|
||||
CXXConversionDecl *Conv;
|
||||
FunctionTemplateDecl *ConvTemplate;
|
||||
GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
|
||||
|
||||
for (UnresolvedSet::iterator I = Conversions->begin(),
|
||||
E = Conversions->end(); I != E; ++I) {
|
||||
// Skip over templated conversion functions; they aren't
|
||||
// surrogates.
|
||||
if (ConvTemplate)
|
||||
if (isa<FunctionTemplateDecl>(*I))
|
||||
continue;
|
||||
|
||||
CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
|
||||
|
||||
// Strip the reference type (if any) and then the pointer type (if
|
||||
// any) to get down to what might be a function type.
|
||||
QualType ConvType = Conv->getConversionType().getNonReferenceType();
|
||||
|
@ -5637,38 +5619,32 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
|
|||
if (Method->isStatic()) {
|
||||
// Do nothing: static member functions aren't any different
|
||||
// from non-member functions.
|
||||
} else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr())) {
|
||||
if (DRE->getQualifier()) {
|
||||
// We have taken the address of a pointer to member
|
||||
// function. Perform the computation here so that we get the
|
||||
// appropriate pointer to member type.
|
||||
QualType ClassType
|
||||
= Context.getTypeDeclType(
|
||||
cast<RecordDecl>(Method->getDeclContext()));
|
||||
QualType MemPtrType
|
||||
= Context.getMemberPointerType(Fn->getType(),
|
||||
ClassType.getTypePtr());
|
||||
} else {
|
||||
// Fix the sub expression, which really has to be one of:
|
||||
// * a DeclRefExpr holding a member function template
|
||||
// * a TemplateIdRefExpr, also holding a member function template
|
||||
// * an UnresolvedLookupExpr holding an overloaded member function
|
||||
Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
|
||||
if (SubExpr == UnOp->getSubExpr())
|
||||
return UnOp->Retain();
|
||||
|
||||
DeclRefExpr *NewDRE
|
||||
= DeclRefExpr::Create(Context,
|
||||
DRE->getQualifier(),
|
||||
DRE->getQualifierRange(),
|
||||
Fn,
|
||||
DRE->getLocation(),
|
||||
DRE->hasExplicitTemplateArgumentList(),
|
||||
DRE->getLAngleLoc(),
|
||||
DRE->getTemplateArgs(),
|
||||
DRE->getNumTemplateArgs(),
|
||||
DRE->getRAngleLoc(),
|
||||
Fn->getType(),
|
||||
DRE->isTypeDependent(),
|
||||
DRE->isValueDependent());
|
||||
|
||||
return new (Context) UnaryOperator(NewDRE, UnaryOperator::AddrOf,
|
||||
MemPtrType,
|
||||
UnOp->getOperatorLoc());
|
||||
}
|
||||
assert(isa<DeclRefExpr>(SubExpr)
|
||||
&& "fixed to something other than a decl ref");
|
||||
assert(cast<DeclRefExpr>(SubExpr)->getQualifier()
|
||||
&& "fixed to a member ref with no nested name qualifier");
|
||||
|
||||
// We have taken the address of a pointer to member
|
||||
// function. Perform the computation here so that we get the
|
||||
// appropriate pointer to member type.
|
||||
QualType ClassType
|
||||
= Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
|
||||
QualType MemPtrType
|
||||
= Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
|
||||
|
||||
return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
|
||||
MemPtrType, UnOp->getOperatorLoc());
|
||||
}
|
||||
|
||||
// FIXME: TemplateIdRefExpr referring to a member function template
|
||||
// specialization!
|
||||
}
|
||||
|
@ -5682,8 +5658,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
|
|||
}
|
||||
|
||||
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
|
||||
assert((isa<OverloadedFunctionDecl>(DRE->getDecl()) ||
|
||||
isa<FunctionTemplateDecl>(DRE->getDecl()) ||
|
||||
assert((isa<FunctionTemplateDecl>(DRE->getDecl()) ||
|
||||
isa<FunctionDecl>(DRE->getDecl())) &&
|
||||
"Expected function or function template");
|
||||
return DeclRefExpr::Create(Context,
|
||||
|
@ -5700,6 +5675,18 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
|
|||
DRE->isTypeDependent(),
|
||||
DRE->isValueDependent());
|
||||
}
|
||||
|
||||
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
|
||||
return DeclRefExpr::Create(Context,
|
||||
ULE->getQualifier(),
|
||||
ULE->getQualifierRange(),
|
||||
Fn,
|
||||
ULE->getNameLoc(),
|
||||
Fn->getType(),
|
||||
Fn->getType()->isDependentType(),
|
||||
false);
|
||||
}
|
||||
|
||||
|
||||
if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {
|
||||
assert((isa<OverloadedFunctionDecl>(MemExpr->getMemberDecl()) ||
|
||||
|
@ -5736,13 +5723,6 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
|
|||
/*FIXME?*/false, /*FIXME?*/false);
|
||||
}
|
||||
|
||||
if (isa<UnresolvedFunctionNameExpr>(E))
|
||||
return DeclRefExpr::Create(Context,
|
||||
/*Qualifier=*/0,
|
||||
/*QualifierRange=*/SourceRange(),
|
||||
Fn, E->getLocStart(),
|
||||
Fn->getType(), false, false);
|
||||
|
||||
assert(false && "Invalid reference to overloaded function");
|
||||
return E->Retain();
|
||||
}
|
||||
|
|
|
@ -556,6 +556,9 @@ namespace {
|
|||
bool isAddressOfOperand);
|
||||
Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E,
|
||||
bool isAddressOfOperand);
|
||||
Sema::OwningExprResult TransformUnresolvedLookupExpr(
|
||||
UnresolvedLookupExpr *E,
|
||||
bool isAddressOfOperand);
|
||||
|
||||
Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
|
||||
bool isAddressOfOperand);
|
||||
|
@ -693,6 +696,55 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E,
|
|||
return getSema().Owned(PE);
|
||||
}
|
||||
|
||||
Sema::OwningExprResult
|
||||
TemplateInstantiator::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
|
||||
bool isAddressOfOperand) {
|
||||
llvm::SmallVector<NamedDecl*, 16> InstDecls;
|
||||
|
||||
bool HasUnresolved = false;
|
||||
|
||||
for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
|
||||
E = Old->decls_end(); I != E; ++I) {
|
||||
NamedDecl *InstD = SemaRef.FindInstantiatedDecl(*I, TemplateArgs);
|
||||
if (!InstD)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// Expand using declarations.
|
||||
if (isa<UsingDecl>(InstD)) {
|
||||
UsingDecl *UD = cast<UsingDecl>(InstD);
|
||||
for (UsingDecl::shadow_iterator UI = UD->shadow_begin(),
|
||||
UE = UD->shadow_end(); UI != UE; ++UI) {
|
||||
UsingShadowDecl *Shadow = *UI;
|
||||
if (isa<UnresolvedUsingValueDecl>(Shadow->getUnderlyingDecl()))
|
||||
HasUnresolved = true;
|
||||
InstDecls.push_back(Shadow);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isa<UnresolvedUsingValueDecl>(InstD->getUnderlyingDecl()))
|
||||
HasUnresolved = true;
|
||||
InstDecls.push_back(InstD);
|
||||
}
|
||||
|
||||
CXXScopeSpec SS;
|
||||
NestedNameSpecifier *Qualifier = 0;
|
||||
if (Old->getQualifier()) {
|
||||
Qualifier = TransformNestedNameSpecifier(Old->getQualifier(),
|
||||
Old->getQualifierRange());
|
||||
if (!Qualifier)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
SS.setScopeRep(Qualifier);
|
||||
SS.setRange(Old->getQualifierRange());
|
||||
}
|
||||
|
||||
return SemaRef.BuildDeclarationNameExpr(&SS, Old->getNameLoc(),
|
||||
Old->getName(), Old->requiresADL(),
|
||||
InstDecls.data(), InstDecls.size());
|
||||
}
|
||||
|
||||
Sema::OwningExprResult
|
||||
TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
|
||||
bool isAddressOfOperand) {
|
||||
|
@ -788,46 +840,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
|
|||
if (!InstD)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// Flatten using declarations into their shadow declarations.
|
||||
if (isa<UsingDecl>(InstD)) {
|
||||
UsingDecl *UD = cast<UsingDecl>(InstD);
|
||||
|
||||
bool HasNonFunction = false;
|
||||
|
||||
llvm::SmallVector<NamedDecl*, 8> Decls;
|
||||
for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
|
||||
E = UD->shadow_end(); I != E; ++I) {
|
||||
NamedDecl *TD = (*I)->getTargetDecl();
|
||||
if (!TD->isFunctionOrFunctionTemplate())
|
||||
HasNonFunction = true;
|
||||
|
||||
Decls.push_back(TD);
|
||||
}
|
||||
|
||||
if (Decls.empty())
|
||||
return SemaRef.ExprError();
|
||||
|
||||
if (Decls.size() == 1)
|
||||
InstD = Decls[0];
|
||||
else if (!HasNonFunction) {
|
||||
OverloadedFunctionDecl *OFD
|
||||
= OverloadedFunctionDecl::Create(SemaRef.Context,
|
||||
UD->getDeclContext(),
|
||||
UD->getDeclName());
|
||||
for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Decls.begin(),
|
||||
E = Decls.end(); I != E; ++I)
|
||||
if (isa<FunctionDecl>(*I))
|
||||
OFD->addOverload(cast<FunctionDecl>(*I));
|
||||
else
|
||||
OFD->addOverload(cast<FunctionTemplateDecl>(*I));
|
||||
|
||||
InstD = OFD;
|
||||
} else {
|
||||
// FIXME
|
||||
assert(false && "using declaration resolved to mixed set");
|
||||
return SemaRef.ExprError();
|
||||
}
|
||||
}
|
||||
assert(!isa<UsingDecl>(InstD) && "decl ref instantiated to UsingDecl");
|
||||
|
||||
CXXScopeSpec SS;
|
||||
NestedNameSpecifier *Qualifier = 0;
|
||||
|
@ -841,10 +854,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
|
|||
SS.setRange(E->getQualifierRange());
|
||||
}
|
||||
|
||||
return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD,
|
||||
/*FIXME:*/false,
|
||||
&SS,
|
||||
isAddressOfOperand);
|
||||
return SemaRef.BuildDeclarationNameExpr(&SS, E->getLocation(), InstD);
|
||||
}
|
||||
|
||||
Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
|
||||
|
|
|
@ -4558,10 +4558,10 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
|
|||
|
||||
template<typename Derived>
|
||||
Sema::OwningExprResult
|
||||
TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
|
||||
UnresolvedFunctionNameExpr *E,
|
||||
TreeTransform<Derived>::TransformUnresolvedLookupExpr(
|
||||
UnresolvedLookupExpr *E,
|
||||
bool isAddressOfOperand) {
|
||||
// There is no transformation we can apply to an unresolved function name.
|
||||
// There is no transformation we can apply to an unresolved lookup.
|
||||
return SemaRef.Owned(E->Retain());
|
||||
}
|
||||
|
||||
|
@ -5384,8 +5384,7 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
|
|||
ExprArg Second) {
|
||||
Expr *FirstExpr = (Expr *)First.get();
|
||||
Expr *SecondExpr = (Expr *)Second.get();
|
||||
DeclRefExpr *DRE
|
||||
= cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
|
||||
Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
|
||||
bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
|
||||
|
||||
// Determine whether this should be a builtin operation.
|
||||
|
@ -5393,7 +5392,7 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
|
|||
if (!FirstExpr->getType()->isOverloadableType() &&
|
||||
!SecondExpr->getType()->isOverloadableType())
|
||||
return getSema().CreateBuiltinArraySubscriptExpr(move(First),
|
||||
DRE->getLocStart(),
|
||||
CalleeExpr->getLocStart(),
|
||||
move(Second), OpLoc);
|
||||
} else if (Op == OO_Arrow) {
|
||||
// -> is never a builtin operation.
|
||||
|
@ -5428,10 +5427,18 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
|
|||
// used during overload resolution.
|
||||
Sema::FunctionSet Functions;
|
||||
|
||||
// FIXME: Do we have to check
|
||||
// IsAcceptableNonMemberOperatorCandidate for each of these?
|
||||
for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
|
||||
Functions.insert(*F);
|
||||
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
|
||||
assert(ULE->requiresADL());
|
||||
|
||||
// FIXME: Do we have to check
|
||||
// IsAcceptableNonMemberOperatorCandidate for each of these?
|
||||
for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
|
||||
E = ULE->decls_end(); I != E; ++I)
|
||||
Functions.insert(AnyFunctionDecl::getFromNamedDecl(*I));
|
||||
} else {
|
||||
Functions.insert(AnyFunctionDecl::getFromNamedDecl(
|
||||
cast<DeclRefExpr>(CalleeExpr)->getDecl()));
|
||||
}
|
||||
|
||||
// Add any functions found via argument-dependent lookup.
|
||||
Expr *Args[2] = { FirstExpr, SecondExpr };
|
||||
|
@ -5449,8 +5456,10 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
|
|||
}
|
||||
|
||||
if (Op == OO_Subscript)
|
||||
return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
|
||||
move(First),move(Second));
|
||||
return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
|
||||
OpLoc,
|
||||
move(First),
|
||||
move(Second));
|
||||
|
||||
// Create the overloaded operator invocation for binary operators.
|
||||
BinaryOperator::Opcode Opc =
|
||||
|
|
|
@ -41,8 +41,8 @@ namespace N1 {
|
|||
|
||||
void m()
|
||||
{
|
||||
void f(int, int); // expected-note{{candidate}}
|
||||
f(4); // expected-error{{no matching}}
|
||||
void f(int, int);
|
||||
f(4); // expected-error{{too few arguments to function call}}
|
||||
void f(int, int = 5); // expected-note{{previous definition}}
|
||||
f(4); // okay
|
||||
void f(int, int = 5); // expected-error{{redefinition of default argument}}
|
||||
|
|
|
@ -15,7 +15,7 @@ int UseGlobalBar;
|
|||
|
||||
@implementation Sprite
|
||||
+ (void)setFoo:(int)foo {
|
||||
sprite = foo; // expected-error {{use of undeclared identifier 'sprite'}}
|
||||
sprite = foo; // expected-error {{instance variable 'sprite' accessed in class method}}
|
||||
spree = foo;
|
||||
Xsprite = foo; // expected-error {{use of undeclared identifier 'Xsprite'}}
|
||||
UseGlobalBar = 10;
|
||||
|
|
Loading…
Reference in New Issue