Implement the notions of the "current instantiation" and "unknown
specialization" within a C++ template, and permit name lookup into the
current instantiation. For example, given:

  template<typename T, typename U>
  struct X {
    typedef T type;

    X* x1;  // current instantiation
    X<T, U> *x2; // current instantiation
    X<U, T> *x3; // not current instantiation
    ::X<type, U> *x4; // current instantiation
    X<typename X<type, U>::type, U>: *x5; // current instantiation
  };



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71471 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 0e1daea..3938978 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -2170,16 +2170,29 @@
 QualType
 Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
                         SourceRange Range) {
-  if (NNS->isDependent()) // FIXME: member of the current instantiation!
-    return Context.getTypenameType(NNS, &II);
+  CXXRecordDecl *CurrentInstantiation = 0;
+  if (NNS->isDependent()) {
+    CurrentInstantiation = getCurrentInstantiationOf(NNS);
 
-  CXXScopeSpec SS;
-  SS.setScopeRep(NNS);
-  SS.setRange(Range);
-  if (RequireCompleteDeclContext(SS))
-    return QualType();
+    // If the nested-name-specifier does not refer to the current
+    // instantiation, then build a typename type.
+    if (!CurrentInstantiation)
+      return Context.getTypenameType(NNS, &II);
+  }
 
-  DeclContext *Ctx = computeDeclContext(SS);
+  DeclContext *Ctx = 0;
+
+  if (CurrentInstantiation)
+    Ctx = CurrentInstantiation;
+  else {
+    CXXScopeSpec SS;
+    SS.setScopeRep(NNS);
+    SS.setRange(Range);
+    if (RequireCompleteDeclContext(SS))
+      return QualType();
+
+    Ctx = computeDeclContext(SS);
+  }
   assert(Ctx && "No declaration context?");
 
   DeclarationName Name(&II);