[cfe-commits] r96836 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp test/SemaCXX/pseudo-destructors.cpp
Douglas Gregor
dgregor at apple.com
Mon Feb 22 16:15:22 PST 2010
Author: dgregor
Date: Mon Feb 22 18:15:22 2010
New Revision: 96836
URL: http://llvm.org/viewvc/llvm-project?rev=96836&view=rev
Log:
Implement crazy destructor name lookup semantics differently in
C++98/03 and C++0x, since the '0x semantics break valid C++98/03
code. This new mess is tracked by core issue 399, which is still
unresolved.
Fixes PR6358 and PR6359.
Added:
cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp
cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
Modified:
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=96836&r1=96835&r2=96836&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Feb 22 18:15:22 2010
@@ -49,7 +49,7 @@
// s->N::S<int>::~S();
// }
//
- //
+ // See also PR6358 and PR6359.
QualType SearchType;
DeclContext *LookupCtx = 0;
bool isDependent = false;
@@ -62,7 +62,39 @@
SearchType = GetTypeFromParser(ObjectTypePtr);
if (SS.isSet()) {
- // C++ [basic.lookup.qual]p6:
+ NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+
+ bool AlreadySearched = false;
+ bool LookAtPrefix = true;
+ if (!getLangOptions().CPlusPlus0x) {
+ // C++ [basic.lookup.qual]p6:
+ // If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier,
+ // the type-names are looked up as types in the scope designated by the
+ // nested-name-specifier. In a qualified-id of the form:
+ //
+ // ::[opt] nested-name-specifier Ì class-name
+ //
+ // where the nested-name-specifier designates a namespace scope, and in
+ // a qualified-id of the form:
+ //
+ // ::opt nested-name-specifier class-name :: Ì class-name
+ //
+ // the class-names are looked up as types in the scope designated by
+ // the nested-name-specifier.
+ //
+ // Here, we check the first case (completely) and determine whether the
+ // code below is permitted to look at the prefix of the
+ // nested-name-specifier (as we do in C++0x).
+ DeclContext *DC = computeDeclContext(SS, EnteringContext);
+ if (DC && DC->isFileContext()) {
+ AlreadySearched = true;
+ LookupCtx = DC;
+ isDependent = false;
+ } else if (DC && isa<CXXRecordDecl>(DC))
+ LookAtPrefix = false;
+ }
+
+ // C++0x [basic.lookup.qual]p6:
// If a pseudo-destructor-name (5.2.4) contains a
// nested-name-specifier, the type-names are looked up as types
// in the scope designated by the nested-name-specifier. Similarly, in
@@ -72,23 +104,33 @@
//
// the second class-name is looked up in the same scope as the first.
//
- // FIXME: We don't implement this, because it breaks lots of
- // perfectly reasonable code that no other compilers diagnose. The
- // issue is that the first class-name is looked up as a
- // nested-name-specifier, so we ignore value declarations, but the
- // second lookup is presumably an ordinary name lookup. Hence, we
- // end up finding values (say, a function) and complain. See PRs
- // 6358 and 6359 for examples of such code. DPG to investigate
- // further.
- if (ObjectTypePtr) {
+ // To implement this, we look at the prefix of the
+ // nested-name-specifier we were given, and determine the lookup
+ // context from that.
+ //
+ // We also fold in the second case from the C++03 rules quoted further
+ // above.
+ NestedNameSpecifier *Prefix = 0;
+ if (AlreadySearched) {
+ // Nothing left to do.
+ } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) {
+ CXXScopeSpec PrefixSS;
+ PrefixSS.setScopeRep(Prefix);
+ LookupCtx = computeDeclContext(PrefixSS, EnteringContext);
+ isDependent = isDependentScopeSpecifier(PrefixSS);
+ } else if (getLangOptions().CPlusPlus0x &&
+ (LookupCtx = computeDeclContext(SS, EnteringContext))) {
+ if (!LookupCtx->isTranslationUnit())
+ LookupCtx = LookupCtx->getParent();
+ isDependent = LookupCtx && LookupCtx->isDependentContext();
+ } else if (ObjectTypePtr) {
LookupCtx = computeDeclContext(SearchType);
isDependent = SearchType->isDependentType();
} else {
LookupCtx = computeDeclContext(SS, EnteringContext);
- if (LookupCtx)
- isDependent = LookupCtx->isDependentContext();
+ isDependent = LookupCtx && LookupCtx->isDependentContext();
}
-
+
LookInScope = (LookupCtx == 0) && !isDependent;
} else if (ObjectTypePtr) {
// C++ [basic.lookup.classref]p3:
Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp?rev=96836&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp Mon Feb 22 18:15:22 2010
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [basic.lookup.classref]p3:
+// If the unqualified-id is â¼type-name, the type-name is looked up in the
+// context of the entire postfix-expression. If the type T of the object
+// expression is of a class type C, the type-name is also looked up in the
+// scope of class C. At least one of the lookups shall find a name that
+// refers to (possibly cv-qualified) T.
+
+// From core issue 305
+struct A {
+};
+
+struct C {
+ struct A {};
+ void f ();
+};
+
+void C::f () {
+ ::A *a;
+ a->~A ();
+}
+
+// From core issue 414
+struct X {};
+void f() {
+ X x;
+ struct X {};
+ x.~X();
+}
Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp?rev=96836&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp Mon Feb 22 18:15:22 2010
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+struct C {
+ typedef int I;
+};
+
+typedef int I1, I2;
+extern int* p;
+extern int* q;
+
+void f() {
+ p->C::I::~I();
+ q->I1::~I2();
+}
+
+struct A {
+ ~A();
+};
+
+typedef A AB;
+int main() {
+ AB *p;
+ p->AB::~AB();
+}
Added: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp?rev=96836&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp (added)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp Mon Feb 22 18:15:22 2010
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct C {
+ typedef int I;
+};
+
+typedef int I1, I2;
+extern int* p;
+extern int* q;
+
+void f() {
+ p->C::I::~I();
+ q->I1::~I2();
+}
+
+struct A {
+ ~A();
+};
+
+typedef A AB;
+int main() {
+ AB *p;
+ p->AB::~AB(); // expected-error{{identifier 'AB' in pseudo-destructor expression does not name a type}}
+}
Modified: cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pseudo-destructors.cpp?rev=96836&r1=96835&r2=96836&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/pseudo-destructors.cpp (original)
+++ cfe/trunk/test/SemaCXX/pseudo-destructors.cpp Mon Feb 22 18:15:22 2010
@@ -29,7 +29,7 @@
g().~Bar(); // expected-error{{non-scalar}}
f->::~Bar();
- f->N::~Wibble(); // FIXME: Cannot use typedef name in destructor id.
+ f->N::~Wibble(); // FIXME: technically, Wibble isn't a class-name
f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
More information about the cfe-commits
mailing list