зеркало из https://github.com/microsoft/clang.git
Extract a common base class between UnresolvedLookupExpr and
UnresolvedMemberExpr and employ it in a few places where it's useful. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95072 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b217bcce14
Коммит
7bb12da2b0
|
@ -1129,6 +1129,112 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
/// \brief A reference to an overloaded function set, either an
|
||||
/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr.
|
||||
class OverloadExpr : public Expr {
|
||||
/// The results. These are undesugared, which is to say, they may
|
||||
/// include UsingShadowDecls. Access is relative to the naming
|
||||
/// class.
|
||||
UnresolvedSet<4> Results;
|
||||
|
||||
/// The common name of these declarations.
|
||||
DeclarationName Name;
|
||||
|
||||
/// The scope specifier, if any.
|
||||
NestedNameSpecifier *Qualifier;
|
||||
|
||||
/// The source range of the scope specifier.
|
||||
SourceRange QualifierRange;
|
||||
|
||||
/// The location of the name.
|
||||
SourceLocation NameLoc;
|
||||
|
||||
/// True if the name was a template-id.
|
||||
bool HasExplicitTemplateArgs;
|
||||
|
||||
protected:
|
||||
OverloadExpr(StmtClass K, QualType T, bool Dependent,
|
||||
NestedNameSpecifier *Qualifier, SourceRange QRange,
|
||||
DeclarationName Name, SourceLocation NameLoc,
|
||||
bool HasTemplateArgs)
|
||||
: Expr(K, T, Dependent, Dependent),
|
||||
Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
|
||||
NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs)
|
||||
{}
|
||||
|
||||
public:
|
||||
/// Computes whether an unresolved lookup on the given declarations
|
||||
/// and optional template arguments is type- and value-dependent.
|
||||
static bool ComputeDependence(UnresolvedSetIterator Begin,
|
||||
UnresolvedSetIterator End,
|
||||
const TemplateArgumentListInfo *Args);
|
||||
|
||||
/// Finds the overloaded expression in the given expression of
|
||||
/// OverloadTy.
|
||||
///
|
||||
/// \return the expression (which must be there) and true if it is
|
||||
/// within an address-of operator.
|
||||
static llvm::PointerIntPair<OverloadExpr*,1> find(Expr *E) {
|
||||
assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
|
||||
|
||||
bool op = false;
|
||||
E = E->IgnoreParens();
|
||||
if (isa<UnaryOperator>(E))
|
||||
op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
|
||||
return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(E), op);
|
||||
}
|
||||
|
||||
void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
|
||||
Results.append(Begin, End);
|
||||
}
|
||||
|
||||
typedef UnresolvedSetImpl::iterator decls_iterator;
|
||||
decls_iterator decls_begin() const { return Results.begin(); }
|
||||
decls_iterator decls_end() const { return Results.end(); }
|
||||
|
||||
/// Gets the decls as an unresolved set.
|
||||
const UnresolvedSetImpl &getDecls() { return Results; }
|
||||
|
||||
/// Gets the number of declarations in the unresolved set.
|
||||
unsigned getNumDecls() const { return Results.size(); }
|
||||
|
||||
/// Gets the name looked up.
|
||||
DeclarationName getName() const { return Name; }
|
||||
void setName(DeclarationName N) { Name = N; }
|
||||
|
||||
/// Gets the location of the name.
|
||||
SourceLocation getNameLoc() const { return NameLoc; }
|
||||
void setNameLoc(SourceLocation Loc) { NameLoc = Loc; }
|
||||
|
||||
/// 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; }
|
||||
|
||||
/// \brief Determines whether this expression had an explicit
|
||||
/// template argument list, e.g. f<int>.
|
||||
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
|
||||
|
||||
ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below
|
||||
|
||||
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
|
||||
return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs();
|
||||
}
|
||||
|
||||
ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() {
|
||||
if (hasExplicitTemplateArgs())
|
||||
return &getExplicitTemplateArgs();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == UnresolvedLookupExprClass ||
|
||||
T->getStmtClass() == UnresolvedMemberExprClass;
|
||||
}
|
||||
static bool classof(const OverloadExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// \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:
|
||||
|
@ -1139,30 +1245,7 @@ public:
|
|||
/// 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<4> Results;
|
||||
|
||||
/// The name declared.
|
||||
DeclarationName Name;
|
||||
|
||||
/// The naming class (C++ [class.access.base]p5) of the lookup, if
|
||||
/// any. This can generally be recalculated from the context chain,
|
||||
/// but that can be fairly expensive for unqualified lookups. If we
|
||||
/// want to improve memory use here, this could go in a union
|
||||
/// against the qualified-lookup bits.
|
||||
CXXRecordDecl *NamingClass;
|
||||
|
||||
/// The qualifier given, if any.
|
||||
NestedNameSpecifier *Qualifier;
|
||||
|
||||
/// The source range of the nested name specifier.
|
||||
SourceRange QualifierRange;
|
||||
|
||||
/// The location of the name.
|
||||
SourceLocation NameLoc;
|
||||
|
||||
class UnresolvedLookupExpr : public OverloadExpr {
|
||||
/// True if these lookup results should be extended by
|
||||
/// argument-dependent lookup if this is the operand of a function
|
||||
/// call.
|
||||
|
@ -1172,19 +1255,20 @@ class UnresolvedLookupExpr : public Expr {
|
|||
/// trivially rederivable if we urgently need to kill this field.
|
||||
bool Overloaded;
|
||||
|
||||
/// True if the name looked up had explicit template arguments.
|
||||
/// This requires all the results to be function templates.
|
||||
bool HasExplicitTemplateArgs;
|
||||
/// The naming class (C++ [class.access.base]p5) of the lookup, if
|
||||
/// any. This can generally be recalculated from the context chain,
|
||||
/// but that can be fairly expensive for unqualified lookups. If we
|
||||
/// want to improve memory use here, this could go in a union
|
||||
/// against the qualified-lookup bits.
|
||||
CXXRecordDecl *NamingClass;
|
||||
|
||||
UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass,
|
||||
NestedNameSpecifier *Qualifier, SourceRange QRange,
|
||||
DeclarationName Name, SourceLocation NameLoc,
|
||||
bool RequiresADL, bool Overloaded, bool HasTemplateArgs)
|
||||
: Expr(UnresolvedLookupExprClass, T, Dependent, Dependent),
|
||||
Name(Name), NamingClass(NamingClass),
|
||||
Qualifier(Qualifier), QualifierRange(QRange),
|
||||
NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded),
|
||||
HasExplicitTemplateArgs(HasTemplateArgs)
|
||||
: OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange,
|
||||
Name, NameLoc, HasTemplateArgs),
|
||||
RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
@ -1212,23 +1296,6 @@ public:
|
|||
bool ADL,
|
||||
const TemplateArgumentListInfo &Args);
|
||||
|
||||
/// Computes whether an unresolved lookup on the given declarations
|
||||
/// and optional template arguments is type- and value-dependent.
|
||||
static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
|
||||
UnresolvedSetImpl::const_iterator End,
|
||||
const TemplateArgumentListInfo *Args);
|
||||
|
||||
void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
|
||||
Results.append(Begin, End);
|
||||
}
|
||||
|
||||
typedef UnresolvedSetImpl::iterator decls_iterator;
|
||||
decls_iterator decls_begin() const { return Results.begin(); }
|
||||
decls_iterator decls_end() const { return Results.end(); }
|
||||
|
||||
/// Retrieves the decls as an unresolved set.
|
||||
const UnresolvedSetImpl &getDecls() { return Results; }
|
||||
|
||||
/// True if this declaration should be extended by
|
||||
/// argument-dependent lookup.
|
||||
bool requiresADL() const { return RequiresADL; }
|
||||
|
@ -1236,30 +1303,20 @@ public:
|
|||
/// True if this lookup is overloaded.
|
||||
bool isOverloaded() const { return Overloaded; }
|
||||
|
||||
/// Fetches the name looked up.
|
||||
DeclarationName getName() const { return Name; }
|
||||
|
||||
/// Gets the location of the name.
|
||||
SourceLocation getNameLoc() const { return NameLoc; }
|
||||
|
||||
/// Gets the 'naming class' (in the sense of C++0x
|
||||
/// [class.access.base]p5) of the lookup. This is the scope
|
||||
/// that was looked in to find these results.
|
||||
CXXRecordDecl *getNamingClass() const { return NamingClass; }
|
||||
|
||||
/// 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; }
|
||||
|
||||
/// Determines whether this lookup had explicit template arguments.
|
||||
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
|
||||
|
||||
// Note that, inconsistently with the explicit-template-argument AST
|
||||
// nodes, users are *forbidden* from calling these methods on objects
|
||||
// without explicit template arguments.
|
||||
|
||||
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
|
||||
assert(hasExplicitTemplateArgs());
|
||||
return *reinterpret_cast<ExplicitTemplateArgumentList*>(this + 1);
|
||||
}
|
||||
|
||||
/// Gets a reference to the explicit template argument list.
|
||||
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
|
||||
assert(hasExplicitTemplateArgs());
|
||||
|
@ -1289,8 +1346,8 @@ public:
|
|||
}
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
SourceRange Range(NameLoc);
|
||||
if (Qualifier) Range.setBegin(QualifierRange.getBegin());
|
||||
SourceRange Range(getNameLoc());
|
||||
if (getQualifier()) Range.setBegin(getQualifierRange().getBegin());
|
||||
if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc());
|
||||
return Range;
|
||||
}
|
||||
|
@ -1802,10 +1859,14 @@ public:
|
|||
/// In the final AST, an explicit access always becomes a MemberExpr.
|
||||
/// An implicit access may become either a MemberExpr or a
|
||||
/// DeclRefExpr, depending on whether the member is static.
|
||||
class UnresolvedMemberExpr : public Expr {
|
||||
/// The results. These are undesugared, which is to say, they may
|
||||
/// include UsingShadowDecls.
|
||||
UnresolvedSet<4> Results;
|
||||
class UnresolvedMemberExpr : public OverloadExpr {
|
||||
/// \brief Whether this member expression used the '->' operator or
|
||||
/// the '.' operator.
|
||||
bool IsArrow : 1;
|
||||
|
||||
/// \brief Whether the lookup results contain an unresolved using
|
||||
/// declaration.
|
||||
bool HasUnresolvedUsing : 1;
|
||||
|
||||
/// \brief The expression for the base pointer or class reference,
|
||||
/// e.g., the \c x in x.f. This can be null if this is an 'unbased'
|
||||
|
@ -1815,47 +1876,9 @@ class UnresolvedMemberExpr : public Expr {
|
|||
/// \brief The type of the base expression; never null.
|
||||
QualType BaseType;
|
||||
|
||||
/// \brief Whether this member expression used the '->' operator or
|
||||
/// the '.' operator.
|
||||
bool IsArrow : 1;
|
||||
|
||||
/// \brief Whether the lookup results contain an unresolved using
|
||||
/// declaration.
|
||||
bool HasUnresolvedUsing : 1;
|
||||
|
||||
/// \brief Whether this member expression has explicitly-specified template
|
||||
/// arguments.
|
||||
bool HasExplicitTemplateArgs : 1;
|
||||
|
||||
/// \brief The location of the '->' or '.' operator.
|
||||
SourceLocation OperatorLoc;
|
||||
|
||||
/// \brief The nested-name-specifier that precedes the member name, if any.
|
||||
NestedNameSpecifier *Qualifier;
|
||||
|
||||
/// \brief The source range covering the nested name specifier.
|
||||
SourceRange QualifierRange;
|
||||
|
||||
/// \brief The member to which this member expression refers, which
|
||||
/// can be a name or an overloaded operator.
|
||||
DeclarationName MemberName;
|
||||
|
||||
/// \brief The location of the member name.
|
||||
SourceLocation MemberLoc;
|
||||
|
||||
/// \brief Retrieve the explicit template argument list that followed the
|
||||
/// member template name.
|
||||
ExplicitTemplateArgumentList *getExplicitTemplateArgs() {
|
||||
assert(HasExplicitTemplateArgs);
|
||||
return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the explicit template argument list that followed the
|
||||
/// member template name, if any.
|
||||
const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const {
|
||||
return const_cast<UnresolvedMemberExpr*>(this)->getExplicitTemplateArgs();
|
||||
}
|
||||
|
||||
UnresolvedMemberExpr(QualType T, bool Dependent,
|
||||
bool HasUnresolvedUsing,
|
||||
Expr *Base, QualType BaseType, bool IsArrow,
|
||||
|
@ -1877,22 +1900,6 @@ public:
|
|||
SourceLocation MemberLoc,
|
||||
const TemplateArgumentListInfo *TemplateArgs);
|
||||
|
||||
/// Adds a declaration to the unresolved set. By assumption, all of
|
||||
/// these happen at initialization time and properties like
|
||||
/// 'Dependent' and 'HasUnresolvedUsing' take them into account.
|
||||
void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) {
|
||||
Results.append(Begin, End);
|
||||
}
|
||||
|
||||
typedef UnresolvedSetImpl::iterator decls_iterator;
|
||||
decls_iterator decls_begin() const { return Results.begin(); }
|
||||
decls_iterator decls_end() const { return Results.end(); }
|
||||
|
||||
unsigned getNumDecls() const { return Results.size(); }
|
||||
|
||||
/// Retrieves the decls as an unresolved set.
|
||||
const UnresolvedSetImpl &getDecls() { return Results; }
|
||||
|
||||
/// \brief True if this is an implicit access, i.e. one in which the
|
||||
/// member being accessed was not written in the source. The source
|
||||
/// location of the operator is invalid in this case.
|
||||
|
@ -1917,60 +1924,60 @@ public:
|
|||
SourceLocation getOperatorLoc() const { return OperatorLoc; }
|
||||
void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that qualifies the member
|
||||
/// name.
|
||||
NestedNameSpecifier *getQualifier() const { return Qualifier; }
|
||||
|
||||
/// \brief Retrieve the source range covering the nested-name-specifier
|
||||
/// that qualifies the member name.
|
||||
SourceRange getQualifierRange() const { return QualifierRange; }
|
||||
|
||||
/// \brief Retrieves the naming class of this lookup.
|
||||
CXXRecordDecl *getNamingClass() const;
|
||||
|
||||
/// \brief Retrieve the name of the member that this expression
|
||||
/// refers to.
|
||||
DeclarationName getMemberName() const { return MemberName; }
|
||||
void setMemberName(DeclarationName N) { MemberName = N; }
|
||||
DeclarationName getMemberName() const { return getName(); }
|
||||
void setMemberName(DeclarationName N) { setName(N); }
|
||||
|
||||
// \brief Retrieve the location of the name of the member that this
|
||||
// expression refers to.
|
||||
SourceLocation getMemberLoc() const { return MemberLoc; }
|
||||
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
|
||||
SourceLocation getMemberLoc() const { return getNameLoc(); }
|
||||
void setMemberLoc(SourceLocation L) { setNameLoc(L); }
|
||||
|
||||
/// \brief Determines whether this member expression actually had a C++
|
||||
/// template argument list explicitly specified, e.g., x.f<int>.
|
||||
bool hasExplicitTemplateArgs() const {
|
||||
return HasExplicitTemplateArgs;
|
||||
/// \brief Retrieve the explicit template argument list that followed the
|
||||
/// member template name.
|
||||
ExplicitTemplateArgumentList &getExplicitTemplateArgs() {
|
||||
assert(hasExplicitTemplateArgs());
|
||||
return *reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the explicit template argument list that followed the
|
||||
/// member template name, if any.
|
||||
const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const {
|
||||
assert(hasExplicitTemplateArgs());
|
||||
return *reinterpret_cast<const ExplicitTemplateArgumentList *>(this + 1);
|
||||
}
|
||||
|
||||
/// \brief Copies the template arguments into the given structure.
|
||||
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
|
||||
getExplicitTemplateArgs()->copyInto(List);
|
||||
getExplicitTemplateArgs().copyInto(List);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the left angle bracket following
|
||||
/// the member name ('<').
|
||||
SourceLocation getLAngleLoc() const {
|
||||
return getExplicitTemplateArgs()->LAngleLoc;
|
||||
return getExplicitTemplateArgs().LAngleLoc;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template arguments provided as part of this
|
||||
/// template-id.
|
||||
const TemplateArgumentLoc *getTemplateArgs() const {
|
||||
return getExplicitTemplateArgs()->getTemplateArgs();
|
||||
return getExplicitTemplateArgs().getTemplateArgs();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the number of template arguments provided as
|
||||
/// part of this template-id.
|
||||
unsigned getNumTemplateArgs() const {
|
||||
return getExplicitTemplateArgs()->NumTemplateArgs;
|
||||
return getExplicitTemplateArgs().NumTemplateArgs;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the right angle bracket
|
||||
/// following the template arguments ('>').
|
||||
SourceLocation getRAngleLoc() const {
|
||||
return getExplicitTemplateArgs()->RAngleLoc;
|
||||
return getExplicitTemplateArgs().RAngleLoc;
|
||||
}
|
||||
|
||||
virtual SourceRange getSourceRange() const {
|
||||
|
@ -1980,12 +1987,12 @@ public:
|
|||
else if (getQualifier())
|
||||
Range.setBegin(getQualifierRange().getBegin());
|
||||
else
|
||||
Range.setBegin(MemberLoc);
|
||||
Range.setBegin(getMemberLoc());
|
||||
|
||||
if (hasExplicitTemplateArgs())
|
||||
Range.setEnd(getRAngleLoc());
|
||||
else
|
||||
Range.setEnd(MemberLoc);
|
||||
Range.setEnd(getMemberLoc());
|
||||
return Range;
|
||||
}
|
||||
|
||||
|
@ -1999,6 +2006,13 @@ public:
|
|||
virtual child_iterator child_end();
|
||||
};
|
||||
|
||||
inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() {
|
||||
if (isa<UnresolvedLookupExpr>(this))
|
||||
return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs();
|
||||
else
|
||||
return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs();
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,10 +137,9 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
|
|||
return ULE;
|
||||
}
|
||||
|
||||
bool UnresolvedLookupExpr::
|
||||
ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
|
||||
UnresolvedSetImpl::const_iterator End,
|
||||
const TemplateArgumentListInfo *Args) {
|
||||
bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
|
||||
UnresolvedSetIterator End,
|
||||
const TemplateArgumentListInfo *Args) {
|
||||
for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
|
||||
if ((*I)->getDeclContext()->isDependentContext())
|
||||
return true;
|
||||
|
@ -646,15 +645,13 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
|
|||
DeclarationName MemberName,
|
||||
SourceLocation MemberLoc,
|
||||
const TemplateArgumentListInfo *TemplateArgs)
|
||||
: Expr(UnresolvedMemberExprClass, T, Dependent, Dependent),
|
||||
Base(Base), BaseType(BaseType), IsArrow(IsArrow),
|
||||
HasUnresolvedUsing(HasUnresolvedUsing),
|
||||
HasExplicitTemplateArgs(TemplateArgs != 0),
|
||||
OperatorLoc(OperatorLoc),
|
||||
Qualifier(Qualifier), QualifierRange(QualifierRange),
|
||||
MemberName(MemberName), MemberLoc(MemberLoc) {
|
||||
: OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
|
||||
Qualifier, QualifierRange, MemberName, MemberLoc,
|
||||
TemplateArgs != 0),
|
||||
IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
|
||||
Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
|
||||
if (TemplateArgs)
|
||||
getExplicitTemplateArgs()->initializeFrom(*TemplateArgs);
|
||||
getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
|
||||
}
|
||||
|
||||
UnresolvedMemberExpr *
|
||||
|
@ -686,8 +683,8 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
|
|||
// It can't be dependent: after all, we were actually able to do the
|
||||
// lookup.
|
||||
const RecordType *RT;
|
||||
if (Qualifier) {
|
||||
Type *T = Qualifier->getAsType();
|
||||
if (getQualifier()) {
|
||||
Type *T = getQualifier()->getAsType();
|
||||
assert(T && "qualifier in member expression does not name type");
|
||||
RT = T->getAs<RecordType>();
|
||||
assert(RT && "qualifier in member expression does not name record");
|
||||
|
|
|
@ -2546,7 +2546,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
|
|||
bool Dependent =
|
||||
BaseExprType->isDependentType() ||
|
||||
R.isUnresolvableResult() ||
|
||||
UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs);
|
||||
OverloadExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs);
|
||||
|
||||
// Suppress any lookup-related diagnostics; we'll do these when we
|
||||
// pick a member.
|
||||
|
|
|
@ -4455,11 +4455,7 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
|
|||
Expr *E = FromExpr->IgnoreParens();
|
||||
if (isa<UnaryOperator>(E))
|
||||
E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
|
||||
DeclarationName Name;
|
||||
if (isa<UnresolvedLookupExpr>(E))
|
||||
Name = cast<UnresolvedLookupExpr>(E)->getName();
|
||||
else
|
||||
Name = cast<UnresolvedMemberExpr>(E)->getMemberName();
|
||||
DeclarationName Name = cast<OverloadExpr>(E)->getName();
|
||||
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload)
|
||||
<< (unsigned) FnKind << FnDesc
|
||||
|
@ -4950,7 +4946,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
|||
}
|
||||
}
|
||||
|
||||
static bool CheckUnresolvedAccess(Sema &S, Expr *E, NamedDecl *D,
|
||||
static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, NamedDecl *D,
|
||||
AccessSpecifier AS) {
|
||||
if (isa<UnresolvedLookupExpr>(E))
|
||||
return S.CheckUnresolvedLookupAccess(cast<UnresolvedLookupExpr>(E), D, AS);
|
||||
|
@ -4994,50 +4990,28 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
return 0;
|
||||
|
||||
// Find the actual overloaded function declaration.
|
||||
if (From->getType() != Context.OverloadTy)
|
||||
return 0;
|
||||
|
||||
// C++ [over.over]p1:
|
||||
// [...] [Note: any redundant set of parentheses surrounding the
|
||||
// overloaded function name is ignored (5.1). ]
|
||||
Expr *OvlExpr = From->IgnoreParens();
|
||||
|
||||
// C++ [over.over]p1:
|
||||
// [...] The overloaded function name can be preceded by the &
|
||||
// operator.
|
||||
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(OvlExpr)) {
|
||||
if (UnOp->getOpcode() == UnaryOperator::AddrOf)
|
||||
OvlExpr = UnOp->getSubExpr()->IgnoreParens();
|
||||
OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
|
||||
TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
|
||||
if (OvlExpr->hasExplicitTemplateArgs()) {
|
||||
OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
|
||||
ExplicitTemplateArgs = &ETABuffer;
|
||||
}
|
||||
|
||||
bool HasExplicitTemplateArgs = false;
|
||||
TemplateArgumentListInfo ExplicitTemplateArgs;
|
||||
const UnresolvedSetImpl *Fns;
|
||||
|
||||
// Look into the overloaded expression.
|
||||
if (UnresolvedLookupExpr *UL
|
||||
= dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
|
||||
Fns = &UL->getDecls();
|
||||
if (UL->hasExplicitTemplateArgs()) {
|
||||
HasExplicitTemplateArgs = true;
|
||||
UL->copyTemplateArgumentsInto(ExplicitTemplateArgs);
|
||||
}
|
||||
} else if (UnresolvedMemberExpr *ME
|
||||
= dyn_cast<UnresolvedMemberExpr>(OvlExpr)) {
|
||||
Fns = &ME->getDecls();
|
||||
if (ME->hasExplicitTemplateArgs()) {
|
||||
HasExplicitTemplateArgs = true;
|
||||
ME->copyTemplateArgumentsInto(ExplicitTemplateArgs);
|
||||
}
|
||||
} else return 0;
|
||||
|
||||
// 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.
|
||||
UnresolvedSet<4> Matches; // contains only FunctionDecls
|
||||
bool FoundNonTemplateFunction = false;
|
||||
for (UnresolvedSetIterator I = Fns->begin(), E = Fns->end(); I != E; ++I) {
|
||||
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
|
||||
E = OvlExpr->decls_end(); I != E; ++I) {
|
||||
// Look through any using declarations to find the underlying function.
|
||||
NamedDecl *Fn = (*I)->getUnderlyingDecl();
|
||||
|
||||
|
@ -5069,8 +5043,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
FunctionDecl *Specialization = 0;
|
||||
TemplateDeductionInfo Info(Context);
|
||||
if (TemplateDeductionResult Result
|
||||
= DeduceTemplateArguments(FunctionTemplate,
|
||||
(HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
|
||||
= DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
|
||||
FunctionType, Specialization, Info)) {
|
||||
// FIXME: make a note of the failed deduction for diagnostics.
|
||||
(void)Result;
|
||||
|
@ -5093,7 +5066,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
|||
continue;
|
||||
|
||||
// If we have explicit template arguments, skip non-templates.
|
||||
if (HasExplicitTemplateArgs)
|
||||
if (OvlExpr->hasExplicitTemplateArgs())
|
||||
continue;
|
||||
} else if (IsMember)
|
||||
continue;
|
||||
|
@ -5192,45 +5165,27 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
|
|||
// C++ [over.over]p1:
|
||||
// [...] [Note: any redundant set of parentheses surrounding the
|
||||
// overloaded function name is ignored (5.1). ]
|
||||
Expr *OvlExpr = From->IgnoreParens();
|
||||
|
||||
// C++ [over.over]p1:
|
||||
// [...] The overloaded function name can be preceded by the &
|
||||
// operator.
|
||||
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(OvlExpr)) {
|
||||
if (UnOp->getOpcode() == UnaryOperator::AddrOf)
|
||||
OvlExpr = UnOp->getSubExpr()->IgnoreParens();
|
||||
}
|
||||
|
||||
bool HasExplicitTemplateArgs = false;
|
||||
TemplateArgumentListInfo ExplicitTemplateArgs;
|
||||
const UnresolvedSetImpl *Fns;
|
||||
|
||||
// Look into the overloaded expression.
|
||||
if (UnresolvedLookupExpr *UL
|
||||
= dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
|
||||
Fns = &UL->getDecls();
|
||||
if (UL->hasExplicitTemplateArgs()) {
|
||||
HasExplicitTemplateArgs = true;
|
||||
UL->copyTemplateArgumentsInto(ExplicitTemplateArgs);
|
||||
}
|
||||
} else if (UnresolvedMemberExpr *ME
|
||||
= dyn_cast<UnresolvedMemberExpr>(OvlExpr)) {
|
||||
Fns = &ME->getDecls();
|
||||
if (ME->hasExplicitTemplateArgs()) {
|
||||
HasExplicitTemplateArgs = true;
|
||||
ME->copyTemplateArgumentsInto(ExplicitTemplateArgs);
|
||||
}
|
||||
} else return 0;
|
||||
|
||||
if (From->getType() != Context.OverloadTy)
|
||||
return 0;
|
||||
|
||||
OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
|
||||
|
||||
// If we didn't actually find any template-ids, we're done.
|
||||
if (Fns->empty() || !HasExplicitTemplateArgs)
|
||||
if (!OvlExpr->hasExplicitTemplateArgs())
|
||||
return 0;
|
||||
|
||||
TemplateArgumentListInfo ExplicitTemplateArgs;
|
||||
OvlExpr->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
|
||||
|
||||
// Look through all of the overloaded functions, searching for one
|
||||
// whose type matches exactly.
|
||||
FunctionDecl *Matched = 0;
|
||||
for (UnresolvedSetIterator I = Fns->begin(), E = Fns->end(); I != E; ++I) {
|
||||
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
|
||||
E = OvlExpr->decls_end(); I != E; ++I) {
|
||||
// C++0x [temp.arg.explicit]p3:
|
||||
// [...] In contexts where deduction is done and fails, or in contexts
|
||||
// where deduction is not done, if a template argument list is
|
||||
|
|
|
@ -1324,34 +1324,19 @@ static QualType GetTypeOfFunction(ASTContext &Context,
|
|||
static QualType
|
||||
ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
|
||||
Expr *Arg, QualType ParamType) {
|
||||
bool isAddressOfOperand = false;
|
||||
llvm::PointerIntPair<OverloadExpr*,1> R = OverloadExpr::find(Arg);
|
||||
|
||||
Arg = Arg->IgnoreParens();
|
||||
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
|
||||
assert(UnOp->getOpcode() == UnaryOperator::AddrOf);
|
||||
isAddressOfOperand = true;
|
||||
Arg = UnOp->getSubExpr()->IgnoreParens();
|
||||
}
|
||||
|
||||
const UnresolvedSetImpl *Decls;
|
||||
bool HasExplicitArgs;
|
||||
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg)) {
|
||||
Decls = &ULE->getDecls();
|
||||
HasExplicitArgs = ULE->hasExplicitTemplateArgs();
|
||||
} else {
|
||||
UnresolvedMemberExpr *UME = cast<UnresolvedMemberExpr>(Arg);
|
||||
Decls = &UME->getDecls();
|
||||
HasExplicitArgs = ULE->hasExplicitTemplateArgs();
|
||||
}
|
||||
bool isAddressOfOperand = bool(R.getInt());
|
||||
OverloadExpr *Ovl = R.getPointer();
|
||||
|
||||
// If there were explicit template arguments, we can only find
|
||||
// something via C++ [temp.arg.explicit]p3, i.e. if the arguments
|
||||
// unambiguously name a full specialization.
|
||||
if (HasExplicitArgs) {
|
||||
if (Ovl->hasExplicitTemplateArgs()) {
|
||||
// But we can still look for an explicit specialization.
|
||||
if (FunctionDecl *ExplicitSpec
|
||||
= S.ResolveSingleFunctionTemplateSpecialization(Arg))
|
||||
return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
|
||||
= S.ResolveSingleFunctionTemplateSpecialization(Ovl))
|
||||
return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
@ -1365,8 +1350,8 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
|
|||
return QualType();
|
||||
|
||||
QualType Match;
|
||||
for (UnresolvedSetIterator I = Decls->begin(),
|
||||
E = Decls->end(); I != E; ++I) {
|
||||
for (UnresolvedSetIterator I = Ovl->decls_begin(),
|
||||
E = Ovl->decls_end(); I != E; ++I) {
|
||||
NamedDecl *D = (*I)->getUnderlyingDecl();
|
||||
|
||||
// - If the argument is an overload set containing one or more
|
||||
|
|
Загрузка…
Ссылка в новой задаче