forked from OSchip/llvm-project
Implement tree transformations for DeclarationNames. Among other
things, this means that we can properly cope with member access expressions such as t->operator T() where T is a template parameter (or other dependent type). llvm-svn: 80957
This commit is contained in:
parent
d93c668f00
commit
f816bd70ce
|
@ -247,6 +247,15 @@ public:
|
|||
QualType ObjectType = QualType(),
|
||||
NamedDecl *FirstQualifierInScope = 0);
|
||||
|
||||
/// \brief Transform the given declaration name.
|
||||
///
|
||||
/// By default, transforms the types of conversion function, constructor,
|
||||
/// and destructor names and then (if needed) rebuilds the declaration name.
|
||||
/// Identifiers and selectors are returned unmodified. Sublcasses may
|
||||
/// override this function to provide alternate behavior.
|
||||
DeclarationName TransformDeclarationName(DeclarationName Name,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// \brief Transform the given template name.
|
||||
///
|
||||
/// By default, transforms the template name by transforming the declarations
|
||||
|
@ -1667,6 +1676,39 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
DeclarationName
|
||||
TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
|
||||
SourceLocation Loc) {
|
||||
if (!Name)
|
||||
return Name;
|
||||
|
||||
switch (Name.getNameKind()) {
|
||||
case DeclarationName::Identifier:
|
||||
case DeclarationName::ObjCZeroArgSelector:
|
||||
case DeclarationName::ObjCOneArgSelector:
|
||||
case DeclarationName::ObjCMultiArgSelector:
|
||||
case DeclarationName::CXXOperatorName:
|
||||
case DeclarationName::CXXUsingDirective:
|
||||
return Name;
|
||||
|
||||
case DeclarationName::CXXConstructorName:
|
||||
case DeclarationName::CXXDestructorName:
|
||||
case DeclarationName::CXXConversionFunctionName: {
|
||||
TemporaryBase Rebase(*this, Loc, Name);
|
||||
QualType T = getDerived().TransformType(Name.getCXXNameType());
|
||||
if (T.isNull())
|
||||
return DeclarationName();
|
||||
|
||||
return SemaRef.Context.DeclarationNames.getCXXSpecialName(
|
||||
Name.getNameKind(),
|
||||
SemaRef.Context.getCanonicalType(T));
|
||||
}
|
||||
}
|
||||
|
||||
return DeclarationName();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
TemplateName
|
||||
TreeTransform<Derived>::TransformTemplateName(TemplateName Name) {
|
||||
|
@ -3838,8 +3880,10 @@ TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
|
|||
if (!NNS)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// FIXME: Transform the declaration name
|
||||
DeclarationName Name = E->getDeclName();
|
||||
DeclarationName Name
|
||||
= getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
|
||||
if (!Name)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
NNS == E->getQualifier() &&
|
||||
|
@ -4078,9 +4122,11 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
|
|||
return SemaRef.ExprError();
|
||||
}
|
||||
|
||||
// FIXME: Transform the declaration name
|
||||
DeclarationName Name = E->getMember();
|
||||
|
||||
DeclarationName Name
|
||||
= getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc());
|
||||
if (!Name)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
Base.get() == E->getBase() &&
|
||||
Qualifier == E->getQualifier() &&
|
||||
|
|
|
@ -46,3 +46,16 @@ void test_f0_through_typedef2(X0 x0, X1 x1) {
|
|||
}
|
||||
|
||||
|
||||
struct X2 {
|
||||
operator int() const;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
T convert(const U& value) {
|
||||
return value.operator T(); // expected-error{{operator long}}
|
||||
}
|
||||
|
||||
void test_convert(X2 x2) {
|
||||
convert<int>(x2);
|
||||
convert<long>(x2); // expected-note{{instantiation}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue