1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Cleanup parsing c-initializers, related to 253690.

This commit is contained in:
Markus Schorn 2008-11-10 15:08:58 +00:00
parent 413d358931
commit e9f3d2a3a2
3 changed files with 143 additions and 168 deletions

View file

@ -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();
}
}
} }

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; 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.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
@ -36,6 +37,8 @@ public class ASTQueries {
return true; return true;
if (expr instanceof IASTIdExpression) if (expr instanceof IASTIdExpression)
return true; return true;
if (expr instanceof IASTCastExpression)
return true;
if (expr instanceof IASTUnaryExpression) { if (expr instanceof IASTUnaryExpression) {
IASTUnaryExpression uexpr= (IASTUnaryExpression) expr; IASTUnaryExpression uexpr= (IASTUnaryExpression) expr;

View file

@ -159,93 +159,84 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
BacktrackException { BacktrackException {
if (LT(1) == IToken.tASSIGN) { if (LT(1) == IToken.tASSIGN) {
consume(); consume();
final List<IASTNode> empty= Collections.emptyList(); return cInitializerClause(false);
return cInitializerClause(empty, false);
} }
return null; return null;
} }
protected IASTInitializer cInitializerClause(List<IASTNode> designators, boolean inAggregateInitializer) protected IASTInitializer cInitializerClause(boolean inAggregate) throws EndOfFileException, BacktrackException {
throws EndOfFileException, BacktrackException { final int offset = LA(1).getOffset();
IToken la = LA(1); if (LT(1) != IToken.tLBRACE) {
int startingOffset = la.getOffset(); IASTExpression assignmentExpression= assignmentExpression();
la = null; if (inAggregate && skipTrivialExpressionsInAggregateInitializers) {
if (LT(1) == IToken.tLBRACE) { if (!ASTQueries.canContainName(assignmentExpression))
consume(); return null;
}
IASTInitializerExpression result= createInitializerExpression();
result.setExpression(assignmentExpression);
setRange(result, assignmentExpression);
return result;
}
// it's an aggregate initializer
consume(IToken.tLBRACE);
IASTInitializerList result = createInitializerList(); IASTInitializerList result = createInitializerList();
((ASTNode) result).setOffset(startingOffset);
// bug 196468, gcc accepts empty braces. // bug 196468, gcc accepts empty braces.
if (supportGCCStyleDesignators && LT(1) == (IToken.tRBRACE)) { if (supportGCCStyleDesignators && LT(1) == IToken.tRBRACE) {
int l = consume().getEndOffset(); int endOffset= consume().getEndOffset();
((ASTNode) result).setLength(l - startingOffset); setRange(result, offset, endOffset);
return result; return result;
} }
for (;;) { for (;;) {
final IToken startToken= LA(1); final int checkOffset= LA(1).getOffset();
// required at least one initializer list // required at least one initializer list
// get designator list // get designator list
List<IASTNode> newDesignators = designatorList(); List<? extends ICASTDesignator> designator= designatorList();
if (newDesignators.size() != 0) if (designator == null) {
if (LT(1) == IToken.tASSIGN) IASTInitializer initializer= cInitializerClause(true);
consume();
IASTInitializer initializer = cInitializerClause(newDesignators, true);
// depending on value of skipTrivialItemsInCompoundInitializers initializer may be null // depending on value of skipTrivialItemsInCompoundInitializers initializer may be null
if (initializer != null) { if (initializer != null) {
if (newDesignators.isEmpty()) {
result.addInitializer(initializer); result.addInitializer(initializer);
}
} else { } else {
if (LT(1) == IToken.tASSIGN)
consume();
IASTInitializer initializer= cInitializerClause(false);
ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer(); ICASTDesignatedInitializer desigInitializer = createDesignatorInitializer();
((ASTNode) desigInitializer).setOffsetAndLength( setRange(desigInitializer, designator.get(0));
((ASTNode) newDesignators.get(0)).getOffset(), adjustLength(desigInitializer, initializer);
((ASTNode)initializer).getOffset() + ((ASTNode)initializer).getLength() - ((ASTNode) newDesignators.get(0)).getOffset());
for (int i = 0; i < newDesignators.size(); ++i) { for (ICASTDesignator d : designator) {
ICASTDesignator d = (ICASTDesignator) newDesignators.get(i);
desigInitializer.addDesignator(d); desigInitializer.addDesignator(d);
} }
desigInitializer.setOperandInitializer(initializer); desigInitializer.setOperandInitializer(initializer);
result.addInitializer(desigInitializer); result.addInitializer(desigInitializer);
} }
}
// can end with ", }" or "}"
if (LT(1) == IToken.tCOMMA)
consume();
if (LT(1) == IToken.tRBRACE)
break;
final IToken nextToken= LA(1); // can end with ", }" or "}"
if (nextToken.getType() == IToken.tEOC) { 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; return result;
} }
if (nextToken == startToken) {
throwBacktrack(startingOffset, nextToken.getEndOffset() - startingOffset);
return null;
}
// otherwise, its another initializer in the list if (!canContinue || LA(1).getOffset() == checkOffset) {
throwBacktrack(offset, LA(1).getEndOffset() - offset);
}
} }
// consume the closing brace // consume the closing brace
int lastOffset = consume(IToken.tRBRACE).getEndOffset();
((ASTNode) result).setLength(lastOffset - startingOffset);
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;
}
IASTInitializerExpression result = createInitializerExpression();
result.setExpression(assignmentExpression);
((ASTNode) result).setOffsetAndLength(
((ASTNode) assignmentExpression).getOffset(),
((ASTNode) assignmentExpression).getLength());
return result;
} }
protected ICASTDesignatedInitializer createDesignatorInitializer() { protected ICASTDesignatedInitializer createDesignatorInitializer() {
@ -260,102 +251,67 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTInitializerExpression(); return new CASTInitializerExpression();
} }
protected List<IASTNode> designatorList() throws EndOfFileException, private List<? extends ICASTDesignator> designatorList() throws EndOfFileException, BacktrackException {
BacktrackException { final int lt1= LT(1);
// designated initializers for C if (lt1 == IToken.tDOT || lt1 == IToken.tLBRACKET) {
List<IASTNode> designatorList= Collections.emptyList(); List<ICASTDesignator> designatorList= null;
while (true) {
if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { switch (LT(1)) {
while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) { case IToken.tDOT:
if (LT(1) == IToken.tDOT) {
int offset = consume().getOffset(); int offset = consume().getOffset();
IToken id = identifier(); IToken id = identifier();
ICASTFieldDesignator designator = createFieldDesignator();
((ASTNode) designator).setOffsetAndLength(offset, id.getEndOffset() - offset);
IASTName n = createName(id); IASTName n = createName(id);
designator.setName(n); ICASTFieldDesignator fieldDesignator = createFieldDesignator();
if (designatorList == Collections.EMPTY_LIST) setRange(fieldDesignator, offset, id.getEndOffset());
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); fieldDesignator.setName(n);
designatorList.add(designator); if (designatorList == null)
} else if (LT(1) == IToken.tLBRACKET) { designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
IToken mark = consume(); designatorList.add(fieldDesignator);
int offset = mark.getOffset(); break;
case IToken.tLBRACKET:
offset = consume().getOffset();
IASTExpression constantExpression = expression(); IASTExpression constantExpression = expression();
if (LT(1) == IToken.tRBRACKET) { if (supportGCCStyleDesignators && LT(1) == IToken.tELLIPSIS) {
int lastOffset = consume().getEndOffset();
ICASTArrayDesignator designator = createArrayDesignator();
((ASTNode) designator).setOffsetAndLength(offset, lastOffset - offset);
designator.setSubscriptExpression(constantExpression);
if (designatorList == Collections.EMPTY_LIST)
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
continue;
}
backup(mark);
if (supportGCCStyleDesignators) {
int startOffset = consume(IToken.tLBRACKET).getOffset();
IASTExpression constantExpression1 = expression();
consume(IToken.tELLIPSIS); consume(IToken.tELLIPSIS);
IASTExpression constantExpression2 = expression(); IASTExpression constantExpression2 = expression();
int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); int lastOffset = consume(IToken.tRBRACKET).getEndOffset();
IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator();
((ASTNode) designator).setOffsetAndLength(startOffset, lastOffset - startOffset); setRange(designator, offset, lastOffset);
designator.setRangeFloor(constantExpression1); designator.setRangeFloor(constantExpression);
designator.setRangeCeiling(constantExpression2); designator.setRangeCeiling(constantExpression2);
if (designatorList == Collections.EMPTY_LIST) if (designatorList == null)
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator); 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<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
}
}
} else { } else {
if (supportGCCStyleDesignators int lastOffset = consume(IToken.tRBRACKET).getEndOffset();
&& (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tLBRACKET)) { ICASTArrayDesignator designator = createArrayDesignator();
setRange(designator, offset, lastOffset);
designator.setSubscriptExpression(constantExpression);
if (designatorList == null)
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
}
break;
if (LT(1) == IToken.tIDENTIFIER) { default:
// fix for 84176: if reach identifier and it's not a designator then return empty designator list
if (LT(2) != IToken.tCOLON)
return designatorList; 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(); IToken identifier = identifier();
int lastOffset = consume(IToken.tCOLON).getEndOffset(); int lastOffset = consume(IToken.tCOLON).getEndOffset();
ICASTFieldDesignator designator = createFieldDesignator(); ICASTFieldDesignator designator = createFieldDesignator();
((ASTNode) designator).setOffsetAndLength(identifier ((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset());
.getOffset(), lastOffset - identifier.getOffset());
IASTName n = createName(identifier); IASTName n = createName(identifier);
designator.setName(n); designator.setName(n);
if (designatorList == Collections.EMPTY_LIST) return Collections.singletonList(designator);
designatorList = new ArrayList<IASTNode>(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<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
} }
}
} return null;
return designatorList;
} }
protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() { protected IGCCASTArrayRangeDesignator createArrayRangeDesignator() {
@ -689,8 +645,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
if (t != null) { if (t != null) {
consume(IToken.tRPAREN).getEndOffset(); consume(IToken.tRPAREN).getEndOffset();
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
final List<IASTNode> emptyList = Collections.emptyList(); IASTInitializer i = cInitializerClause(false);
IASTInitializer i = cInitializerClause(emptyList, false);
firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i)); firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i));
break; break;
} }