Skip to content

Commit

Permalink
Sema: Implement DR244
Browse files Browse the repository at this point in the history
Summary:
Naming the destructor using a typedef-name for the class-name is
well-formed.

This fixes PR19620.

Reviewers: rsmith, doug.gregor

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D3583

llvm-svn: 209319
  • Loading branch information
majnemer committed May 21, 2014
1 parent 2b4307d commit e37a6ce
Showing 4 changed files with 21 additions and 22 deletions.
25 changes: 9 additions & 16 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
@@ -121,31 +121,26 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,

bool AlreadySearched = false;
bool LookAtPrefix = true;
// C++ [basic.lookup.qual]p6:
// C++11 [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:
// nested-name-specifier. Similarly, in a qualified-id of the form:
//
// ::[opt] nested-name-specifier ~ class-name
// nested-name-specifier[opt] class-name :: ~ class-name
//
// where the nested-name-specifier designates a namespace scope, and in
// a qualified-id of the form:
// the second class-name is looked up in the same scope as the first.
//
// ::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.
// Here, we determine whether the code below is permitted to look at the
// prefix of the nested-name-specifier.
DeclContext *DC = computeDeclContext(SS, EnteringContext);
if (DC && DC->isFileContext()) {
AlreadySearched = true;
LookupCtx = DC;
isDependent = false;
} else if (DC && isa<CXXRecordDecl>(DC))
} else if (DC && isa<CXXRecordDecl>(DC)) {
LookAtPrefix = false;
LookInScope = true;
}

// The second case from the C++03 rules quoted further above.
NestedNameSpecifier *Prefix = 0;
@@ -163,8 +158,6 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = LookupCtx && LookupCtx->isDependentContext();
}

LookInScope = false;
} else if (ObjectTypePtr) {
// C++ [basic.lookup.classref]p3:
// If the unqualified-id is ~type-name, the type-name is looked up
3 changes: 2 additions & 1 deletion clang/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// expected-no-diagnostics

struct C {
typedef int I;
@@ -20,5 +21,5 @@ struct A {
typedef A AB;
int main() {
AB *p;
p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}}
p->AB::~AB();
}
13 changes: 9 additions & 4 deletions clang/test/CXX/drs/dr2xx.cpp
Original file line number Diff line number Diff line change
@@ -466,7 +466,7 @@ namespace dr243 { // dr243: yes
A a2 = b; // expected-error {{ambiguous}}
}

namespace dr244 { // dr244: no
namespace dr244 { // dr244: 3.5
struct B {}; struct D : B {}; // expected-note {{here}}

D D_object;
@@ -480,7 +480,7 @@ namespace dr244 { // dr244: no
B_ptr->~B_alias();
B_ptr->B_alias::~B();
// This is valid under DR244.
B_ptr->B_alias::~B_alias(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}}
B_ptr->B_alias::~B_alias();
B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}}
B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}}
}
@@ -1013,11 +1013,16 @@ namespace dr298 { // dr298: yes

B::B() {} // expected-error {{requires a type specifier}}
B::A() {} // ok
C::~C() {} // expected-error {{expected the class name}}
C::~A() {} // ok
C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'C' (aka 'const dr298::A') of the class name}}

typedef struct D E; // expected-note {{here}}
struct E {}; // expected-error {{conflicts with typedef}}

struct F {
~F();
};
typedef const F G;
G::~F() {} // ok
}

namespace dr299 { // dr299: yes c++11
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
@@ -1504,7 +1504,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#244">244</a></td>
<td>CD1</td>
<td>Destructor lookup</td>
<td class="none" align="center">No</td>
<td class="svn" align="center">SVN</td>
</tr>
<tr id="245">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#245">245</a></td>

0 comments on commit e37a6ce

Please sign in to comment.