зеркало из https://github.com/microsoft/clang-1.git
The member classes of a current instantiation aren't necessarily a
current instantiation, even though we have a RecordDecl describing them. Fixes PR9255. Amusingly, I've had this patch sitting around for a month or two because it was "obviously" wrong, but hadn't gotten around to writing a test case to submit the fix :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126038 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
e41721e7df
Коммит
d9ea180032
|
@ -24,14 +24,26 @@
|
|||
using namespace clang;
|
||||
|
||||
/// \brief Find the current instantiation that associated with the given type.
|
||||
static CXXRecordDecl *getCurrentInstantiationOf(QualType T) {
|
||||
static CXXRecordDecl *getCurrentInstantiationOf(QualType T,
|
||||
DeclContext *CurContext) {
|
||||
if (T.isNull())
|
||||
return 0;
|
||||
|
||||
const Type *Ty = T->getCanonicalTypeInternal().getTypePtr();
|
||||
if (isa<RecordType>(Ty))
|
||||
return cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
|
||||
else if (isa<InjectedClassNameType>(Ty))
|
||||
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
|
||||
CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
|
||||
if (!T->isDependentType())
|
||||
return Record;
|
||||
|
||||
// This may be a member of a class template or class template partial
|
||||
// specialization. If it's part of the current semantic context, then it's
|
||||
// an injected-class-name;
|
||||
for (; !CurContext->isFileContext(); CurContext = CurContext->getParent())
|
||||
if (CurContext->Equals(Record))
|
||||
return Record;
|
||||
|
||||
return 0;
|
||||
} else if (isa<InjectedClassNameType>(Ty))
|
||||
return cast<InjectedClassNameType>(Ty)->getDecl();
|
||||
else
|
||||
return 0;
|
||||
|
@ -45,10 +57,11 @@ static CXXRecordDecl *getCurrentInstantiationOf(QualType T) {
|
|||
/// or NULL if the declaration context cannot be computed (e.g., because it is
|
||||
/// dependent and not the current instantiation).
|
||||
DeclContext *Sema::computeDeclContext(QualType T) {
|
||||
if (!T->isDependentType())
|
||||
if (const TagType *Tag = T->getAs<TagType>())
|
||||
return Tag->getDecl();
|
||||
|
||||
return ::getCurrentInstantiationOf(T);
|
||||
return ::getCurrentInstantiationOf(T, CurContext);
|
||||
}
|
||||
|
||||
/// \brief Compute the DeclContext that is associated with the given
|
||||
|
@ -174,7 +187,7 @@ CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) {
|
|||
return 0;
|
||||
|
||||
QualType T = QualType(NNS->getAsType(), 0);
|
||||
return ::getCurrentInstantiationOf(T);
|
||||
return ::getCurrentInstantiationOf(T, CurContext);
|
||||
}
|
||||
|
||||
/// \brief Require that the context specified by SS be complete.
|
||||
|
|
|
@ -199,3 +199,19 @@ namespace Expressions {
|
|||
typename Enable_If<Is_Same<U, Class<T> >::value, void>::type
|
||||
Class<T>::foo() {}
|
||||
}
|
||||
|
||||
namespace PR9255 {
|
||||
template<typename T>
|
||||
class X0 {
|
||||
public:
|
||||
class Inner1;
|
||||
|
||||
class Inner2 {
|
||||
public:
|
||||
void f()
|
||||
{
|
||||
Inner1::f.g();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче