Introduce a new expression type, UnresolvedDeclRefExpr, that describes
dependent qualified-ids such as

  Fibonacci<N - 1>::value

where N is a template parameter. These references are "unresolved"
because the name is dependent and, therefore, cannot be resolved to a
declaration node (as we would do for a DeclRefExpr or
QualifiedDeclRefExpr). UnresolvedDeclRefExprs instantiate to
DeclRefExprs, QualifiedDeclRefExprs, etc.

Also, be a bit more careful about keeping only a single set of
specializations for a class template, and instantiating from the
definition of that template rather than a previous declaration. In
general, we need a better solution for this for all TagDecls, because
it's too easy to accidentally look at a declaration that isn't the
definition.

We can now process a simple Fibonacci computation described as a
template metaprogram.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67308 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index b15f6ab..e43d4b8 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -613,6 +613,21 @@
   // Could be enum-constant, value decl, instance variable, etc.
   if (SS && SS->isInvalid())
     return ExprError();
+
+  // C++ [temp.dep.expr]p3:
+  //   An id-expression is type-dependent if it contains:
+  //     -- a nested-name-specifier that contains a class-name that
+  //        names a dependent type.
+  if (SS && isDependentScopeSpecifier(*SS)) {
+    llvm::SmallVector<NestedNameSpecifier, 16> Specs;
+    for (CXXScopeSpec::iterator Spec = SS->begin(), SpecEnd = SS->end();
+         Spec != SpecEnd; ++Spec)
+      Specs.push_back(NestedNameSpecifier::getFromOpaquePtr(*Spec));
+    return Owned(UnresolvedDeclRefExpr::Create(Context, Name, Loc,
+                                               SS->getRange(), &Specs[0],
+                                               Specs.size()));
+  }
+
   LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
                                          false, true, Loc);