1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 18:56:02 +02:00

Correct parsing of typeof-expressions, bug 226492.

This commit is contained in:
Markus Schorn 2008-04-10 15:35:21 +00:00
parent 027bd802aa
commit 1e97408e2b
5 changed files with 94 additions and 84 deletions

View file

@ -4474,4 +4474,14 @@ public class AST2Tests extends AST2BaseTest {
parseAndCheckBindings(code, ParserLanguage.C, true); parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true); parseAndCheckBindings(code, ParserLanguage.CPP, true);
} }
// void test(int count) {
// __typeof__(count) a= 1;
// int ret0 = ((__typeof__(count)) 1);
// }
public void testTypeofExpression_Bug226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
}
} }

View file

@ -852,41 +852,31 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTTypeId d = null; IASTTypeId d = null;
IASTExpression unaryExpression = null; IASTExpression unaryExpression = null;
IToken m = mark();
int lastOffset = 0; int lastOffset = 0;
if (LT(1) == IToken.tLPAREN) { // prefer unary expressions over type-expressions
if (LT(2) == IToken.tLBRACE) { if (LT(1) == IToken.tLPAREN && LT(2) != IToken.tLBRACE) {
unaryExpression = compoundStatementExpression(); consume();
lastOffset = calculateEndOffset(unaryExpression); final IToken m = mark();
} else { try {
boolean needBack = false; unaryExpression= unaryExpression();
try { }
consume(); // tLPAREN catch (BacktrackException e) {
d = typeId(false); backup(m);
if (d == null) d = typeId(false);
needBack = true; if (d == null)
else throw new BacktrackException();
lastOffset = consume(IToken.tRPAREN).getEndOffset(); }
} catch (BacktrackException bt) { lastOffset = consume(IToken.tRPAREN).getEndOffset();
needBack = true;
}
if (needBack) {
backup(m);
d = null;
unaryExpression = unaryExpression();
lastOffset = calculateEndOffset(unaryExpression);
}
}
} else { } else {
unaryExpression = unaryExpression(); unaryExpression = unaryExpression();
lastOffset = calculateEndOffset(unaryExpression); lastOffset = calculateEndOffset(unaryExpression);
} }
if (d != null & unaryExpression == null) if (d != null)
return buildTypeIdExpression(IGNUASTTypeIdExpression.op_typeof, d, return buildTypeIdExpression(IGNUASTTypeIdExpression.op_typeof, d, offset, lastOffset);
offset, lastOffset);
else if (unaryExpression != null && d == null) if (unaryExpression != null)
return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof, return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof, unaryExpression, offset, lastOffset);
unaryExpression, offset, lastOffset);
return null; return null;
} }
@ -2016,6 +2006,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
protected boolean canBeTypeSpecifier() throws EndOfFileException { protected boolean canBeTypeSpecifier() throws EndOfFileException {
switch (LT(1)) { switch (LT(1)) {
// simple type specifiers: // simple type specifiers:
case IToken.tIDENTIFIER: case IToken.tIDENTIFIER:
@ -2050,12 +2041,16 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
case IToken.t_const: case IToken.t_const:
case IToken.t_volatile: case IToken.t_volatile:
case IToken.t_restrict: case IToken.t_restrict:
return true;
// gcc-special
case IGCCToken.t_typeof:
// content assist
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
return true; return true;
default:
return false;
} }
return false;
} }
} }

View file

