[cfe-commits] r126038 - in /cfe/trunk: lib/Sema/SemaCXXScopeSpec.cpp test/SemaTemplate/current-instantiation.cpp

Douglas Gregor dgregor at apple.com
Sat Feb 19 11:24:40 PST 2011


Author: dgregor
Date: Sat Feb 19 13:24:40 2011
New Revision: 126038

URL: http://llvm.org/viewvc/llvm-project?rev=126038&view=rev
Log:
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 :)

Modified:
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/test/SemaTemplate/current-instantiation.cpp

Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=126038&r1=126037&r2=126038&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Sat Feb 19 13:24:40 2011
@@ -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 @@
 /// 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 (const TagType *Tag = T->getAs<TagType>())
-    return Tag->getDecl();
+  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 @@
     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.

Modified: cfe/trunk/test/SemaTemplate/current-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/current-instantiation.cpp?rev=126038&r1=126037&r2=126038&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/current-instantiation.cpp (original)
+++ cfe/trunk/test/SemaTemplate/current-instantiation.cpp Sat Feb 19 13:24:40 2011
@@ -199,3 +199,19 @@
   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();
+      }
+    };
+  };
+}





More information about the cfe-commits mailing list