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:
parent
413d358931
commit
e9f3d2a3a2
3 changed files with 143 additions and 168 deletions
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue