зеркало из https://github.com/microsoft/clang-1.git
Handle substitutions into the "first qualifier in scope" of a
qualified member access expression (e.g., t->U::member) when that first qualifier refers to a template parameters. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84612 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
8f99993856
Коммит
6cd219879f
|
@ -400,6 +400,10 @@ namespace {
|
|||
/// instantiating it.
|
||||
Decl *TransformDefinition(Decl *D);
|
||||
|
||||
/// \bried Transform the first qualifier within a scope by instantiating the
|
||||
/// declaration.
|
||||
NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
|
||||
|
||||
/// \brief Rebuild the exception declaration and register the declaration
|
||||
/// as an instantiated local.
|
||||
VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
|
||||
|
@ -457,6 +461,31 @@ Decl *TemplateInstantiator::TransformDefinition(Decl *D) {
|
|||
return Inst;
|
||||
}
|
||||
|
||||
NamedDecl *
|
||||
TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
|
||||
SourceLocation Loc) {
|
||||
// If the first part of the nested-name-specifier was a template type
|
||||
// parameter, instantiate that type parameter down to a tag type.
|
||||
if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) {
|
||||
const TemplateTypeParmType *TTP
|
||||
= cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD));
|
||||
if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
|
||||
QualType T = TemplateArgs(TTP->getDepth(), TTP->getIndex()).getAsType();
|
||||
if (T.isNull())
|
||||
return cast_or_null<NamedDecl>(TransformDecl(D));
|
||||
|
||||
if (const TagType *Tag = T->getAs<TagType>())
|
||||
return Tag->getDecl();
|
||||
|
||||
// The resulting type is not a tag; complain.
|
||||
getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return cast_or_null<NamedDecl>(TransformDecl(D));
|
||||
}
|
||||
|
||||
VarDecl *
|
||||
TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
|
||||
QualType T,
|
||||
|
|
|
@ -236,6 +236,19 @@ public:
|
|||
/// Subclasses may override this function to provide alternate behavior.
|
||||
Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
|
||||
|
||||
/// \brief Transform the given declaration, which was the first part of a
|
||||
/// nested-name-specifier in a member access expression.
|
||||
///
|
||||
/// This specific declaration transformation only applies to the first
|
||||
/// identifier in a nested-name-specifier of a member access expression, e.g.,
|
||||
/// the \c T in \c x->T::member
|
||||
///
|
||||
/// By default, invokes TransformDecl() to transform the declaration.
|
||||
/// Subclasses may override this function to provide alternate behavior.
|
||||
NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
|
||||
return cast_or_null<NamedDecl>(getDerived().TransformDecl(D));
|
||||
}
|
||||
|
||||
/// \brief Transform the given nested-name-specifier.
|
||||
///
|
||||
/// By default, transforms all of the types and declarations within the
|
||||
|
@ -4195,6 +4208,7 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
|
|||
if (Base.isInvalid())
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// Start the member reference and compute the object's type.
|
||||
Sema::TypeTy *ObjectType = 0;
|
||||
Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
|
||||
E->getOperatorLoc(),
|
||||
|
@ -4203,12 +4217,12 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
|
|||
if (Base.isInvalid())
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// FIXME: The first qualifier found might be a template type parameter,
|
||||
// in which case there is no transformed declaration to refer to (it might
|
||||
// refer to a built-in type!).
|
||||
// Transform the first part of the nested-name-specifier that qualifies
|
||||
// the member name.
|
||||
NamedDecl *FirstQualifierInScope
|
||||
= cast_or_null<NamedDecl>(
|
||||
getDerived().TransformDecl(E->getFirstQualifierFoundInScope()));
|
||||
= getDerived().TransformFirstQualifierInScope(
|
||||
E->getFirstQualifierFoundInScope(),
|
||||
E->getQualifierRange().getBegin());
|
||||
|
||||
NestedNameSpecifier *Qualifier = 0;
|
||||
if (E->getQualifier()) {
|
||||
|
|
|
@ -24,8 +24,7 @@ struct XDerived : public X {
|
|||
};
|
||||
|
||||
void test_f1(XDerived xd) {
|
||||
// FIXME: Not quite functional yet.
|
||||
// int &ir = f1<X>(xd);
|
||||
int &ir = f1<X>(xd);
|
||||
}
|
||||
|
||||
// PR5213
|
||||
|
|
Загрузка…
Ссылка в новой задаче