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);