[PATCH] Allow more lookup of types in dependent base classes

Reid Kleckner rnk at google.com
Fri Jun 27 14:40:43 PDT 2014


================
Comment at: lib/Sema/SemaDecl.cpp:139-141
@@ +138,5 @@
+  for (const auto &Base : RD->bases()) {
+    auto *TST = Base.getType()->getAs<TemplateSpecializationType>();
+    if (!TST)
+      continue;
+    auto *TD = TST->getTemplateName().getAsTemplateDecl();
----------------
Richard Smith wrote:
> It'd be nice to also handle deriving from `A<T>::B`, and so on.
Thanks for the test!  MSVC rejects, though:
  template <typename T> struct A { struct B { typedef T InnerType; }; };
  template <typename T> struct C : A<T>::B { InnerType m; };

I'll add it as a negative test.

================
Comment at: lib/Sema/SemaDecl.cpp:259-268
@@ -212,1 +258,12 @@
+    // For unqualified lookup in a class template in MSVC mode, look into
+    // dependent base classes where the primary class template is known.
+    if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+      auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
+      if (RD && RD->getDescribedClassTemplate()) {
+        ParsedType TypeInBase =
+            recoverFromTypeInKnownDependentBase(*this, RD, II, NameLoc);
+        if (TypeInBase)
+          return TypeInBase;
+      }
+    }
   }
----------------
Richard Smith wrote:
> I suspect you'll also need to do something like this in `ClassifyName`.
Hm, yeah.  Looks like that feeds more or less directly into template deduction.  I added a bunch of tests for this.  It seems that this extra special lookup only applies to types.  MSVC doesn't accept unqualified non-type declarations as non-type template arguments, for example.

================
Comment at: lib/Sema/SemaDecl.cpp:261-262
@@ +260,4 @@
+    if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+      auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
+      if (RD && RD->getDescribedClassTemplate()) {
+        ParsedType TypeInBase =
----------------
Richard Smith wrote:
> This seems rather specific. I suppose we don't need to worry much about function contexts, because we'll delay-parse most of those, but what about the cases where we don't (`auto` return type, `constexpr` functions) and nested classes of class templates? Is it feasible to walk upwards until we see a class template, if we're in a dependent context?
> 
> Also, what about a class template within another class template? Should we look in dependent base classes of both?
MSVC doesn't support constexpr member functions or auto return types.  Eventually, though, they will add support.  When they do, they might actually require the use of 'typename Base<T>::', so I'm not inclined to accept code that we think MSVC *might* accept in the future.  What do you think?

http://reviews.llvm.org/D4237






More information about the cfe-commits mailing list