[cfe-commits] r110486 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/SemaTemplate/dependent-class-member-operator.cpp

Eli Friedman eli.friedman at gmail.com
Fri Aug 6 16:41:47 PDT 2010


Author: efriedma
Date: Fri Aug  6 18:41:47 2010
New Revision: 110486

URL: http://llvm.org/viewvc/llvm-project?rev=110486&view=rev
Log:
PR7837: For qualified id's, make sure the decl context is complete if not
dependent in ActOnIdExpression.  (This issue only shows up with member
operators because an operator is never a type.)


Added:
    cfe/trunk/test/SemaTemplate/dependent-class-member-operator.cpp
Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=110486&r1=110485&r2=110486&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Aug  6 18:41:47 2010
@@ -699,23 +699,6 @@
   return true;
 }
 
-/// Determines whether we can lookup this id-expression now or whether
-/// we have to wait until template instantiation is complete.
-static bool IsDependentIdExpression(Sema &SemaRef, const CXXScopeSpec &SS) {
-  DeclContext *DC = SemaRef.computeDeclContext(SS, false);
-
-  // If the qualifier scope isn't computable, it's definitely dependent.
-  if (!DC) return true;
-
-  // If the qualifier scope doesn't name a record, we can always look into it.
-  if (!isa<CXXRecordDecl>(DC)) return false;
-
-  // We can't look into record types unless they're fully-formed.
-  if (!IsFullyFormedScope(SemaRef, cast<CXXRecordDecl>(DC))) return true;
-
-  return false;
-}
-
 /// Determines if the given class is provably not derived from all of
 /// the prospective base classes.
 static bool IsProvablyNotDerivedFrom(Sema &SemaRef,
@@ -1100,9 +1083,24 @@
   //        names a dependent type.
   // Determine whether this is a member of an unknown specialization;
   // we need to handle these differently.
-  if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
-       Name.getCXXNameType()->isDependentType()) ||
-      (SS.isSet() && IsDependentIdExpression(*this, SS))) {
+  bool DependentID = false;
+  if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+      Name.getCXXNameType()->isDependentType()) {
+    DependentID = true;
+  } else if (SS.isSet()) {
+    DeclContext *DC = computeDeclContext(SS, false);
+    if (DC) {
+      if (RequireCompleteDeclContext(SS, DC))
+        return ExprError();
+      // FIXME: We should be checking whether DC is the current instantiation.
+      if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
+        DependentID = !IsFullyFormedScope(*this, RD);
+    } else {
+      DependentID = true;
+    }
+  }
+
+  if (DependentID) {
     return ActOnDependentIdExpression(SS, Name, NameLoc,
                                       isAddressOfOperand,
                                       TemplateArgs);

Added: cfe/trunk/test/SemaTemplate/dependent-class-member-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-class-member-operator.cpp?rev=110486&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-class-member-operator.cpp (added)
+++ cfe/trunk/test/SemaTemplate/dependent-class-member-operator.cpp Fri Aug  6 18:41:47 2010
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR7837
+
+template<class T> struct C1 { void operator()(T); };
+template<class T> struct C2; // expected-note {{template is declared here}}
+template<class T> void foo(T);
+void wrap() {
+  foo(&C1<int>::operator());
+  foo(&C1<int>::operator+); // expected-error {{no member named 'operator+' in 'C1<int>'}}
+  foo(&C2<int>::operator+); // expected-error {{implicit instantiation of undefined template 'C2<int>'}}
+}





More information about the cfe-commits mailing list