mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-18 22:45:23 +02:00
Empty versus no exception specification, bug 86943.
This commit is contained in:
parent
fe9a0ddd82
commit
1aae35abf1
9 changed files with 71 additions and 49 deletions
|
@ -5962,4 +5962,28 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
public void testTypeIdForPtrToMember_Bug242197() throws Exception {
|
||||
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||
}
|
||||
|
||||
// void test1();
|
||||
// void test2() throw ();
|
||||
// void test3() throw (int);
|
||||
public void testEmptyExceptionSpecification_Bug86943() throws Exception {
|
||||
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||
|
||||
IASTSimpleDeclaration d= getDeclaration(tu, 0);
|
||||
ICPPASTFunctionDeclarator fdtor= (ICPPASTFunctionDeclarator) d.getDeclarators()[0];
|
||||
IASTTypeId[] specs= fdtor.getExceptionSpecification();
|
||||
assertEquals(0, specs.length);
|
||||
assertSame(ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION, specs);
|
||||
|
||||
d= getDeclaration(tu, 1);
|
||||
fdtor= (ICPPASTFunctionDeclarator) d.getDeclarators()[0];
|
||||
specs= fdtor.getExceptionSpecification();
|
||||
assertEquals(0, specs.length);
|
||||
assertNotSame(ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION, specs);
|
||||
|
||||
d= getDeclaration(tu, 2);
|
||||
fdtor= (ICPPASTFunctionDeclarator) d.getDeclarators()[0];
|
||||
specs= fdtor.getExceptionSpecification();
|
||||
assertEquals(1, specs.length);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class ExceptionTest extends ChangeGeneratorTest {
|
|||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
source = "void foo(int parameter) throw (int){\n}\n\n"; //$NON-NLS-1$
|
||||
expectedSource = "void foo(int parameter){\n}\n\n"; //$NON-NLS-1$
|
||||
expectedSource = "void foo(int parameter) throw (){\n}\n\n"; //$NON-NLS-1$
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
|
|
|
@ -295,14 +295,15 @@ public class ASTStringUtil {
|
|||
buffer.append("=0 "); //$NON-NLS-1$
|
||||
}
|
||||
final IASTTypeId[] exceptionTypeIds= cppFunctionDecl.getExceptionSpecification();
|
||||
if (exceptionTypeIds.length > 0) {
|
||||
buffer.append(Keywords.THROW).append(' ');
|
||||
if (exceptionTypeIds != ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION) {
|
||||
buffer.append(Keywords.THROW).append(" ("); //$NON-NLS-1$
|
||||
for (int i= 0; i < exceptionTypeIds.length; i++) {
|
||||
if (i > 0) {
|
||||
buffer.append(COMMA_SPACE);
|
||||
}
|
||||
appendTypeIdString(buffer, exceptionTypeIds[i]);
|
||||
}
|
||||
buffer.append(')');
|
||||
}
|
||||
}
|
||||
} else if (declarator instanceof IASTFieldDeclarator) {
|
||||
|
|
|
@ -22,6 +22,12 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
|||
*/
|
||||
public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarator {
|
||||
|
||||
/**
|
||||
* Used as return value for {@link #getExceptionSpecification()}.
|
||||
* @since 5.1
|
||||
*/
|
||||
public static final IASTTypeId[] NO_EXCEPTION_SPECIFICATION = {};
|
||||
|
||||
/**
|
||||
* <code>EXCEPTION_TYPEID</code> represents the type IDs throws in the
|
||||
* exception specification.
|
||||
|
@ -60,7 +66,9 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato
|
|||
public void setPureVirtual(boolean isPureVirtual);
|
||||
|
||||
/**
|
||||
* Get the exception specification.
|
||||
* Returns an array of type-ids representing the exception specification. The return value
|
||||
* {@link #NO_EXCEPTION_SPECIFICATION} indicates that no exceptions are specified, whereas
|
||||
* {@link IASTTypeId#EMPTY_TYPEID_ARRAY} is used for an empty exception specification.
|
||||
*/
|
||||
public IASTTypeId[] getExceptionSpecification();
|
||||
|
||||
|
@ -69,6 +77,13 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato
|
|||
*/
|
||||
public void addExceptionSpecificationTypeId(IASTTypeId typeId);
|
||||
|
||||
/**
|
||||
* Configures the declarator with an empty exception specification (as opposed to having none).
|
||||
*
|
||||
* @since 5.1
|
||||
*/
|
||||
public void setEmptyExceptionSpecification();
|
||||
|
||||
/**
|
||||
* Get function scope this node represents. Returns <code>null</code>, if this declarator does not
|
||||
* declare a function-prototype or function-definition.
|
||||
|
|
|
@ -284,14 +284,12 @@ public class ArrayUtil {
|
|||
* The position of the last non-null element in the array must also be known.
|
||||
*/
|
||||
public static Object[] removeNullsAfter(Class<?> c, Object[] array, int index) {
|
||||
if( array == null || index < 0)
|
||||
return (Object[]) Array.newInstance( c, 0 );
|
||||
|
||||
final int newLen= index+1;
|
||||
if( array.length == newLen)
|
||||
if (array != null && array.length == newLen)
|
||||
return array;
|
||||
|
||||
Object[] newArray = (Object[]) Array.newInstance(c, newLen);
|
||||
if (array != null && newLen > 0)
|
||||
System.arraycopy(array, 0, newArray, 0, newLen);
|
||||
return newArray;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
|||
public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPASTFunctionDeclarator {
|
||||
private IASTParameterDeclaration[] parameters = null;
|
||||
private int parametersPos = -1;
|
||||
private IASTTypeId[] typeIds = null;
|
||||
private IASTTypeId[] typeIds = NO_EXCEPTION_SPECIFICATION;
|
||||
private int typeIdsPos = -1;
|
||||
|
||||
private boolean varArgs;
|
||||
|
@ -86,12 +86,13 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
}
|
||||
|
||||
public IASTTypeId[] getExceptionSpecification() {
|
||||
if (typeIds == null)
|
||||
return IASTTypeId.EMPTY_TYPEID_ARRAY;
|
||||
|
||||
return typeIds= ArrayUtil.trimAt(IASTTypeId.class, typeIds, typeIdsPos);
|
||||
}
|
||||
|
||||
public void setEmptyExceptionSpecification() {
|
||||
typeIds= IASTTypeId.EMPTY_TYPEID_ARRAY;
|
||||
}
|
||||
|
||||
public void addExceptionSpecificationTypeId(IASTTypeId typeId) {
|
||||
if (typeId != null) {
|
||||
typeIds = (IASTTypeId[]) ArrayUtil.append(IASTTypeId.class, typeIds, ++typeIdsPos, typeId);
|
||||
|
|
|
@ -170,9 +170,7 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
|
|||
public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||
private static final int DEFAULT_PARM_LIST_SIZE = 4;
|
||||
private static final int DEFAULT_POINTEROPS_LIST_SIZE = 4;
|
||||
private static final int DEFAULT_SIZE_EXCEPTIONS_LIST = 2;
|
||||
private static final int DEFAULT_CATCH_HANDLER_LIST_SIZE= 4;
|
||||
private static final int DEFAULT_PARAMETER_LIST_SIZE= 4;
|
||||
private static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {};
|
||||
private static enum DtorStrategy {PREFER_FUNCTION, PREFER_NESTED}
|
||||
|
||||
|
@ -3434,10 +3432,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
IToken last = consume(IToken.tLPAREN);
|
||||
int startOffset= last.getOffset();
|
||||
boolean seenParameter= false;
|
||||
boolean encounteredVarArgs= false;
|
||||
List<IASTParameterDeclaration> parameters= null;
|
||||
int endOffset= last.getEndOffset();
|
||||
|
||||
final ICPPASTFunctionDeclarator fc= createFunctionDeclarator();
|
||||
paramLoop: while(true) {
|
||||
switch (LT(1)) {
|
||||
case IToken.tRPAREN:
|
||||
|
@ -3446,7 +3443,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
break paramLoop;
|
||||
case IToken.tELLIPSIS:
|
||||
endOffset= consume().getEndOffset();
|
||||
encounteredVarArgs = true;
|
||||
fc.setVarArgs(true);
|
||||
break;
|
||||
case IToken.tCOMMA:
|
||||
endOffset= consume().getEndOffset();
|
||||
|
@ -3457,10 +3454,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
throwBacktrack(startOffset, endOffset - startOffset);
|
||||
|
||||
IASTParameterDeclaration pd = parameterDeclaration();
|
||||
fc.addParameterDeclaration(pd);
|
||||
endOffset = calculateEndOffset(pd);
|
||||
if (parameters == null)
|
||||
parameters = new ArrayList<IASTParameterDeclaration>(DEFAULT_PARAMETER_LIST_SIZE);
|
||||
parameters.add(pd);
|
||||
seenParameter = true;
|
||||
break;
|
||||
}
|
||||
|
@ -3469,20 +3464,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
// Consume any number of __attribute__ tokens after the parameters
|
||||
__attribute_decl_seq(supportAttributeSpecifiers, false);
|
||||
|
||||
boolean isConst= false;
|
||||
boolean isVolatile= false;
|
||||
boolean isPureVirtual= false;
|
||||
ArrayList<IASTTypeId> exceptionSpecIds= null;
|
||||
|
||||
// cv-qualifiers
|
||||
cvloop: while(true) {
|
||||
switch(LT(1)) {
|
||||
case IToken.t_const:
|
||||
isConst= true;
|
||||
fc.setConst(true);
|
||||
endOffset= consume().getEndOffset();
|
||||
break;
|
||||
case IToken.t_volatile:
|
||||
isVolatile= true;
|
||||
fc.setVolatile(true);
|
||||
endOffset= consume().getEndOffset();
|
||||
break;
|
||||
default:
|
||||
|
@ -3492,7 +3482,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
// throws clause
|
||||
if (LT(1) == IToken.t_throw) {
|
||||
exceptionSpecIds = new ArrayList<IASTTypeId>(DEFAULT_SIZE_EXCEPTIONS_LIST);
|
||||
fc.setEmptyExceptionSpecification();
|
||||
consume(); // throw
|
||||
consume(IToken.tLPAREN);
|
||||
|
||||
|
@ -3509,7 +3499,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
int thoffset= LA(1).getOffset();
|
||||
IASTTypeId typeId= typeId(DeclarationOptions.TYPEID);
|
||||
if (typeId != null) {
|
||||
exceptionSpecIds.add(typeId);
|
||||
fc.addExceptionSpecificationTypeId(typeId);
|
||||
} else {
|
||||
int thendoffset= LA(1).getOffset();
|
||||
if (thoffset == thendoffset) {
|
||||
|
@ -3519,7 +3509,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
IASTProblemTypeId typeIdProblem = createTypeIDProblem();
|
||||
typeIdProblem.setProblem(p);
|
||||
((ASTNode) typeIdProblem).setOffsetAndLength(((ASTNode) p));
|
||||
exceptionSpecIds.add(typeIdProblem);
|
||||
fc.addExceptionSpecificationTypeId(typeIdProblem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3535,24 +3525,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (image.length == 1 && image[0] == '0') {
|
||||
consume(); // tASSIGN
|
||||
endOffset= consume().getEndOffset(); // tINTEGER
|
||||
isPureVirtual= true;
|
||||
fc.setPureVirtual(true);
|
||||
}
|
||||
}
|
||||
|
||||
final ICPPASTFunctionDeclarator fc= createFunctionDeclarator();
|
||||
fc.setVarArgs(encounteredVarArgs);
|
||||
fc.setConst(isConst);
|
||||
fc.setVolatile(isVolatile);
|
||||
fc.setPureVirtual(isPureVirtual);
|
||||
if (parameters != null) {
|
||||
for (IASTParameterDeclaration param : parameters) {
|
||||
fc.addParameterDeclaration(param);
|
||||
}
|
||||
}
|
||||
if (exceptionSpecIds != null)
|
||||
for (IASTTypeId exception : exceptionSpecIds) {
|
||||
fc.addExceptionSpecificationTypeId(exception);
|
||||
}
|
||||
((ASTNode) fc).setOffsetAndLength(startOffset, endOffset-startOffset);
|
||||
return fc;
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ public class DeclaratorWriter extends NodeWriter {
|
|||
}
|
||||
|
||||
protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, IASTTypeId[] exceptions) {
|
||||
if(exceptions.length != 0) {
|
||||
if (exceptions != ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION) {
|
||||
scribe.printSpace();
|
||||
scribe.print(THROW);
|
||||
scribe.print('(');
|
||||
|
|
|
@ -65,6 +65,13 @@ public class ModifiedASTDeclaratorWriter extends DeclaratorWriter {
|
|||
@Override
|
||||
protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, IASTTypeId[] exceptions ) {
|
||||
IASTTypeId[] modifiedExceptions = modificationHelper.createModifiedChildArray(funcDec, exceptions, IASTTypeId.class);
|
||||
// it makes a difference whether the exception array is identical to
|
||||
// ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION
|
||||
if (modifiedExceptions.length == 0 &&
|
||||
exceptions == ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION) {
|
||||
modifiedExceptions= ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION;
|
||||
}
|
||||
|
||||
super.writeExceptionSpecification(funcDec, modifiedExceptions);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue