1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-05 08:05:24 +02:00

Bug 400940 - Friend constructor reported as syntax error

Change-Id: I0cbe6b9285b1e26abb985e6582e534132acb0c6c
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/15837
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-08-25 19:46:12 -04:00 committed by Sergey Prigogin
parent 2c5fcc3d85
commit 07709b85ce
3 changed files with 27 additions and 10 deletions

View file

@ -9802,6 +9802,19 @@ public class AST2CPPTests extends AST2TestBase {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// struct foo {
// foo();
// ~foo();
// };
//
// class bar {
// friend foo::foo();
// friend foo::~foo();
// };
public void testFriendConstructorDestructor_400940() throws Exception {
parseAndCheckBindings();
}
// struct S { // struct S {
// virtual void mFuncDecl() final; // virtual void mFuncDecl() final;
// virtual void mFuncDef() final {} // virtual void mFuncDef() final {}

View file

@ -1620,9 +1620,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} catch (BacktrackException e) { } catch (BacktrackException e) {
if (acceptEmpty) { if (acceptEmpty) {
backup(dtorMark1); backup(dtorMark1);
return result.set(declspec1, null, null); dtor1= null;
} } else {
// try second variant, if possible // try second variant, if possible
if (dtorMark2 == null) if (dtorMark2 == null)
throw e; throw e;
@ -1631,6 +1630,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
dtor2= initDeclarator(declspec2, option); dtor2= initDeclarator(declspec2, option);
return result.set(declspec2, dtor2, dtorMark2); return result.set(declspec2, dtor2, dtorMark2);
} }
}
// first variant was a success. If possible, try second one. // first variant was a success. If possible, try second one.
if (dtorMark2 == null) { if (dtorMark2 == null) {

View file

@ -2632,7 +2632,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
SHORT= 0x20, UNSIGNED= 0x40, SIGNED= 0x80, COMPLEX= 0x100, IMAGINARY= 0x200, SHORT= 0x20, UNSIGNED= 0x40, SIGNED= 0x80, COMPLEX= 0x100, IMAGINARY= 0x200,
VIRTUAL= 0x400, EXPLICIT= 0x800, FRIEND= 0x1000, THREAD_LOCAL= 0x2000; VIRTUAL= 0x400, EXPLICIT= 0x800, FRIEND= 0x1000, THREAD_LOCAL= 0x2000;
private static final int FORBID_IN_EMPTY_DECLSPEC = private static final int FORBID_IN_EMPTY_DECLSPEC =
CONST | RESTRICT | VOLATILE | SHORT | UNSIGNED | SIGNED | COMPLEX | IMAGINARY | FRIEND | THREAD_LOCAL; CONST | RESTRICT | VOLATILE | SHORT | UNSIGNED | SIGNED | COMPLEX | IMAGINARY | THREAD_LOCAL;
/** /**
* This function parses a declaration specifier sequence, as according to * This function parses a declaration specifier sequence, as according to
@ -3282,6 +3282,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (CharArrayUtils.equals(nchars, start, nchars.length-start, currentClassName)) if (CharArrayUtils.equals(nchars, start, nchars.length-start, currentClassName))
return; return;
} }
// Accept constructors and destructors of other classes as friends
if (declspec instanceof ICPPASTDeclSpecifier && ((ICPPASTDeclSpecifier) declspec).isFriend())
return;
} else if (isQualified) { } else if (isQualified) {
// Accept qualified constructor or destructor outside of class body // Accept qualified constructor or destructor outside of class body
return; return;