[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] [FIXED][78165][Parser] Problems handling Elaborated type specifiers
|
[FIXED][78165][Parser] Problems handling
Elaborated type specifiers
Take some time to think about this one
before applying it. It looks like BacktrackExceptions were used to
detect elaborated type specifiers for enumerations. This rendered
all of the previously used BacktrackExceptions in Parser.enumSpecifier()
to be somewhat useless as they were all implied to be used when an elaborated
type specifier was found.
Note: This patch only works for
enum and it looks like similar logic was applied to class, struct, and
union. I would like to do something similar for the way class, struct,
and union are handled in Parser.declSpecifierSeq() but it's more complex
and not required for this bug fix.
Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada
Index: parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java,v
retrieving revision 1.138
diff -u -r1.138 CompleteParseASTTest.java
--- parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java 18 Nov 2004 21:05:23 -0000 1.138
+++ parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java 19 Nov 2004 16:17:07 -0000
@@ -2416,5 +2416,54 @@
assertEquals(ip.getSourceLineNumber(), 4);
}
}
+
+ public void testBug78165() throws Exception {
+ Writer writer = new StringWriter();
+ writer.write("struct Node {\n"); //$NON-NLS-1$
+ writer.write("struct Node* Next; // OK: Refers to Node at global scope\n"); //$NON-NLS-1$
+ writer.write("struct Data* Data; // OK: Declares type Data at global scope and member Data\n"); //$NON-NLS-1$
+ writer.write("};\n"); //$NON-NLS-1$
+ writer.write("struct Data {\n"); //$NON-NLS-1$
+ writer.write("struct Node* Node; // OK: Refers to Node at global scope\n"); //$NON-NLS-1$
+ writer.write("friend struct Glob; // OK: Refers to (as yet) undeclared Glob at global scope.\n"); //$NON-NLS-1$
+ writer.write("};\n"); //$NON-NLS-1$
+ writer.write("struct Base {\n"); //$NON-NLS-1$
+ writer.write("struct Data; // OK: Declares nested Data\n"); //$NON-NLS-1$
+ writer.write("struct ::Data* thatData; // OK: Refers to ::Data\n"); //$NON-NLS-1$
+ writer.write("struct Base::Data* thisData; // OK: Refers to nested Data\n"); //$NON-NLS-1$
+ writer.write("friend class ::Data; // OK: global Data is a friend\n"); //$NON-NLS-1$
+ writer.write("friend class Data; // OK: nested Data is a friend\n"); //$NON-NLS-1$
+ writer.write("struct Data { /* ... */ }; // Defines nested Data\n"); //$NON-NLS-1$
+ writer.write("struct Data; // OK: Redeclares nested Data\n"); //$NON-NLS-1$
+ writer.write("};\n"); //$NON-NLS-1$
+ writer.write("struct Data; // OK: Redeclares Data at global scope\n"); //$NON-NLS-1$
+ writer.write("struct Base::Data* pBase; // OK: refers to nested Data\n"); //$NON-NLS-1$
+
+ Iterator i = parse( writer.toString() ).getDeclarations();
+ IASTAbstractTypeSpecifierDeclaration node = (IASTAbstractTypeSpecifierDeclaration)i.next();
+ assertEquals(node.getStartingLine(), 1);
+ assertTrue(node.getTypeSpecifier() instanceof IASTClassSpecifier);
+ IASTClassSpecifier typeSpec = (IASTClassSpecifier)node.getTypeSpecifier();
+ assertEquals(typeSpec.getName(), "Node"); //$NON-NLS-1$
+ IASTAbstractTypeSpecifierDeclaration data = (IASTAbstractTypeSpecifierDeclaration)i.next();
+ assertEquals(data.getStartingLine(), 5);
+ assertTrue(data.getTypeSpecifier() instanceof IASTClassSpecifier);
+ typeSpec = (IASTClassSpecifier)data.getTypeSpecifier();
+ assertEquals(typeSpec.getName(), "Data"); //$NON-NLS-1$
+ IASTAbstractTypeSpecifierDeclaration base = (IASTAbstractTypeSpecifierDeclaration)i.next();
+ assertEquals(base.getStartingLine(), 9);
+ assertTrue(base.getTypeSpecifier() instanceof IASTClassSpecifier);
+ typeSpec = (IASTClassSpecifier)base.getTypeSpecifier();
+ assertEquals(typeSpec.getName(), "Base"); //$NON-NLS-1$
+ IASTAbstractTypeSpecifierDeclaration data2 = (IASTAbstractTypeSpecifierDeclaration)i.next();
+ assertEquals(data2.getStartingLine(), 18);
+ assertTrue(data2.getTypeSpecifier() instanceof IASTElaboratedTypeSpecifier);
+ IASTElaboratedTypeSpecifier typeSpec2 = (IASTElaboratedTypeSpecifier)data2.getTypeSpecifier();
+ assertEquals(typeSpec2.getName(), "Data"); //$NON-NLS-1$
+ assertTrue(typeSpec2.isForwardDeclaration());
+ IASTVariable pBase = (IASTVariable)i.next();
+ assertEquals(pBase.getStartingLine(), 19);
+ }
+
}
Index: parser/org/eclipse/cdt/core/parser/ast/IASTElaboratedTypeSpecifier.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTElaboratedTypeSpecifier.java,v
retrieving revision 1.9
diff -u -r1.9 IASTElaboratedTypeSpecifier.java
--- parser/org/eclipse/cdt/core/parser/ast/IASTElaboratedTypeSpecifier.java 16 Jan 2004 05:09:00 -0000 1.9
+++ parser/org/eclipse/cdt/core/parser/ast/IASTElaboratedTypeSpecifier.java 19 Nov 2004 16:16:45 -0000
@@ -23,4 +23,5 @@
public String getName();
public ASTClassKind getClassKind();
public boolean isResolved() throws ASTNotImplementedException;
+ public boolean isForwardDeclaration();
}
Index: parser/org/eclipse/cdt/internal/core/parser/Parser.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java,v
retrieving revision 1.266
diff -u -r1.266 Parser.java
--- parser/org/eclipse/cdt/internal/core/parser/Parser.java 18 Nov 2004 16:52:07 -0000 1.266
+++ parser/org/eclipse/cdt/internal/core/parser/Parser.java 19 Nov 2004 16:16:46 -0000
@@ -82,6 +82,7 @@
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
import org.eclipse.cdt.internal.core.parser.ast.complete.CompleteParseASTFactory;
import org.eclipse.cdt.internal.core.parser.problem.IProblemFactory;
+import org.eclipse.cdt.internal.core.parser.problem.Problem;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner;
import org.eclipse.cdt.internal.core.parser.token.KeywordSets;
import org.eclipse.cdt.internal.core.parser.token.OffsetDuple;
@@ -4719,16 +4720,9 @@
break;
}
case IToken.t_enum :
- try {
enumSpecifier(sdw);
flags.setEncounteredTypename(true);
break;
- } catch (BacktrackException bt) {
- // this is an elaborated class specifier
- elaboratedTypeSpecifier(sdw);
- flags.setEncounteredTypename(true);
- break;
- }
default :
if (extension.canHandleDeclSpecifierSequence(LT(1))) {
IParserExtension.IDeclSpecifierExtensionResult declSpecExtResult = extension
@@ -5547,7 +5541,11 @@
if (enumerator != null)
enumerator.freeReferences();
int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0 ;
- throwBacktrack(mark.getOffset(), endOffset, mark.getLineNumber(), mark.getFilename());
+ failParse(new Problem(IProblem.SYNTAX_ERROR, lastToken.getOffset(), endOffset, lastToken.getLineNumber(), lastToken.getFilename(), EMPTY_STRING, true, false));
+ errorHandling();
+ if (LT(1) == IToken.tRBRACE)
+ consume(IToken.tRBRACE);
+ return;
}
try {
enumerator = astFactory.addEnumerator(enumeration,
@@ -5575,10 +5573,9 @@
enumeration.acceptElement(requestor);
sdw.setTypeSpecifier(enumeration);
} else {
- // enumSpecifierAbort
- int endOffset = ( lastToken != null ) ? lastToken.getEndOffset() : 0 ;
+ // 72685 handle elaborated type specifier here (instead of using throwBacktrack exception to handle it)
backup(mark);
- throwBacktrack(mark.getOffset(), endOffset, mark.getLineNumber(), mark.getFilename());
+ elaboratedTypeSpecifier(sdw);
}
}
/**
Index: parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTElaboratedTypeSpecifier.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTElaboratedTypeSpecifier.java,v
retrieving revision 1.20
diff -u -r1.20 ASTElaboratedTypeSpecifier.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTElaboratedTypeSpecifier.java 7 Sep 2004 18:56:38 -0000 1.20
+++ parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTElaboratedTypeSpecifier.java 19 Nov 2004 16:16:46 -0000
@@ -228,4 +228,10 @@
public char[] getFilename() {
return fn;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier#isForwardDeclaration()
+ */
+ public boolean isForwardDeclaration() {
+ return isForwardDeclaration;
+ }
}
Index: parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java,v
retrieving revision 1.198
diff -u -r1.198 CompleteParseASTFactory.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java 18 Nov 2004 14:34:42 -0000 1.198
+++ parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java 19 Nov 2004 16:16:47 -0000
@@ -3283,7 +3283,7 @@
ISymbol checkSymbol = null;
if (!isTemplateId) {
try {
- if (isFriend && isForewardDecl) {
+ if (isFriend && isForewardDecl && currentScopeSymbol instanceof IDerivableContainerSymbol) {
checkSymbol = ((IDerivableContainerSymbol) currentScopeSymbol)
.lookupForFriendship(newSymbolName);
} else {
Index: parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTElaboratedTypeSpecifier.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTElaboratedTypeSpecifier.java,v
retrieving revision 1.20
diff -u -r1.20 ASTElaboratedTypeSpecifier.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTElaboratedTypeSpecifier.java 7 Sep 2004 18:56:38 -0000 1.20
+++ parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTElaboratedTypeSpecifier.java 19 Nov 2004 16:16:47 -0000
@@ -199,4 +199,11 @@
public char[] getNameCharArray() {
return typeName;
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier#isForwardDeclaration()
+ */
+ public boolean isForwardDeclaration() {
+ return false;
+ }
}