From e9f3d2a3a2f806cd38e999f71579c7fa5edd28d4 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 10 Nov 2008 15:08:58 +0000 Subject: [PATCH] Cleanup parsing c-initializers, related to 253690. --- .../internal/index/tests/IndexBugsTests.java | 17 + .../internal/core/dom/parser/ASTQueries.java | 3 + .../core/dom/parser/c/GNUCSourceParser.java | 291 ++++++++---------- 3 files changed, 143 insertions(+), 168 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 28d1bbeb771..6f8a6431aa3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -1550,4 +1550,21 @@ public class IndexBugsTests extends BaseTestCase { } } + // struct s {int a;}; + // struct s x[]= {{.a=1,},{.a=2}}; + public void testReferencesInDesignators_Bug253690() throws Exception { + String code= getContentsForTest(1)[0]; + final IIndexManager indexManager = CCorePlugin.getIndexManager(); + IFile file= TestSourceReader.createFile(fCProject.getProject(), "test.c", code); + waitUntilFileIsIndexed(file, 4000); + fIndex.acquireReadLock(); + try { + IIndexBinding[] bindings = fIndex.findBindings("a".toCharArray(), false, IndexFilter.ALL_DECLARED, NPM); + assertEquals(1, bindings.length); + IIndexName[] refs = fIndex.findNames(bindings[0], IIndex.FIND_REFERENCES); + assertEquals(2, refs.length); + } finally { + fIndex.releaseReadLock(); + } + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java index 34c6f4c0607..515795650b0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.dom.parser; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpressionList; @@ -36,6 +37,8 @@ public class ASTQueries { return true; if (expr instanceof IASTIdExpression) return true; + if (expr instanceof IASTCastExpression) + return true; if (expr instanceof IASTUnaryExpression) { IASTUnaryExpression uexpr= (IASTUnaryExpression) expr; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index b6329a0661b..54c9849d041 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -159,93 +159,84 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { BacktrackException { if (LT(1) == IToken.tASSIGN) { consume(); - final List empty= Collections.emptyList(); - return cInitializerClause(empty, false); + return cInitializerClause(false); } return null; } - protected IASTInitializer cInitializerClause(List designators, boolean inAggregateInitializer) - throws EndOfFileException, BacktrackException { - IToken la = LA(1); - int startingOffset = la.getOffset(); - la = null; - if (LT(1) == IToken.tLBRACE) { - consume(); - IASTInitializerList result = createInitializerList(); - ((ASTNode) result).setOffset(startingOffset); - - // bug 196468, gcc accepts empty braces. - if (supportGCCStyleDesignators && LT(1) == (IToken.tRBRACE)) { - int l = consume().getEndOffset(); - ((ASTNode) result).setLength(l - startingOffset); - return result; + protected IASTInitializer cInitializerClause(boolean inAggregate) throws EndOfFileException, BacktrackException { + final int offset = LA(1).getOffset(); + if (LT(1) != IToken.tLBRACE) { + IASTExpression assignmentExpression= assignmentExpression(); + if (inAggregate && skipTrivialExpressionsInAggregateInitializers) { + if (!ASTQueries.canContainName(assignmentExpression)) + return null; } - - for (;;) { - final IToken startToken= LA(1); - // required at least one initializer list - // get designator list - List newDesignators = designatorList(); - if (newDesignators.size() != 0) - if (LT(1) == IToken.tASSIGN) - consume(); - - IASTInitializer initializer = cInitializerClause(newDesignators, true); - - // depending on value of skipTrivialItemsInCompoundInitializers initializer may be null - if (initializer != null) { - if (newDesignators.isEmpty()) { - result.addInitializer(initializer); - } else { - ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); - ((ASTNode) desigInitializer).setOffsetAndLength( - ((ASTNode) newDesignators.get(0)).getOffset(), - ((ASTNode)initializer).getOffset() + ((ASTNode)initializer).getLength() - ((ASTNode) newDesignators.get(0)).getOffset()); - for (int i = 0; i < newDesignators.size(); ++i) { - ICASTDesignator d = (ICASTDesignator) newDesignators.get(i); - desigInitializer.addDesignator(d); - } - desigInitializer.setOperandInitializer(initializer); - result.addInitializer(desigInitializer); - } - } - // can end with ", }" or "}" - if (LT(1) == IToken.tCOMMA) - consume(); - if (LT(1) == IToken.tRBRACE) - break; - - final IToken nextToken= LA(1); - if (nextToken.getType() == IToken.tEOC) { - return result; - } - if (nextToken == startToken) { - throwBacktrack(startingOffset, nextToken.getEndOffset() - startingOffset); - return null; - } - - // otherwise, its another initializer in the list - } - // consume the closing brace - int lastOffset = consume(IToken.tRBRACE).getEndOffset(); - ((ASTNode) result).setLength(lastOffset - startingOffset); + IASTInitializerExpression result= createInitializerExpression(); + result.setExpression(assignmentExpression); + setRange(result, assignmentExpression); return result; + } - // if we get this far, it means that we have not yet succeeded - // try this now instead - // assignmentExpression - IASTExpression assignmentExpression = assignmentExpression(); - if (inAggregateInitializer && skipTrivialExpressionsInAggregateInitializers) { - if (!ASTQueries.canContainName(assignmentExpression)) - return null; + + // it's an aggregate initializer + consume(IToken.tLBRACE); + IASTInitializerList result = createInitializerList(); + + // bug 196468, gcc accepts empty braces. + if (supportGCCStyleDesignators && LT(1) == IToken.tRBRACE) { + int endOffset= consume().getEndOffset(); + setRange(result, offset, endOffset); + return result; } - IASTInitializerExpression result = createInitializerExpression(); - result.setExpression(assignmentExpression); - ((ASTNode) result).setOffsetAndLength( - ((ASTNode) assignmentExpression).getOffset(), - ((ASTNode) assignmentExpression).getLength()); - return result; + + for (;;) { + final int checkOffset= LA(1).getOffset(); + // required at least one initializer list + // get designator list + List designator= designatorList(); + if (designator == null) { + IASTInitializer initializer= cInitializerClause(true); + // depending on value of skipTrivialItemsInCompoundInitializers initializer may be null + if (initializer != null) { + result.addInitializer(initializer); + } + } else { + if (LT(1) == IToken.tASSIGN) + consume(); + IASTInitializer initializer= cInitializerClause(false); + ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); + setRange(desigInitializer, designator.get(0)); + adjustLength(desigInitializer, initializer); + + for (ICASTDesignator d : designator) { + desigInitializer.addDesignator(d); + } + desigInitializer.setOperandInitializer(initializer); + result.addInitializer(desigInitializer); + } + + // can end with ", }" or "}" + boolean canContinue= LT(1) == IToken.tCOMMA; + if (canContinue) + consume(); + + switch (LT(1)) { + case IToken.tRBRACE: + int lastOffset = consume().getEndOffset(); + setRange(result, offset, lastOffset); + return result; + + case IToken.tEOC: + setRange(result, offset, LA(1).getOffset()); + return result; + } + + if (!canContinue || LA(1).getOffset() == checkOffset) { + throwBacktrack(offset, LA(1).getEndOffset() - offset); + } + } + // consume the closing brace } protected ICASTDesignatedInitializer createDesignatorInitializer() { @@ -260,102 +251,67 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return new CASTInitializerExpression(); } - protected List designatorList() throws EndOfFileException, - BacktrackException { - // designated initializers for C - List designatorList= Collections.emptyList(); - - if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { - while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { - if (LT(1) == IToken.tDOT) { + private List designatorList() throws EndOfFileException, BacktrackException { + final int lt1= LT(1); + if (lt1 == IToken.tDOT || lt1 == IToken.tLBRACKET) { + List designatorList= null; + while (true) { + switch (LT(1)) { + case IToken.tDOT: int offset = consume().getOffset(); IToken id = identifier(); - ICASTFieldDesignator designator = createFieldDesignator(); - ((ASTNode) designator).setOffsetAndLength(offset, id.getEndOffset() - offset); IASTName n = createName(id); - designator.setName(n); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } else if (LT(1) == IToken.tLBRACKET) { - IToken mark = consume(); - int offset = mark.getOffset(); + ICASTFieldDesignator fieldDesignator = createFieldDesignator(); + setRange(fieldDesignator, offset, id.getEndOffset()); + fieldDesignator.setName(n); + if (designatorList == null) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(fieldDesignator); + break; + + case IToken.tLBRACKET: + offset = consume().getOffset(); IASTExpression constantExpression = expression(); - if (LT(1) == IToken.tRBRACKET) { - int lastOffset = consume().getEndOffset(); - ICASTArrayDesignator designator = createArrayDesignator(); - ((ASTNode) designator).setOffsetAndLength(offset, lastOffset - offset); - designator.setSubscriptExpression(constantExpression); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - continue; - } - backup(mark); - if (supportGCCStyleDesignators) { - int startOffset = consume(IToken.tLBRACKET).getOffset(); - IASTExpression constantExpression1 = expression(); - consume(IToken.tELLIPSIS); - IASTExpression constantExpression2 = expression(); + if (supportGCCStyleDesignators && LT(1) == IToken.tELLIPSIS) { + consume(IToken.tELLIPSIS); + IASTExpression constantExpression2 = expression(); + int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); + IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); + setRange(designator, offset, lastOffset); + designator.setRangeFloor(constantExpression); + designator.setRangeCeiling(constantExpression2); + if (designatorList == null) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + designatorList.add(designator); + } else { int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); - IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); - ((ASTNode) designator).setOffsetAndLength(startOffset, lastOffset - startOffset); - designator.setRangeFloor(constantExpression1); - designator.setRangeCeiling(constantExpression2); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); + ICASTArrayDesignator designator = createArrayDesignator(); + setRange(designator, offset, lastOffset); + designator.setSubscriptExpression(constantExpression); + if (designatorList == null) + designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); designatorList.add(designator); } - } else if (supportGCCStyleDesignators - && LT(1) == IToken.tIDENTIFIER) { - IToken identifier = identifier(); - int lastOffset = consume(IToken.tCOLON).getEndOffset(); - ICASTFieldDesignator designator = createFieldDesignator(); - ((ASTNode) designator).setOffsetAndLength(identifier - .getOffset(), lastOffset - identifier.getOffset()); - IASTName n = createName(identifier); - designator.setName(n); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); + break; + + default: + return designatorList; } } - } else { - if (supportGCCStyleDesignators - && (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tLBRACKET)) { - - if (LT(1) == IToken.tIDENTIFIER) { - // fix for 84176: if reach identifier and it's not a designator then return empty designator list - if (LT(2) != IToken.tCOLON) - return designatorList; - - IToken identifier = identifier(); - int lastOffset = consume(IToken.tCOLON).getEndOffset(); - ICASTFieldDesignator designator = createFieldDesignator(); - ((ASTNode) designator).setOffsetAndLength(identifier - .getOffset(), lastOffset - identifier.getOffset()); - IASTName n = createName(identifier); - designator.setName(n); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } else if (LT(1) == IToken.tLBRACKET) { - int startOffset = consume().getOffset(); - IASTExpression constantExpression1 = expression(); - consume(IToken.tELLIPSIS); - IASTExpression constantExpression2 = expression(); - int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); - IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); - ((ASTNode) designator).setOffsetAndLength(startOffset, lastOffset - startOffset); - designator.setRangeFloor(constantExpression1); - designator.setRangeCeiling(constantExpression2); - if (designatorList == Collections.EMPTY_LIST) - designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE); - designatorList.add(designator); - } - } - } - return designatorList; + } + + // fix for 84176: if reach identifier and it's not a designator then return empty designator list + if (supportGCCStyleDesignators && lt1 == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) { + IToken identifier = identifier(); + int lastOffset = consume(IToken.tCOLON).getEndOffset(); + ICASTFieldDesignator designator = createFieldDesignator(); + ((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset()); + IASTName n = createName(identifier); + designator.setName(n); + return Collections.singletonList(designator); + } + + return null; } protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() { @@ -689,8 +645,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { if (t != null) { consume(IToken.tRPAREN).getEndOffset(); if (LT(1) == IToken.tLBRACE) { - final List emptyList = Collections.emptyList(); - IASTInitializer i = cInitializerClause(emptyList, false); + IASTInitializer i = cInitializerClause(false); firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i)); break; }