]> granicus.if.org Git - clang/commitdiff
Partial fix for qualified name lookup, such that the lookup of N in
authorDouglas Gregor <dgregor@apple.com>
Tue, 16 Dec 2008 06:37:47 +0000 (06:37 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 16 Dec 2008 06:37:47 +0000 (06:37 +0000)
N::X only skips those entities specified in C++ [basic.lookup.qual]p1.

Note that both EDG and GCC currently get this wrong. EDG has confirmed
that the bug will be fixed in a future version.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61079 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCXXScopeSpec.cpp
test/SemaCXX/nested-name-spec.cpp

index 8b3218b33b194de9b9bdc82df28243d9e08c8847..fe9ae07ebaca54b417c803dfb498c68986262d5c 100644 (file)
@@ -28,8 +28,8 @@ namespace {
       DeclContext::lookup_const_iterator I, E;\r
       for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) {\r
        IdIsUndeclared = false;\r
-       if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag) && \r
-           !isa<EnumDecl>(*I))\r
+       if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag) || \r
+           isa<TypedefDecl>(*I))\r
          return *I;\r
       }\r
 \r
@@ -56,12 +56,10 @@ namespace {
     // not a class-name or namespace-name, the program is ill-formed.\r
 \r
     for (; I != E; ++I) {\r
-      if (TypedefDecl *TD = dyn_cast<TypedefDecl>(*I)) {\r
-        if (TD->getUnderlyingType()->isRecordType())\r
-          break;\r
-        continue;\r
+      if (isa<TypedefDecl>(*I)) {\r
+        break;\r
       }\r
-      if (((*I)->getIdentifierNamespace()&Decl::IDNS_Tag) && !isa<EnumDecl>(*I))\r
+      if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag))\r
         break;    \r
     }\r
 \r
@@ -100,13 +98,14 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
 \r
   if (SD) {\r
     if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {\r
-      assert(TD->getUnderlyingType()->isRecordType() &&"Invalid Scope Decl!");\r
-      SD = TD->getUnderlyingType()->getAsRecordType()->getDecl();\r
+      if (const RecordType* Record = TD->getUnderlyingType()->getAsRecordType())\r
+        return cast<DeclContext>(Record->getDecl());\r
+    } else if (isa<NamespaceDecl>(SD) || isa<RecordDecl>(SD)) {\r
+      return cast<DeclContext>(SD);\r
     }\r
 \r
-    assert((isa<NamespaceDecl>(SD) || isa<RecordDecl>(SD)) &&\r
-           "Invalid Scope Decl!");\r
-    return cast<DeclContext>(SD);\r
+    // Fall through to produce an error: we found something that isn't\r
+    // a class or a namespace.\r
   }\r
 \r
   unsigned DiagID;\r
index 1d91c24b969a2b2de840c56fc3c6e7342363baec..74220662474f2450b830d55afd29f54590e0e5e3 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify %s 
+// RUN: clang -fsyntax-only -verify -std=c++98 %s 
 namespace A {
   struct C {
     static int cx;
@@ -72,10 +72,8 @@ void f3() {
   int N;
   N::x = 0; // expected-error {{expected a class or namespace}}
   { int A;           A::ax = 0; }
-  { enum A {};       A::ax = 0; }
-  { enum A { A };    A::ax = 0; }
-  { typedef int A;   A::ax = 0; }
-  { typedef int A(); A::ax = 0; }
+  { typedef int A;   A::ax = 0; } // expected-error{{expected a class or namespace}}
+  { int A(); A::ax = 0; }
   { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}}
   { typedef A::C A;  A::cx = 0; }
 }
@@ -90,3 +88,18 @@ void f6(int A2::RC::x); // expected-error{{parameter declarator cannot be qualif
 int A2::RC::x; // expected-error{{non-static data member defined out-of-line}}
 
 void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member must be a definition}}
+
+
+namespace E {
+  int X = 5;
+  
+  namespace Nested {
+    enum E {
+      X = 0
+    };
+
+    void f() {
+      return E::X; // expected-error{{expected a class or namespace}}
+    }
+  }
+}