Quantcast

Type in friend declaration does not refer to the right RecordDecl?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Type in friend declaration does not refer to the right RecordDecl?

Philip Reames via cfe-dev
Hi all,

I have the following code:
```
namespace a {                
class A {};                  
namespace b { class B { friend class A; };  }  // b                          
} // a                            
```
I expect that the friend "class A" refers to CXXRecordDecl "class a::A". However, it refers to an implicit CXXRecordDecl "class a::b::A" instead. Is this expected?

* Node dump of the ElaboratedType "class A" in the friend declaration:
```
ElaboratedType 0x7fbf27d39570 'class A' sugar
`-RecordType 0x7fbf27d39540 'class a::b::A'
  `-CXXRecord 0x7fbf27d394a8 'A'
```

* AST dump:
```
....
`-NamespaceDecl 0x7f1f79f4f050 </home/ioeric/llvm-build/test.cc:1:1, line:6:1> line:1:11 a
  |-CXXRecordDecl 0x7f1f79f4f0b8 <line:2:1, col:10> col:7 class A definition
  | `-CXXRecordDecl 0x7f1f79f4f1d0 <col:1, col:7> col:7 implicit class A
  `-NamespaceDecl 0x7f1f79f4f288 <line:3:1, line:5:1> line:3:11 b
    `-CXXRecordDecl 0x7f1f79f4f2f0 <line:4:1, col:27> col:7 class B definition
      |-CXXRecordDecl 0x7f1f79f4f410 <col:1, col:7> col:7 implicit class B
      `-FriendDecl 0x7f1f79f4f5c0 <col:11, col:24> col:18 'class A':'class a::b::A'
```

Thanks,
Eric

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Type in friend declaration does not refer to the right RecordDecl?

Philip Reames via cfe-dev
On 10 February 2017 at 05:34, Eric Liu via cfe-dev <[hidden email]> wrote:
Hi all,

I have the following code:
```
namespace a {                
class A {};                  
namespace b { class B { friend class A; };  }  // b                          
} // a                            
```
I expect that the friend "class A" refers to CXXRecordDecl "class a::A". However, it refers to an implicit CXXRecordDecl "class a::b::A" instead. Is this expected?

Yes; that's how C++ works. The rule in question is in kind of an odd place (it's [namespace.memdef]p3) but is pretty clear:

"If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.

It looks like MSVC does not properly implement this rule. I don't know whether Clang's MSVC compatibility mode emulates that bug.
 
* Node dump of the ElaboratedType "class A" in the friend declaration:
```
ElaboratedType 0x7fbf27d39570 'class A' sugar
`-RecordType 0x7fbf27d39540 'class a::b::A'
  `-CXXRecord 0x7fbf27d394a8 'A'
```

* AST dump:
```
....
`-NamespaceDecl 0x7f1f79f4f050 </home/ioeric/llvm-build/test.cc:1:1, line:6:1> line:1:11 a
  |-CXXRecordDecl 0x7f1f79f4f0b8 <line:2:1, col:10> col:7 class A definition
  | `-CXXRecordDecl 0x7f1f79f4f1d0 <col:1, col:7> col:7 implicit class A
  `-NamespaceDecl 0x7f1f79f4f288 <line:3:1, line:5:1> line:3:11 b
    `-CXXRecordDecl 0x7f1f79f4f2f0 <line:4:1, col:27> col:7 class B definition
      |-CXXRecordDecl 0x7f1f79f4f410 <col:1, col:7> col:7 implicit class B
      `-FriendDecl 0x7f1f79f4f5c0 <col:11, col:24> col:18 'class A':'class a::b::A'
```

Thanks,
Eric

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Type in friend declaration does not refer to the right RecordDecl?

Philip Reames via cfe-dev
Thank you for the reference Richard!

On Sun, Feb 12, 2017 at 9:57 PM Richard Smith <[hidden email]> wrote:
On 10 February 2017 at 05:34, Eric Liu via cfe-dev <[hidden email]> wrote:
Hi all,

I have the following code:
```
namespace a {                
class A {};                  
namespace b { class B { friend class A; };  }  // b                          
} // a                            
```
I expect that the friend "class A" refers to CXXRecordDecl "class a::A". However, it refers to an implicit CXXRecordDecl "class a::b::A" instead. Is this expected?

Yes; that's how C++ works. The rule in question is in kind of an odd place (it's [namespace.memdef]p3) but is pretty clear:

"If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.

It looks like MSVC does not properly implement this rule. I don't know whether Clang's MSVC compatibility mode emulates that bug.
 
* Node dump of the ElaboratedType "class A" in the friend declaration:
```
ElaboratedType 0x7fbf27d39570 'class A' sugar
`-RecordType 0x7fbf27d39540 'class a::b::A'
  `-CXXRecord 0x7fbf27d394a8 'A'
```

* AST dump:
```
....
`-NamespaceDecl 0x7f1f79f4f050 </home/ioeric/llvm-build/test.cc:1:1, line:6:1> line:1:11 a
  |-CXXRecordDecl 0x7f1f79f4f0b8 <line:2:1, col:10> col:7 class A definition
  | `-CXXRecordDecl 0x7f1f79f4f1d0 <col:1, col:7> col:7 implicit class A
  `-NamespaceDecl 0x7f1f79f4f288 <line:3:1, line:5:1> line:3:11 b
    `-CXXRecordDecl 0x7f1f79f4f2f0 <line:4:1, col:27> col:7 class B definition
      |-CXXRecordDecl 0x7f1f79f4f410 <col:1, col:7> col:7 implicit class B
      `-FriendDecl 0x7f1f79f4f5c0 <col:11, col:24> col:18 'class A':'class a::b::A'
```

Thanks,
Eric

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...