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

Bug 90606 - [IBinding] Problem from sizeof ambiguity

Bug 86861 - [Parser] IASTProblemStatement with cast expression as selector
This commit is contained in:
John Camelon 2005-05-05 18:53:50 +00:00
parent 6447835c74
commit c4c31b724f
10 changed files with 5129 additions and 5128 deletions

View file

@ -88,55 +88,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 3.3.6-5):
typedef int c;
enum { i = 1 };
class X {
int i=3;
char v[i];
int f() { return sizeof(c); } // OK: X::c
char c;
enum { i = 2 };
};
typedef char* T;
struct Y {
typedef long T;
T b;
};
typedef int I;
class D {
typedef I I; // error, even though no reordering involved
};
--End Example]
*/
public void test3_3_6s5() { // TODO raised bug 90606
StringBuffer buffer = new StringBuffer();
buffer.append("typedef int c;\n"); //$NON-NLS-1$
buffer.append("enum { i = 1 };\n"); //$NON-NLS-1$
buffer.append("class X {\n"); //$NON-NLS-1$
buffer.append("int i=3;\n"); //$NON-NLS-1$
buffer.append("char v[i];\n"); //$NON-NLS-1$
buffer.append("int f() { return sizeof(c); } // OK: X::c\n"); //$NON-NLS-1$
buffer.append("char c;\n"); //$NON-NLS-1$
buffer.append("enum { i = 2 };\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("typedef char* T;\n"); //$NON-NLS-1$
buffer.append("struct Y {\n"); //$NON-NLS-1$
buffer.append("typedef long T;\n"); //$NON-NLS-1$
buffer.append("T b;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("typedef int I;\n"); //$NON-NLS-1$
buffer.append("class D {\n"); //$NON-NLS-1$
buffer.append("typedef I I; // error, even though no reordering involved\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 3.4.1-10):
struct A {
@ -493,42 +444,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 13.4-5a):
int f(double);
int f(int);
int (*pfd)(double) = &f; // selects f(double)
int (*pfi)(int) = &f; // selects f(int)
int (*pfe)(...) = &f; // error: type mismatch
int (&rfi)(int) = f; // selects f(int)
int (&rfd)(double) = f; // selects f(double)
void g() {
(int (*)(int))&f; // cast expression as selector
}
--End Example]
*/
public void test13_4s5a() { // TODO raised bug 90674
StringBuffer buffer = new StringBuffer();
buffer.append("int f(double);\n"); //$NON-NLS-1$
buffer.append("int f(int);\n"); //$NON-NLS-1$
buffer.append("int (*pfd)(double) = &f; // selects f(double)\n"); //$NON-NLS-1$
buffer.append("int (*pfi)(int) = &f; // selects f(int)\n"); //$NON-NLS-1$
buffer.append("int (*pfe)(...) = &f; // error: type mismatch\n"); //$NON-NLS-1$
buffer.append("int (&rfi)(int) = f; // selects f(int)\n"); //$NON-NLS-1$
buffer.append("int (&rfd)(double) = f; // selects f(double)\n"); //$NON-NLS-1$
buffer.append("void g() {\n"); //$NON-NLS-1$
buffer.append("(int (*)(int))&f; // cast expression as selector\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, false, 0);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 14.3-2):
template<class T> void f();
@ -1181,7 +1096,4 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
} catch (Exception e) {
}
}
}

View file

@ -12136,4 +12136,79 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 3.3.6-5):
typedef int c;
enum { i = 1 };
class X {
int i=3;
char v[i];
int f() { return sizeof(c); } // OK: X::c
char c;
enum { i = 2 };
};
typedef char* T;
struct Y {
typedef long T;
T b;
};
typedef int I;
class D {
typedef I I; // error, even though no reordering involved
};
--End Example]
*/
public void test3_3_6s5() throws Exception { // 90606
StringBuffer buffer = new StringBuffer();
buffer.append("typedef int c;\n"); //$NON-NLS-1$
buffer.append("enum { i = 1 };\n"); //$NON-NLS-1$
buffer.append("class X {\n"); //$NON-NLS-1$
buffer.append("int i=3;\n"); //$NON-NLS-1$
buffer.append("char v[i];\n"); //$NON-NLS-1$
buffer.append("int f() { return sizeof(c); } // OK: X::c\n"); //$NON-NLS-1$
buffer.append("char c;\n"); //$NON-NLS-1$
buffer.append("enum { i = 2 };\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("typedef char* T;\n"); //$NON-NLS-1$
buffer.append("struct Y {\n"); //$NON-NLS-1$
buffer.append("typedef long T;\n"); //$NON-NLS-1$
buffer.append("T b;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("typedef int I;\n"); //$NON-NLS-1$
buffer.append("class D {\n"); //$NON-NLS-1$
buffer.append("typedef I I; // error, even though no reordering involved\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 13.4-5a):
int f(double);
int f(int);
int (*pfd)(double) = &f; // selects f(double)
int (*pfi)(int) = &f; // selects f(int)
int (*pfe)(...) = &f; // error: type mismatch
int (&rfi)(int) = f; // selects f(int)
int (&rfd)(double) = f; // selects f(double)
void g() {
(int (*)(int))&f; // cast expression as selector
}
--End Example]
* @throws ParserException
*/
public void test13_4s5a() throws ParserException { // bug 90674
StringBuffer buffer = new StringBuffer();
buffer.append("int f(double);\n"); //$NON-NLS-1$
buffer.append("int f(int);\n"); //$NON-NLS-1$
buffer.append("int (*pfd)(double) = &f; // selects f(double)\n"); //$NON-NLS-1$
buffer.append("int (*pfi)(int) = &f; // selects f(int)\n"); //$NON-NLS-1$
buffer.append("int (*pfe)(...) = &f; // error: type mismatch\n"); //$NON-NLS-1$
buffer.append("int (&rfi)(int) = f; // selects f(int)\n"); //$NON-NLS-1$
buffer.append("int (&rfd)(double) = f; // selects f(double)\n"); //$NON-NLS-1$
buffer.append("void g() {\n"); //$NON-NLS-1$
buffer.append("(int (*)(int))&f; // cast expression as selector\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, false, 0);
}
}

View file

@ -1,6 +1,7 @@
package org.eclipse.cdt.core.parser.tests.ast2;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@ -229,9 +230,10 @@ public class AST2UtilOldTests extends AST2BaseTest {
}
// Kind UNARY_SIZEOF_TYPEID : unsigned int
public void testUnarySizeofTypeId() throws Exception {
IASTTranslationUnit tu = parse("int y = foo( sizeof(x) );".toString(), ParserLanguage.CPP); //$NON-NLS-1$
IASTTranslationUnit tu = parse("int x, y = foo( sizeof(x) );".toString(), ParserLanguage.CPP); //$NON-NLS-1$
IASTDeclaration[] d = tu.getDeclarations();
isExpressionStringEqual( ((IASTInitializerExpression)((IASTSimpleDeclaration)d[0]).getDeclarators()[0].getInitializer()).getExpression(), "foo(sizeof (x))" ); //$NON-NLS-1$
final IASTExpression expression = ((IASTInitializerExpression)((IASTSimpleDeclaration)d[0]).getDeclarators()[1].getInitializer()).getExpression();
isExpressionStringEqual( expression, "foo(sizeof (x))" ); //$NON-NLS-1$
}
// Kind NEW_TYPEID
public void testNewTypeId() throws Exception {

View file

@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
@ -389,6 +390,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IToken simpleDeclarationMark;
private static final IASTNode[] EMPTY_NODE_ARRAY = new IASTNode[0];
public IASTTranslationUnit parse() {
long startTime = System.currentTimeMillis();
translationUnit();
@ -633,8 +636,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpression multiplicativeExpression()
throws BacktrackException, EndOfFileException;
protected abstract IASTTypeId typeId(boolean skipArrayMods,
boolean forNewExpression) throws BacktrackException,
protected abstract IASTTypeId typeId(boolean forNewExpression) throws BacktrackException,
EndOfFileException;
protected abstract IASTExpression castExpression()
@ -938,7 +940,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if (LT(1) == IToken.tLPAREN) {
try {
consume(IToken.tLPAREN);
d = typeId(false, false);
d = typeId(false);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
} catch (BacktrackException bt) {
backup(m);
@ -974,7 +976,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} else
try {
consume(IToken.tLPAREN);
d = typeId(false, false);
d = typeId(false);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
} catch (BacktrackException bt) {
backup(m);
@ -2105,5 +2107,107 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throwBacktrack(token.getOffset(), token.getLength());
}
protected IASTNode[] parseTypeIdOrUnaryExpression(boolean typeIdWithParentheses ) throws EndOfFileException {
IASTTypeId typeId = null;
IASTExpression unaryExpression = null;
IToken typeIdLA = null, unaryExpressionLA = null;
IToken mark = mark();
try
{
if( typeIdWithParentheses )
consume( IToken.tLPAREN );
typeId = typeId( false );
if( typeIdWithParentheses )
{
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
consume();
break;
default:
throw backtrack;
}
}
typeIdLA = LA(1);
}
catch( BacktrackException bte )
{
typeId = null;
}
backup( mark );
try
{
unaryExpression = unaryExpression();
unaryExpressionLA = LA(1);
}
catch( BacktrackException bte )
{
unaryExpression = null;
}
IASTNode [] result;
if( unaryExpression == null && typeId != null )
{
backup( typeIdLA );
result = new IASTNode[1];
result[0] = typeId;
return result;
}
if( unaryExpression != null && typeId == null )
{
backup( unaryExpressionLA );
result = new IASTNode[1];
result[0] = unaryExpression;
return result;
}
if( unaryExpression != null && typeId != null && typeIdLA == unaryExpressionLA )
{
result = new IASTNode[2];
result[0] = typeId;
result[1] = unaryExpression;
return result;
}
return EMPTY_NODE_ARRAY;
}
protected abstract IASTAmbiguousExpression createAmbiguousExpression();
protected IASTExpression parseSizeofExpression() throws BacktrackException, EndOfFileException {
int startingOffset = consume(IToken.t_sizeof).getOffset();
IASTNode[] choice = parseTypeIdOrUnaryExpression(true);
switch (choice.length) {
case 1:
int lastOffset = calculateEndOffset(choice[0]);
if (choice[0] instanceof IASTExpression)
return buildUnaryExpression(IASTUnaryExpression.op_sizeof,
(IASTExpression) choice[0], startingOffset, lastOffset);
else if (choice[0] instanceof IASTTypeId)
return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof,
(IASTTypeId) choice[0], startingOffset, lastOffset);
throwBacktrack(LA(1));
break;
case 2:
lastOffset = calculateEndOffset(choice[0]);
IASTAmbiguousExpression ambExpr = createAmbiguousExpression();
IASTExpression e1 = buildTypeIdExpression(
IASTTypeIdExpression.op_sizeof, (IASTTypeId) choice[0],
startingOffset, lastOffset);
IASTExpression e2 = buildUnaryExpression(
IASTUnaryExpression.op_sizeof, (IASTExpression) choice[1],
startingOffset, lastOffset);
ambExpr.addExpression(e1);
e1.setParent(ambExpr);
e1.setPropertyInParent(IASTAmbiguousExpression.SUBEXPRESSION);
ambExpr.addExpression(e2);
e2.setParent(ambExpr);
e2.setPropertyInParent(IASTAmbiguousExpression.SUBEXPRESSION);
((ASTNode) ambExpr).setOffsetAndLength((ASTNode) e2);
return ambExpr;
default:
}
throwBacktrack(LA(1));
return null;
}
}

View file

@ -51,9 +51,12 @@ public abstract class CASTAmbiguity extends CASTNode {
* @param j
* @throws DOMException
*/
protected void clearCache(IASTName[] names, int j) throws DOMException {
protected void clearCache(IASTName[] names, int j) {
IScope scope = CPPVisitor.getContainingScope( names[j] );
try {
scope.flushCache();
} catch (DOMException e) {
}
}
/**
@ -66,7 +69,8 @@ public abstract class CASTAmbiguity extends CASTNode {
IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent();
IASTNode s = nodes[bestIndex];
owner.replace(this, nodes[bestIndex]);
if( !s.accept( visitor ) ) return false;
if (!s.accept(visitor))
return false;
return true;
}

View file

@ -0,0 +1,36 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
public class CASTAmbiguousExpression extends CASTAmbiguity implements
IASTAmbiguousExpression {
private IASTExpression [] expressions = new IASTExpression[2];
public void addExpression(IASTExpression e) {
expressions = (IASTExpression[]) ArrayUtil.append( IASTExpression.class, expressions, e );
}
public IASTExpression[] getExpressions() {
return (IASTExpression[]) ArrayUtil.removeNulls( IASTExpression.class, expressions );
}
protected IASTNode[] getNodes() {
return getExpressions();
}
}

View file

@ -101,6 +101,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.BacktrackException;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
/**
@ -799,7 +800,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// If this isn't a type name, then we shouldn't be here
try {
try {
typeId = typeId(false, false);
typeId = typeId(false);
consume(IToken.tRPAREN);
castExpression = castExpression();
} catch (BacktrackException bte) {
@ -849,7 +850,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tLPAREN) {
try {
consume(IToken.tLPAREN);
typeId = typeId(false, false);
typeId = typeId(false);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
} catch (BacktrackException bt) {
backup(mark);
@ -924,7 +925,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IToken m = mark();
try {
int offset = consume(IToken.tLPAREN).getOffset();
IASTTypeId t = typeId(false, false);
IASTTypeId t = typeId(false);
consume(IToken.tRPAREN).getEndOffset();
IASTInitializer i = cInitializerClause(Collections.EMPTY_LIST);
firstExpression = buildTypeIdInitializerExpression(t, i,
@ -1194,8 +1195,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTIdExpression();
}
protected IASTTypeId typeId(boolean skipArrayModifiers,
boolean forNewExpression) throws EndOfFileException,
protected IASTTypeId typeId(boolean forNewExpression) throws EndOfFileException,
BacktrackException {
IToken mark = mark();
int startingOffset = mark.getOffset();
@ -2595,50 +2595,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTAmbiguousStatement();
}
// static class HeuristicTypeDetector extends CASTVisitor
// {
// private final char[] lookingForName;
// boolean result = false;
//
// {
// shouldVisitDeclarations = true;
// }
//
// public HeuristicTypeDetector( char [] name )
// {
// this.lookingForName = name;
// }
//
// public int visit(IASTDeclaration declaration) {
// if( declaration instanceof IASTSimpleDeclaration )
// {
// IASTSimpleDeclaration sd = (IASTSimpleDeclaration) declaration;
// if( sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef )
// {
// IASTDeclarator [] declarators = sd.getDeclarators();
// for( int i = 0; i < declarators.length; ++i )
// if( CharArrayUtils.equals( declarators[i].getName().toCharArray(), lookingForName ) )
// {
// result = true;
// return PROCESS_ABORT;
// }
// }
// }
// return PROCESS_CONTINUE;
// }
//
// public boolean getAnswer()
// {
// return result;
// }
//
// }
//
// protected boolean queryIsTypeName(IASTName name) {
// HeuristicTypeDetector nc = new HeuristicTypeDetector( name.toCharArray() );
// translationUnit.accept(nc);
// return nc.result;
// }
protected IASTAmbiguousExpression createAmbiguousExpression() {
return new CASTAmbiguousExpression();
}
}

View file

@ -70,7 +70,7 @@ public class CPPUnknownBinding implements ICPPInternalUnknown {
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#createDelegate(org.eclipse.cdt.core.dom.ast.IASTName)
*/
public ICPPDelegate createDelegate( IASTName name ) {
public ICPPDelegate createDelegate( IASTName name1 ) {
return null;
}

View file

@ -26,7 +26,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
* @author aniefer
*/
public class CPPUnknownScope implements ICPPScope {
private ICPPScope parentScope = null;
private IBinding binding = null;
private IASTName scopeName = null;
private CharArrayObjectMap map = null;
@ -78,7 +77,7 @@ public class CPPUnknownScope implements ICPPScope {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#removeBinding(org.eclipse.cdt.core.dom.ast.IBinding)
*/
public void removeBinding( IBinding binding ) {
public void removeBinding( IBinding binding1 ) {
}

View file

@ -170,8 +170,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected CPPASTTranslationUnit translationUnit;
private static final IASTNode[] EMPTY_NODE_ARRAY = new IASTNode[0];
private static class ScopeStack {
private int[] stack;
@ -291,7 +289,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IToken mark = mark();
try {
IASTTypeId typeId = typeId(false, false);
IASTTypeId typeId = typeId(false);
list.add(typeId);
completedArg = true;
} catch (BacktrackException e) {
@ -473,7 +471,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} else {
// must be a conversion function
IToken t = LA(1);
typeId = typeId(true, false);
typeId = typeId(true);
if (t != LA(1)) {
while (t.getNext() != LA(1)) {
t = t.getNext();
@ -895,7 +893,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// If this isn't a type name, then we shouldn't be here
try {
try {
typeId = typeId(false, false);
typeId = typeId(false);
consume(IToken.tRPAREN);
} catch (BacktrackException bte) {
backup(mark);
@ -925,9 +923,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
/**
* @throws BacktrackException
*/
protected IASTTypeId typeId(boolean skipArrayModifiers,
boolean forNewExpression) throws EndOfFileException,
BacktrackException {
protected IASTTypeId typeId(boolean forNewExpression)
throws EndOfFileException, BacktrackException {
IToken mark = mark();
int startingOffset = mark.getOffset();
IASTDeclSpecifier declSpecifier = null;
@ -936,8 +933,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
try {
declSpecifier = declSpecifierSeq(true, true);
if (LT(1) != IToken.tEOC)
declarator = declarator(SimpleDeclarationStrategy.TRY_CONSTRUCTOR,
true, forNewExpression);
declarator = declarator(
SimpleDeclarationStrategy.TRY_CONSTRUCTOR, forNewExpression,
forNewExpression);
} catch (BacktrackException bt) {
backup(mark);
throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
@ -945,8 +943,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
- startingOffset);
}
if (declarator != null) {
if (declarator.getName().toString() != null)
{
if (declarator.getName().toString() != null) {
backup(mark);
throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
declarator)
@ -959,7 +956,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
declarator)
- startingOffset);
}
if (declarator instanceof IASTArrayDeclarator && skipArrayModifiers) {
if (declarator instanceof IASTArrayDeclarator && forNewExpression) {
backup(mark);
throwBacktrack(startingOffset, figureEndOffset(declSpecifier,
declarator)
@ -1109,7 +1106,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// CASE: new (typeid-not-looking-as-placement) ...
// the first expression in () is not a placement
// - then it has to be typeId
typeId = typeId(true, false);
typeId = typeId(true);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
@ -1132,7 +1129,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// - then it has to be typeId
try {
backtrackMarker = mark();
typeId = typeId(true, true);
typeId = typeId(true);
lastOffset = calculateEndOffset(typeId);
break master_new_loop;
} catch (BacktrackException e) {
@ -1150,7 +1147,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// The problem is, the first expression might as well be a
// typeid
try {
typeId = typeId(true, false);
typeId = typeId(true);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
@ -1207,7 +1204,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// CASE: new typeid ...
// new parameters do not start with '('
// i.e it has to be a plain typeId
typeId = typeId(true, true);
typeId = typeId(true);
lastOffset = calculateEndOffset(typeId);
isNewTypeId = true;
break master_new_loop;
@ -1292,8 +1289,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
*/
protected IASTExpression unaryExpression() throws EndOfFileException,
BacktrackException {
IToken la = LA(1);
int startingOffset = la.getOffset();
switch (LT(1)) {
case IToken.tSTAR:
return unaryOperatorCastExpression(IASTUnaryExpression.op_star);// IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION);
@ -1312,38 +1307,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tDECR:
return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixDecr);// IASTExpression.Kind.UNARY_DECREMENT);
case IToken.t_sizeof:
consume(IToken.t_sizeof);
IToken mark = LA(1);
IASTTypeId typeId = null;
int lastOffset = 0;
IASTExpression unaryExpression = null;
if (LT(1) == IToken.tLPAREN) {
try {
consume(IToken.tLPAREN);
typeId = typeId(true, false);
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
lastOffset = consume().getEndOffset();
break;
default:
throw backtrack;
}
} catch (BacktrackException bt) {
backup(mark);
unaryExpression = unaryExpression();
lastOffset = calculateEndOffset(unaryExpression);
}
} else {
unaryExpression = unaryExpression();
lastOffset = calculateEndOffset(unaryExpression);
}
if (typeId == null && unaryExpression != null)
return buildUnaryExpression(IASTUnaryExpression.op_sizeof,
unaryExpression, startingOffset, lastOffset);
return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof,
typeId, startingOffset, lastOffset);
return parseSizeofExpression();
case IToken.t_new:
return newExpression();
case IToken.t_delete:
@ -1464,37 +1428,35 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN);
}
IASTNode [] n = parseTypeIdOrUnaryExpression();
IASTNode[] n = parseTypeIdOrUnaryExpression(false);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
if (templateIdScopes.size() > 0) {
templateIdScopes.pop();
}
switch( n.length )
{
switch (n.length) {
case 0:
throwBacktrack(LA(1));
break;
case 1:
if( n[0] instanceof IASTTypeId )
{
if (n[0] instanceof IASTTypeId) {
firstExpression = buildTypeIdExpression(
ICPPASTTypeIdExpression.op_typeid, (IASTTypeId) n[0], so,
lastOffset);
}
else if( n[0] instanceof IASTExpression )
{
ICPPASTTypeIdExpression.op_typeid,
(IASTTypeId) n[0], so, lastOffset);
} else if (n[0] instanceof IASTExpression) {
firstExpression = buildUnaryExpression(
ICPPASTUnaryExpression.op_typeid, (IASTExpression) n[0], so, lastOffset);
ICPPASTUnaryExpression.op_typeid,
(IASTExpression) n[0], so, lastOffset);
}
break;
case 2:
IASTAmbiguousExpression ambExpr = createAmbiguousExpression();
IASTExpression e1 = buildTypeIdExpression(
ICPPASTTypeIdExpression.op_typeid, (IASTTypeId) n[0], so,
lastOffset);
ICPPASTTypeIdExpression.op_typeid, (IASTTypeId) n[0],
so, lastOffset);
IASTExpression e2 = buildUnaryExpression(
ICPPASTUnaryExpression.op_typeid, (IASTExpression) n[1], so, lastOffset);
ICPPASTUnaryExpression.op_typeid,
(IASTExpression) n[1], so, lastOffset);
ambExpr.addExpression(e1);
e1.setParent(ambExpr);
e1.setPropertyInParent(IASTAmbiguousExpression.SUBEXPRESSION);
@ -1664,56 +1626,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return new CPPASTAmbiguousExpression();
}
protected IASTNode[] parseTypeIdOrUnaryExpression() throws EndOfFileException {
IASTTypeId typeId = null;
IASTExpression unaryExpression = null;
IToken typeIdLA = null, unaryExpressionLA = null;
IToken mark = mark();
try
{
typeId = typeId( false, false );
typeIdLA = LA(1);
}
catch( BacktrackException bte )
{
typeId = null;
}
backup( mark );
try
{
unaryExpression = unaryExpression();
unaryExpressionLA = LA(1);
}
catch( BacktrackException bte )
{
unaryExpression = null;
}
IASTNode [] result;
if( unaryExpression == null && typeId != null )
{
backup( typeIdLA );
result = new IASTNode[1];
result[0] = typeId;
return result;
}
if( unaryExpression != null && typeId == null )
{
backup( unaryExpressionLA );
result = new IASTNode[1];
result[0] = unaryExpression;
return result;
}
if( unaryExpression != null && typeId != null && typeIdLA == unaryExpressionLA )
{
result = new IASTNode[2];
result[0] = typeId;
result[1] = unaryExpression;
return result;
}
return EMPTY_NODE_ARRAY;
}
/**
* @return
*/
@ -1940,7 +1852,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
int startingOffset = LA(1).getOffset();
IToken op = consume();
consume(IToken.tLT);
IASTTypeId typeID = typeId(false, false);
IASTTypeId typeID = typeId(false);
consume(IToken.tGT);
consume(IToken.tLPAREN);
IASTExpression lhs = expression();
@ -2367,7 +2279,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tASSIGN) // optional = type-id
{
consume(IToken.tASSIGN);
typeId = typeId(false, false); // type-id
typeId = typeId(false); // type-id
lastOffset = calculateEndOffset(typeId);
}
} else {
@ -3769,7 +3681,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* parameterDeclarationClause ")" (oldKRParameterDeclaration)* declaratorId :
* name
*
* @param forTypeID
* @param forNewTypeId
* TODO
* @param skipArrayDeclarator
* TODO
@ -3780,7 +3692,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* request a backtrack
*/
protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy,
boolean forTypeID, boolean skipArrayDeclarator)
boolean forNewTypeId, boolean skipArrayDeclarator)
throws EndOfFileException, BacktrackException {
IToken la = LA(1);
@ -3805,11 +3717,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
finalOffset = calculateEndOffset((IASTNode) pointerOps
.get(pointerOps.size() - 1));
if (!forTypeID && LT(1) == IToken.tLPAREN) {
if (!forNewTypeId && LT(1) == IToken.tLPAREN) {
IToken mark = mark();
try {
consume();
innerDecl = declarator(strategy, forTypeID,
innerDecl = declarator(strategy, forNewTypeId,
skipArrayDeclarator);
finalOffset = consume(IToken.tRPAREN).getEndOffset();
} catch (BacktrackException bte) {
@ -3858,7 +3770,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
if ((!LA(2).looksLikeExpression()
&& strategy != SimpleDeclarationStrategy.TRY_VARIABLE
&& !failed && !forTypeID)) {
&& !failed && !forNewTypeId)) {
// parameterDeclarationClause
isFunction = true;
// TODO need to create a temporary scope object here
@ -3945,7 +3857,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
default:
IToken before = LA(1);
try {
exceptionSpecIds.add(typeId(false, false));
exceptionSpecIds.add(typeId(false));
} catch (BacktrackException e) {
IASTProblem p = failParse(e);
IASTProblemTypeId typeIdProblem = createTypeIDProblem();
@ -5079,7 +4991,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return result;
}
/*
* (non-Javadoc)
*
@ -5139,7 +5050,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
}
private static class EmptyVisitor extends CPPASTVisitor {
{
shouldVisitStatements = true;