@ -32,12 +32,15 @@ import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
import org.eclipse.cdt.core.dom.ast.c.ICScope; import org.eclipse.cdt.core.dom.ast.c.ICScope;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTUnaryExpression;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
@ -213,42 +216,54 @@ public class CScope implements ICScope, IASTInternalScope {
int type = getNamespaceType( name ); int type = getNamespaceType( name );
Object o = bindings[type].get( name.toCharArray() ); Object o = bindings[type].get( name.toCharArray() );
if( o == null || name == o) {
IBinding result= null;
if(physicalNode instanceof IASTTranslationUnit) {
final IASTTranslationUnit tu = (IASTTranslationUnit)physicalNode;
IIndex index= tu.getIndex();
if(index!=null) {
try {
IBinding[] bindings= index.findBindings(name.toCharArray(), INDEX_FILTERS[type], new NullProgressMonitor());
if (fileSet != null) {
bindings= fileSet.filterFileLocalBindings(bindings);
}
result= processIndexResults(name, bindings);
} catch(CoreException ce) {
CCorePlugin.log(ce);
}
}
}
return result;
}
if( o instanceof IBinding ) if( o instanceof IBinding )
return (IBinding) o; return (IBinding) o;
IASTName foundName= (IASTName) o; if (o != null && o != name) {
if( (resolve || foundName.getBinding() != null) && ( foundName != name ) ) { IASTName foundName= (IASTName) o;
if(!isTypeDefinition(name) || CVisitor.declaredBefore(foundName, name)) { if( (resolve || foundName.getBinding() != null) && ( foundName != name ) ) {
return foundName.resolveBinding(); if(!isTypeDefinition(name) || CVisitor.declaredBefore(foundName, name)) {
return foundName.resolveBinding();
}
} }
} }
return null; IBinding result= null;
if(physicalNode instanceof IASTTranslationUnit) {
final IASTTranslationUnit tu = (IASTTranslationUnit)physicalNode;
IIndex index= tu.getIndex();
if(index!=null) {
try {
IBinding[] bindings= index.findBindings(name.toCharArray(), INDEX_FILTERS[type], new NullProgressMonitor());
if (fileSet != null) {
bindings= fileSet.filterFileLocalBindings(bindings);
}
result= processIndexResults(name, bindings);
} catch(CoreException ce) {
CCorePlugin.log(ce);
}
}
}
return result;
} }
private boolean isTypeDefinition(IASTName name) { private boolean isTypeDefinition(IASTName name) {
return name.getPropertyInParent()==IASTNamedTypeSpecifier.NAME; if (name.getPropertyInParent()==IASTNamedTypeSpecifier.NAME) {
return true;
}
IASTNode parent= name.getParent();
while (parent != null) {
if (parent instanceof IASTUnaryExpression) {
if (((IASTUnaryExpression) parent).getOperator() == IGNUASTUnaryExpression.op_typeof)
return true;
}
else if (parent instanceof IASTTypeIdExpression) {
if (((IASTTypeIdExpression) parent).getOperator() == IASTTypeIdExpression.op_typeof)
return true;
}
parent= parent.getParent();
}
return false;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -259,17 +274,17 @@ public class CScope implements ICScope, IASTInternalScope {
Object[] obj = null; Object[] obj = null;
for (int i = 0; i < bindings.length; i++) { for (CharArrayObjectMap binding : bindings) {
if (prefixLookup) { if (prefixLookup) {
Object[] keys = bindings[i].keyArray(); Object[] keys = binding.keyArray();
for (int j = 0; j < keys.length; j++) { for (Object key2 : keys) {
char[] key = (char[]) keys[j]; char[] key = (char[]) key2;
if (CharArrayUtils.equals(key, 0, c.length, c, true)) { if (CharArrayUtils.equals(key, 0, c.length, c, true)) {
obj = ArrayUtil.append(obj, bindings[i].get(key)); obj = ArrayUtil.append(obj, binding.get(key));
} }
} }
} else { } else {
obj = ArrayUtil.append(obj, bindings[i].get(c)); obj = ArrayUtil.append(obj, binding.get(c));
} }
} }
@ -294,12 +309,12 @@ public class CScope implements ICScope, IASTInternalScope {
obj = ArrayUtil.trim(Object.class, obj); obj = ArrayUtil.trim(Object.class, obj);
IBinding[] result = null; IBinding[] result = null;
for (int i = 0; i < obj.length; i++) { for (Object element : obj) {
if( obj[i] instanceof IBinding ) if( element instanceof IBinding )
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, obj[i]); result = (IBinding[]) ArrayUtil.append(IBinding.class, result, element);
if( (resolve || ((IASTName)obj[i]).getBinding() != null) && ( obj[i] != name ) ) if( (resolve || ((IASTName)element).getBinding() != null) && ( element != name ) )
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, ((IASTName)obj[i]).resolveBinding()); result = (IBinding[]) ArrayUtil.append(IBinding.class, result, ((IASTName)element).resolveBinding());
} }
return (IBinding[]) ArrayUtil.trim(IBinding.class, result); return (IBinding[]) ArrayUtil.trim(IBinding.class, result);

View file

@ -1234,7 +1234,7 @@ public class CVisitor {
} }
} }
} }
boolean prefix = ( bits & PREFIX_LOOKUP ) != 0; boolean prefix = ( bits & PREFIX_LOOKUP ) != 0;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Object binding = prefix ? new ObjectSet( 2 ) : null; Object binding = prefix ? new ObjectSet( 2 ) : null;

View file

@ -1024,23 +1024,13 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
declSpecifier = declSpecifierSeq(false, true); declSpecifier = declSpecifierSeq(false, true);
} catch (FoundDeclaratorException e) { } catch (FoundDeclaratorException e) {
return null; return null;
// backup(mark);
// throwBacktrack( e.currToken );
} }
declarator = declarator(); declarator = declarator();
} catch (BacktrackException bt) { } catch (BacktrackException bt) {
return null; return null;
// backup(mark);
// throwBacktrack(bt);
} }
if (declarator == null || declarator.getName().toCharArray().length > 0) if (declarator == null || declarator.getName().toCharArray().length > 0)
{
return null; return null;
// backup(mark);
// throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
// declarator)
// - startingOffset);
}
IASTTypeId result = createTypeId(); IASTTypeId result = createTypeId();
((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset( ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset(