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.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;
IASTExpression unaryExpression = null;
IToken m = mark();
int lastOffset = 0;
if (LT(1) == IToken.tLPAREN) {
if (LT(2) == IToken.tLBRACE) {
unaryExpression = compoundStatementExpression();
lastOffset = calculateEndOffset(unaryExpression);
} else {
boolean needBack = false;
try {
consume(); // tLPAREN
d = typeId(false);
if (d == null)
needBack = true;
else
lastOffset = consume(IToken.tRPAREN).getEndOffset();
} catch (BacktrackException bt) {
needBack = true;
}
if (needBack) {
backup(m);
d = null;
unaryExpression = unaryExpression();
lastOffset = calculateEndOffset(unaryExpression);
}
}
// prefer unary expressions over type-expressions
if (LT(1) == IToken.tLPAREN && LT(2) != IToken.tLBRACE) {
consume();
final IToken m = mark();
try {
unaryExpression= unaryExpression();
}
catch (BacktrackException e) {
backup(m);
d = typeId(false);
if (d == null)
throw new BacktrackException();
}
lastOffset = consume(IToken.tRPAREN).getEndOffset();
} else {
unaryExpression = unaryExpression();
lastOffset = calculateEndOffset(unaryExpression);
}
if (d != null & unaryExpression == null)
return buildTypeIdExpression(IGNUASTTypeIdExpression.op_typeof, d,
offset, lastOffset);
else if (unaryExpression != null && d == null)
return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof,
unaryExpression, offset, lastOffset);
if (d != null)
return buildTypeIdExpression(IGNUASTTypeIdExpression.op_typeof, d, offset, lastOffset);
if (unaryExpression != null)
return buildUnaryExpression(IGNUASTUnaryExpression.op_typeof, unaryExpression, offset, lastOffset);
return null;
}
@ -2016,6 +2006,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
protected boolean canBeTypeSpecifier() throws EndOfFileException {
switch (LT(1)) {
// simple type specifiers:
case IToken.tIDENTIFIER:
@ -2050,12 +2041,16 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
case IToken.t_const:
case IToken.t_volatile:
case IToken.t_restrict:
return true;
// gcc-special
case IGCCToken.t_typeof:
// content assist
case IToken.tCOMPLETION:
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.IASTStatement;
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.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
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.ICScope;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTUnaryExpression;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IndexFilter;
@ -213,42 +216,54 @@ public class CScope implements ICScope, IASTInternalScope {
int type = getNamespaceType( name );
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 )
return (IBinding) o;
IASTName foundName= (IASTName) o;
if( (resolve || foundName.getBinding() != null) && ( foundName != name ) ) {
if(!isTypeDefinition(name) || CVisitor.declaredBefore(foundName, name)) {
return foundName.resolveBinding();
if (o != null && o != name) {
IASTName foundName= (IASTName) o;
if( (resolve || foundName.getBinding() != null) && ( foundName != name ) ) {
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) {
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)
@ -259,17 +274,17 @@ public class CScope implements ICScope, IASTInternalScope {
Object[] obj = null;
for (int i = 0; i < bindings.length; i++) {
for (CharArrayObjectMap binding : bindings) {
if (prefixLookup) {
Object[] keys = bindings[i].keyArray();
for (int j = 0; j < keys.length; j++) {
char[] key = (char[]) keys[j];
Object[] keys = binding.keyArray();
for (Object key2 : keys) {
char[] key = (char[]) key2;
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 {
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);
IBinding[] result = null;
for (int i = 0; i < obj.length; i++) {
if( obj[i] instanceof IBinding )
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, obj[i]);
for (Object element : obj) {
if( element instanceof IBinding )
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, element);
if( (resolve || ((IASTName)obj[i]).getBinding() != null) && ( obj[i] != name ) )
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, ((IASTName)obj[i]).resolveBinding());
if( (resolve || ((IASTName)element).getBinding() != null) && ( element != name ) )
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, ((IASTName)element).resolveBinding());
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);

View file

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

View file

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