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;
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;
} }
IASTInitializerExpression result= createInitializerExpression();
for (;;) { result.setExpression(assignmentExpression);
final IToken startToken= LA(1); setRange(result, assignmentExpression);
// required at least one initializer list
// get designator list
List<IASTNode> 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);
return result; return result;
} }
// if we get this far, it means that we have not yet succeeded
// try this now instead // it's an aggregate initializer
// assignmentExpression consume(IToken.tLBRACE);
IASTExpression assignmentExpression = assignmentExpression(); IASTInitializerList result = createInitializerList();
if (inAggregateInitializer && skipTrivialExpressionsInAggregateInitializers) {
if (!ASTQueries.canContainName(assignmentExpression)) // bug 196468, gcc accepts empty braces.
return null; if (supportGCCStyleDesignators && LT(1) == IToken.tRBRACE) {
int endOffset= consume().getEndOffset();
setRange(result, offset, endOffset);
return result;
} }
IASTInitializerExpression result = createInitializerExpression();
result.setExpression(assignmentExpression); for (;;) {
((ASTNode) result).setOffsetAndLength( final int checkOffset= LA(1).getOffset();
((ASTNode) assignmentExpression).getOffset(), // required at least one initializer list
((ASTNode) assignmentExpression).getLength()); // get designator list
return result; List<? extends ICASTDesignator> 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() { 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(); consume(IToken.tELLIPSIS);
ICASTArrayDesignator designator = createArrayDesignator(); IASTExpression constantExpression2 = expression();
((ASTNode) designator).setOffsetAndLength(offset, lastOffset - offset); int lastOffset = consume(IToken.tRBRACKET).getEndOffset();
designator.setSubscriptExpression(constantExpression); IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator();
if (designatorList == Collections.EMPTY_LIST) setRange(designator, offset, lastOffset);
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE); designator.setRangeFloor(constantExpression);
designatorList.add(designator); designator.setRangeCeiling(constantExpression2);
continue; if (designatorList == null)
} designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
backup(mark); designatorList.add(designator);
if (supportGCCStyleDesignators) { } else {
int startOffset = consume(IToken.tLBRACKET).getOffset();
IASTExpression constantExpression1 = expression();
consume(IToken.tELLIPSIS);
IASTExpression constantExpression2 = expression();
int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); int lastOffset = consume(IToken.tRBRACKET).getEndOffset();
IGCCASTArrayRangeDesignator designator = createArrayRangeDesignator(); ICASTArrayDesignator designator = createArrayDesignator();
((ASTNode) designator).setOffsetAndLength(startOffset, lastOffset - startOffset); setRange(designator, offset, lastOffset);
designator.setRangeFloor(constantExpression1); designator.setSubscriptExpression(constantExpression);
designator.setRangeCeiling(constantExpression2); if (designatorList == null)
if (designatorList == Collections.EMPTY_LIST) designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator); designatorList.add(designator);
} }
} else if (supportGCCStyleDesignators break;
&& LT(1) == IToken.tIDENTIFIER) {
IToken identifier = identifier(); default:
int lastOffset = consume(IToken.tCOLON).getEndOffset(); return designatorList;
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 { }
if (supportGCCStyleDesignators
&& (LT(1) == IToken.tIDENTIFIER || LT(1) == IToken.tLBRACKET)) { // 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) {
if (LT(1) == IToken.tIDENTIFIER) { IToken identifier = identifier();
// fix for 84176: if reach identifier and it's not a designator then return empty designator list int lastOffset = consume(IToken.tCOLON).getEndOffset();
if (LT(2) != IToken.tCOLON) ICASTFieldDesignator designator = createFieldDesignator();
return designatorList; ((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset());
IASTName n = createName(identifier);
IToken identifier = identifier(); designator.setName(n);
int lastOffset = consume(IToken.tCOLON).getEndOffset(); return Collections.singletonList(designator);
ICASTFieldDesignator designator = createFieldDesignator(); }
((ASTNode) designator).setOffsetAndLength(identifier
.getOffset(), lastOffset - identifier.getOffset()); return null;
IASTName n = createName(identifier);
designator.setName(n);
if (designatorList == Collections.EMPTY_LIST)
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 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;
} }