[PATCH] Instantiate UnresolvedLookupExpr to MemberExpr when appropriate

Reid Kleckner rnk at google.com
Tue Dec 16 16:07:31 PST 2014


Hi rsmith,

During the initial template parse for this code, 'member' is unresolved
and we don't know anything about it:

  struct A { int member };
  template <typename T>
  struct B : public T {
    using T::member;
    static void f() {
      (void)member; // Could be static or non-static.
    }
  };
  template class B<A>;

The pattern declaration contains an UnresolvedLookupExpr rather than an
UnresolvedMemberExpr. Later we have to notice that the decl resolved to
an instance member and form a MemberExpr if so.

http://reviews.llvm.org/D6700

Files:
  lib/Sema/SemaExprMember.cpp
  lib/Sema/TreeTransform.h
  test/SemaTemplate/instantiate-using-decl.cpp

Index: lib/Sema/SemaExprMember.cpp
===================================================================
--- lib/Sema/SemaExprMember.cpp
+++ lib/Sema/SemaExprMember.cpp
@@ -90,7 +90,6 @@
 /// conservatively answer "yes", in which case some errors will simply
 /// not be caught until template-instantiation.
 static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
-                                            Scope *CurScope,
                                             const LookupResult &R) {
   assert(!R.empty() && (*R.begin())->isCXXClassMember());
 
@@ -205,6 +204,9 @@
   SourceRange Range(Loc);
   if (SS.isSet()) Range.setBegin(SS.getRange().getBegin());
 
+  // Look through using shadow decls and aliases.
+  Rep = Rep->getUnderlyingDecl();
+
   DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext();
   CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC);
   CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr;
@@ -237,7 +239,7 @@
                                       SourceLocation TemplateKWLoc,
                                       LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs) {
-  switch (ClassifyImplicitMemberAccess(*this, CurScope, R)) {
+  switch (ClassifyImplicitMemberAccess(*this, R)) {
   case IMA_Instance:
     return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true);
 
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8705,8 +8705,18 @@
 
   // If we have neither explicit template arguments, nor the template keyword,
   // it's a normal declaration name.
-  if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
+  if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) {
+    // If this resolved to a data member, do member reference semantic analysis
+    // and possibly form a MemberExpr.
+    if (NamedDecl *D = R.getAsSingle<NamedDecl>()) {
+      D = D->getUnderlyingDecl();
+      if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) ||
+          isa<MSPropertyDecl>(D))
+        return getSema().BuildPossibleImplicitMemberExpr(
+            SS, SourceLocation(), R, /*TemplateArgs=*/nullptr);
+    }
     return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
+  }
 
   // If we have template arguments, rebuild them, then rebuild the
   // templateid expression.
Index: test/SemaTemplate/instantiate-using-decl.cpp
===================================================================
--- test/SemaTemplate/instantiate-using-decl.cpp
+++ test/SemaTemplate/instantiate-using-decl.cpp
@@ -104,3 +104,26 @@
     x.f();
   }
 }
+
+namespace PR21923 {
+struct A {
+  int member;
+  void method();
+};
+template <typename T>
+struct B : public T {
+  using T::member;
+  using T::method;
+  static void StaticFun() {
+    (void)member; // expected-error {{invalid use of member 'member' in static member function}}
+    (void)B<T>::member; // expected-error {{invalid use of member 'member' in static member function}}
+    method(); // expected-error {{call to non-static member function without an object argument}}
+  }
+  void InstanceFun() {
+    (void)member;
+    (void)B<T>::member;
+    method();
+  }
+};
+template class B<A>; // expected-note 1 {{requested here}}
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D6700.17374.patch
Type: text/x-patch
Size: 3384 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141217/cda5ef33/attachment.bin>


More information about the cfe-commits mailing list