Skip to main content

[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;
+	}
 }

Back to the top