1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00
Fixed Bug 40007 : Parser reports success when it fails
	Fixed Bug 44305 : Scanner/preprocessor fails on conditionals using hexidecimal 
	Fixed Bug 41935 : parser provides wrong name on namespace aliases 
	Fixed Bug 39525 : Parser fails on expressions that take address of overloaded operators 
	Fixed Bug 45287 : Scanner does not accept character sequence literals 
	Fixed Bug 36550 : Error recovery with unterminated string is weak 
	Fixed Bug 41063 : Remove unused K&R C support from ANSI Parser 
	Fixed Bug 39528 : Function try-blocks are not supported by the parser (ANSI C++) 
	Fixed Bug 39538 : Parser fails on explicit instantiation of templated operators 
	Fixed Bug 39536 : Parser fails on templated constructors/conversion operators 
	Refactored Scanner to make it easier to debug.  

TESTS
	Moved testBug40007() from ASTFailedTests to QuickParseASTTests.  
	Added QuickParseASTTests::testBug40759().  
	Added QuickParseASTTests::testBug44633().  
	Added ScannerTestCase::testBug44305().  
	Added QuickParseASTTests::testBug41935(). 
	Moved testBug39525() from ASTFailedTests to QuickParseASTTests.  
	Added ScannerTestCase::testBug45287(). 
	Moved testBug39528() from ASTFailedTests to QuickParseASTTests.  
	Moved testBug39538() from ASTFailedTests to QuickParseASTTests.  
	Added QuickParseASTTests::testBug39536().  
	Moved testBug39536A() from ASTFailedTests to QuickParseASTTests.  
	Moved testBug39536B() from ASTFailedTests to QuickParseASTTests.
This commit is contained in:
John Camelon 2003-10-21 23:22:40 +00:00
parent 503c0b61b6
commit dfdfecab15
22 changed files with 638 additions and 341 deletions

View file

@ -1,3 +1,17 @@
2003-10-21 John Camelon
Moved testBug40007() from ASTFailedTests to QuickParseASTTests.
Added QuickParseASTTests::testBug40759().
Added QuickParseASTTests::testBug44633().
Added ScannerTestCase::testBug44305().
Added QuickParseASTTests::testBug41935().
Moved testBug39525() from ASTFailedTests to QuickParseASTTests.
Added ScannerTestCase::testBug45287().
Moved testBug39528() from ASTFailedTests to QuickParseASTTests.
Moved testBug39538() from ASTFailedTests to QuickParseASTTests.
Added QuickParseASTTests::testBug39536().
Moved testBug39536A() from ASTFailedTests to QuickParseASTTests.
Moved testBug39536B() from ASTFailedTests to QuickParseASTTests.
2003-10-20 David Inglis
use project owner ID in plugin class

View file

@ -16,9 +16,7 @@ import java.util.Iterator;
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.tests.BaseASTTest;
@ -38,46 +36,7 @@ public class ASTFailedTests extends BaseASTTest
assertCodeFailsParse("FUNCTION_MACRO( 1, a )\n int i;");
}
public void testBug39525() throws Exception
{
assertCodeFailsParse("C &(C::*DD)(const C &x) = &C::operator=;");
}
public void testBug39528() throws Exception
{
Writer code = new StringWriter();
try
{
code.write("struct B: public A {\n");
code.write(" A a;\n");
code.write(" B() try : A(1), a(2)\n");
code.write(" { throw 1; }\n");
code.write(" catch (...)\n");
code.write(" { if (c != 3) r |= 1; }\n");
code.write("};\n");
}
catch (IOException ioe)
{
}
assertCodeFailsParse(code.toString());
}
public void testBug39536A() throws Exception
{
IASTTemplateDeclaration template = (IASTTemplateDeclaration)parse("template<class E> class X { X<E>(); };").getDeclarations().next();
IASTClassSpecifier classX = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)template.getOwnedDeclaration()).getTypeSpecifier();
IASTDeclaration d = (IASTDeclaration)classX.getDeclarations().next();
assertTrue( d instanceof IASTVariable ); // this is not right!
}
public void testBug39536B() throws Exception
{
assertCodeFailsParse("template<class E> class X { inline X<E>(int); };");
}
public void testBug39538() throws Exception
{
assertCodeFailsParse("template C::operator int<float> ();");
}
public void testBug39542() throws Exception
{
assertCodeFailsParse("void f(int a, struct {int b[a];} c) {}");
@ -303,11 +262,7 @@ public class ASTFailedTests extends BaseASTTest
{
assertCodeFailsParse("#ident \"@(#)filename.c 1.3 90/02/12\"");
}
//Here GCC-specific section ends
public void testBug40007() throws Exception
{
parse("int y = #;");
}
public void testBug40422() throws Exception {
// Parse and get the translaton unit

View file

@ -76,19 +76,13 @@ public class BaseASTTest extends TestCase
Iterator declarationIter = null;
try
{
try
{
declarationIter = parse(code).getDeclarations();
}
catch (ASTNotImplementedException e1)
{
// TODO Auto-generated catch block
}
declarationIter = parse(code).getDeclarations();
}
catch (ParserException e)
catch (ASTNotImplementedException e1)
{
// TODO Auto-generated catch block
}
assertNotNull( declarationIter );
assertTrue( declarationIter.hasNext() );
IASTDeclaration returnValue = (IASTDeclaration)declarationIter.next();

View file

@ -117,6 +117,7 @@ public class BaseScannerTest extends TestCase {
assertTrue(false);
}
}
public void validateChar( String expected ) throws ScannerException
{
try {
@ -205,6 +206,20 @@ public class BaseScannerTest extends TestCase {
public static final boolean verbose = false;
protected NullSourceElementRequestor callback = new NullSourceElementRequestor();
/**
* @param string
*/
protected void validateWideChar(String string) throws Exception
{
try {
IToken t= scanner.nextToken();
assertTrue(t.getType() == IToken.tLCHAR );
assertEquals( t.getImage(), string );
} catch (EndOfFile e) {
assertTrue(false);
}
}
}

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.core.parser.ast.IASTInitializerClause;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMacro;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceAlias;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
@ -1871,5 +1872,108 @@ public class QuickParseASTTests extends BaseASTTest
{
parse("class AString { operator char const *() const; };");
}
public void testBug40007() throws Exception
{
assertCodeFailsParse("int y = #;");
}
public void testBug40759() throws Exception
{
IASTClassSpecifier classSpec = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)assertSoleDeclaration( "#define X SomeName \n class X {};" )).getTypeSpecifier();
assertEquals( classSpec.getNameOffset() + 1, classSpec.getNameEndOffset() );
assertEquals( classSpec.getName(), "SomeName");
}
public void testBug44633() throws Exception
{
Writer writer = new StringWriter();
writer.write( "template <typename T> class A {};\n" );
writer.write( "class B { template <typename T> friend class A;\n" );
writer.write( "void method();\n" );
writer.write( "};\n" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration templateDecl = (IASTTemplateDeclaration)i.next();
IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
Iterator members = classB.getDeclarations();
IASTTemplateDeclaration friend = (IASTTemplateDeclaration)members.next();
IASTMethod method = (IASTMethod)members.next();
assertFalse( i.hasNext() );
}
public void testBug39525() throws Exception
{
parse("C &(C::*DD)(const C &x) = &C::operator=;");
}
public void testBug41935() throws Exception
{
Iterator i = parse( "namespace A { int x; } namespace B = A;" ).getDeclarations();
IASTNamespaceDefinition n = (IASTNamespaceDefinition)i.next();
IASTNamespaceAlias a = (IASTNamespaceAlias)i.next();
assertEquals( a.getName(), "B" );
assertFalse( i.hasNext() );
}
public void testBug39528() throws Exception
{
Writer code = new StringWriter();
try
{
code.write("struct B: public A {\n");
code.write(" A a;\n");
code.write(" B() try : A(1), a(2)\n");
code.write(" { throw 1; }\n");
code.write(" catch (...)\n");
code.write(" { if (c != 3) r |= 1; }\n");
code.write("};\n");
}
catch (IOException ioe)
{
}
IASTClassSpecifier structB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)assertSoleDeclaration(code.toString())).getTypeSpecifier();
Iterator members = structB.getDeclarations();
IASTField a = (IASTField)members.next();
IASTMethod b = (IASTMethod)members.next();
assertFalse( members.hasNext() );
assertTrue( b.hasFunctionTryBlock() );
}
public void testBug39538() throws Exception
{
parse("template C::operator int<float> ();");
}
public void testBug39536() throws Exception
{
Writer writer = new StringWriter();
writer.write( "template<class E>\n" );
writer.write( "class X {\n" );
writer.write( "X<E>(); // This fails \n" );
writer.write( "inline X<E>(int); // This also fails \n" );
writer.write( "inline ~X<E>(); // This works fine \n" );
writer.write( "};\n" );
IASTTemplateDeclaration template = (IASTTemplateDeclaration)assertSoleDeclaration( writer.toString() );
IASTClassSpecifier X = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)template.getOwnedDeclaration()).getTypeSpecifier();
Iterator members = X.getDeclarations();
IASTMethod defaultCons = (IASTMethod)members.next();
IASTMethod inlinedCons = (IASTMethod)members.next();
IASTMethod destructor = (IASTMethod)members.next();
assertFalse( members.hasNext() );
}
public void testBug39536A() throws Exception
{
IASTTemplateDeclaration template = (IASTTemplateDeclaration)parse("template<class E> class X { X<E>(); };").getDeclarations().next();
IASTClassSpecifier classX = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)template.getOwnedDeclaration()).getTypeSpecifier();
IASTDeclaration d = (IASTDeclaration)classX.getDeclarations().next();
assertTrue( d instanceof IASTMethod);
}
public void testBug39536B() throws Exception
{
parse("template<class E> class X { inline X<E>(int); };");
}
}

View file

@ -1366,7 +1366,7 @@ public class ScannerTestCase extends BaseScannerTest
// if Scanner.throwExceptionOnBadCharacterRead == true
// we might end up with valid ScannerException "Invalid character ..."
// for '\'
assertTrue(se.getMessage().equals("Invalid character '\\' read @ offset 5 of file TEXT"));
assertTrue(se.getErrorCode() == ScannerException.ErrorCode.BAD_CHARACTER );
}
}
@ -1391,4 +1391,25 @@ public class ScannerTestCase extends BaseScannerTest
validateString("@ \\\\n hh \\\"aa\\\"");
validateEOF();
}
public void testBug44305() throws Exception
{
StringWriter writer = new StringWriter();
writer.write( "#define WCHAR_MAX 0 \n");
writer.write( "#if WCHAR_MAX <= 0xff\n" );
writer.write( "bool\n");
writer.write( "#endif");
initializeScanner( writer.toString());
validateToken( IToken.t_bool );
validateEOF();
}
public void testBug45287() throws Exception
{
initializeScanner( "'abcdefg' L'hijklmnop'");
validateChar( "abcdefg" );
validateWideChar( "hijklmnop");
validateEOF();
}
}

View file

@ -1,3 +1,16 @@
2003-10-21 John Camelon
Fixed Bug 40007 : Parser reports success when it fails
Fixed Bug 44305 : Scanner/preprocessor fails on conditionals using hexidecimal
Fixed Bug 41935 : parser provides wrong name on namespace aliases
Fixed Bug 39525 : Parser fails on expressions that take address of overloaded operators
Fixed Bug 45287 : Scanner does not accept character sequence literals
Fixed Bug 36550 : Error recovery with unterminated string is weak
Fixed Bug 41063 : Remove unused K&R C support from ANSI Parser
Fixed Bug 39528 : Function try-blocks are not supported by the parser (ANSI C++)
Fixed Bug 39538 : Parser fails on explicit instantiation of templated operators
Fixed Bug 39536 : Parser fails on templated constructors/conversion operators
Refactored Scanner to make it easier to debug.
2003-10-01 John Camelon
Fixed Bug 43987 : Search results: Declaration of class not highlighted when selected
Fixed Bug 43997 : Search results: selection includes preceding whitespace

View file

@ -39,6 +39,7 @@ public class ScannerException extends Exception {
public static final ErrorCode MACRO_USAGE_ERROR = new ErrorCode( 14 );
public static final ErrorCode MACRO_PASTING_ERROR = new ErrorCode( 15 );
public static final ErrorCode CIRCULAR_INCLUSION = new ErrorCode( 16 );
public static final ErrorCode BAD_CHARACTER = new ErrorCode( 17 );
/**
* @param enumValue
*/
@ -73,6 +74,8 @@ public class ScannerException extends Exception {
*/
public boolean isSeriousError(ParserMode mode)
{
if(this == ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE)
return true;
if( mode == ParserMode.COMPLETE_PARSE )
if( this == ErrorCode.POUND_ERROR ||
this == ErrorCode.DEFINITION_NOT_FOUND ||
@ -81,8 +84,7 @@ public class ScannerException extends Exception {
this == ErrorCode.UNEXPECTED_EOF ||
this == ErrorCode.MACRO_USAGE_ERROR ||
this == ErrorCode.MACRO_PASTING_ERROR ||
this == ErrorCode.EXPRESSION_EVALUATION_ERROR ||
this == ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE ||
this == ErrorCode.EXPRESSION_EVALUATION_ERROR ||
this == ErrorCode.ATTEMPTED_REDEFINITION )
return true;
return false;
@ -123,7 +125,8 @@ public class ScannerException extends Exception {
errorMessages.put( ErrorCode.BAD_HEXIDECIMAL_FORMAT, "Invalid hexidecimal format " );
errorMessages.put( ErrorCode.INVALID_PREPROCESSOR_DIRECTIVE, "Invalid preprocessor directive format " );
errorMessages.put( ErrorCode.UNEXPECTED_EOF, "Unexpected End Of File " );
errorMessages.put( ErrorCode.MACRO_PASTING_ERROR, "Invalid use of macro pasting " );
errorMessages.put( ErrorCode.MACRO_PASTING_ERROR, "Invalid use of macro pasting " );
errorMessages.put( ErrorCode.BAD_CHARACTER, "Bad character sequence encountered:");
}
@ -166,4 +169,12 @@ public class ScannerException extends Exception {
{
return getErrorCode().isSeriousError( mode );
}
/**
* @return
*/
public String getInfoString()
{
return info;
}
}

View file

@ -147,7 +147,7 @@ public interface IASTFactory
boolean isVolatile,
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual, List constructorChain, boolean isDefinition ) throws ASTSemanticException, Exception;
boolean isPureVirtual, List constructorChain, boolean isDefinition, boolean hasFunctionTryBlock ) throws ASTSemanticException, Exception;
public IASTAbstractDeclaration createAbstractDeclaration(
boolean isConst,
boolean isVolatile,
@ -170,7 +170,7 @@ public interface IASTFactory
boolean isVolatile,
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isDefinition) throws ASTSemanticException, Exception;
boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isDefinition, boolean hasFunctionTryBlock) throws ASTSemanticException, Exception;
public IASTVariable createVariable(IASTScope scope, String name, boolean isAuto, IASTInitializerClause initializerClause, IASTExpression bitfieldExpression,
IASTAbstractDeclaration abstractDeclaration, boolean isMutable, boolean isExtern, boolean isRegister, boolean isStatic, int startingOffset, int nameOffset, int nameEndOffset, IASTExpression constructorExpression ) throws ASTSemanticException, Exception;

View file

@ -33,6 +33,9 @@ public interface IASTFunction extends IASTCodeScope, IASTOffsetableNamedElement,
public void setHasFunctionBody(boolean b);
public boolean hasFunctionBody();
public void setHasFunctionTryBlock( boolean b );
public boolean hasFunctionTryBlock();
public boolean previouslyDeclared();
}

View file

@ -482,7 +482,7 @@ public class DeclarationWrapper implements IDeclaratorOwner
virtual,
explicit,
declarator.isPureVirtual(), ((IASTClassSpecifier)scope).getCurrentVisibilityMode(),
declarator.getConstructorMemberInitializers(), declarator.hasFunctionBody());
declarator.getConstructorMemberInitializers(), declarator.hasFunctionBody(), declarator.hasFunctionTryBlock());
}
catch (ASTSemanticException e)
{
@ -503,7 +503,7 @@ public class DeclarationWrapper implements IDeclaratorOwner
{
return astFactory.createFunction(
scope,
nested ? declarator.getOwnedDeclarator().getNamedDuple() : declarator.getNamedDuple(),
nested ? declarator.getOwnedDeclarator().getNameDuple() : declarator.getNameDuple(),
createParameterList(declarator.getParameters()),
astFactory.createAbstractDeclaration(
constt,
@ -523,7 +523,7 @@ public class DeclarationWrapper implements IDeclaratorOwner
virtual,
explicit,
declarator.isPureVirtual(),
declarator.getConstructorMemberInitializers(), declarator.hasFunctionBody() );
declarator.getConstructorMemberInitializers(), declarator.hasFunctionBody(), declarator.hasFunctionTryBlock() );
}
catch (ASTSemanticException e)
{

View file

@ -29,7 +29,8 @@ import org.eclipse.cdt.core.parser.ast.IASTInitializerClause;
*/
public class Declarator implements IParameterCollection, IDeclaratorOwner, IDeclarator
{
private ITokenDuple pointerOperatorNameDuple;
private boolean hasFunctionTryBlock;
private ITokenDuple pointerOperatorNameDuple;
private ITokenDuple namedDuple;
private boolean isFunction;
private boolean hasFunctionBody;
@ -371,7 +372,7 @@ public class Declarator implements IParameterCollection, IDeclaratorOwner, IDecl
/**
* @return
*/
public ITokenDuple getNamedDuple()
public ITokenDuple getNameDuple()
{
return namedDuple;
}
@ -408,4 +409,28 @@ public class Declarator implements IParameterCollection, IDeclaratorOwner, IDecl
hasFunctionBody = b;
}
/**
* @param b
*/
public void setFunctionTryBlock(boolean b)
{
hasFunctionTryBlock = true;
}
/**
* @return
*/
public boolean hasFunctionTryBlock()
{
return hasFunctionTryBlock;
}
/**
* @param b
*/
public void setHasFunctionTryBlock(boolean b)
{
hasFunctionTryBlock = b;
}
}

View file

@ -773,7 +773,6 @@ public class Parser implements IParser
{
simpleDeclaration(
SimpleDeclarationStrategy.TRY_CONSTRUCTOR,
false,
scope,
ownerTemplate);
// try it first with the original strategy
@ -787,9 +786,8 @@ public class Parser implements IParser
{
simpleDeclaration(
SimpleDeclarationStrategy.TRY_FUNCTION,
false,
scope,
ownerTemplate);
scope,
ownerTemplate);
}
catch( Backtrack bt2 )
{
@ -799,7 +797,6 @@ public class Parser implements IParser
{
simpleDeclaration(
SimpleDeclarationStrategy.TRY_VARIABLE,
false,
scope,
ownerTemplate);
}
@ -889,11 +886,11 @@ public class Parser implements IParser
throw backtrack;
ITokenDuple duple = name();
consume( IToken.tSEMI );
try
{
astFactory.createNamespaceAlias(
scope, identifier.toString(), duple, first.getOffset(),
scope, identifier.getImage(), duple, first.getOffset(),
identifier.getOffset(), identifier.getEndOffset(), duple.getLastToken().getEndOffset() );
}
catch (Exception e1)
@ -926,7 +923,6 @@ public class Parser implements IParser
*/
protected void simpleDeclaration(
SimpleDeclarationStrategy strategy,
boolean forKR,
IASTScope scope,
IASTTemplate ownerTemplate)
throws Backtrack
@ -935,7 +931,7 @@ public class Parser implements IParser
DeclarationWrapper sdw =
new DeclarationWrapper(scope, firstToken.getOffset(), ownerTemplate);
declSpecifierSeq(false, strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR, sdw, forKR );
declSpecifierSeq(false, strategy == SimpleDeclarationStrategy.TRY_CONSTRUCTOR, sdw );
if (sdw.getTypeSpecifier() == null && sdw.getSimpleType() != IASTSimpleTypeSpecifier.Type.UNSPECIFIED )
try
{
@ -957,40 +953,55 @@ public class Parser implements IParser
Declarator declarator = null;
if (LT(1) != IToken.tSEMI)
{
declarator = initDeclarator(sdw, forKR, strategy);
declarator = initDeclarator(sdw, strategy);
while (LT(1) == IToken.tCOMMA)
{
consume();
initDeclarator(sdw, forKR, strategy);
initDeclarator(sdw, strategy);
}
}
boolean hasFunctionBody = false;
boolean hasFunctionTryBlock = false;
boolean consumedSemi = false;
switch (LT(1))
{
case IToken.tSEMI :
consume(IToken.tSEMI);
consumedSemi = true;
break;
case IToken.t_try :
consume( IToken.t_try );
if( LT(1) == IToken.tCOLON )
ctorInitializer( declarator );
hasFunctionTryBlock = true;
declarator.setFunctionTryBlock( true );
break;
case IToken.tCOLON :
if (forKR)
throw backtrack;
ctorInitializer(declarator);
// Falling through on purpose
case IToken.tLBRACE :
if (forKR)
throw backtrack;
if( firstToken == LA(1) )
throw backtrack;
declarator.setHasFunctionBody(true);
hasFunctionBody = true;
break;
default :
throw backtrack;
case IToken.tLBRACE:
break;
default:
throw backtrack;
}
if( forKR ) return;
if( ! consumedSemi )
{
if( LT(1) == IToken.tLBRACE )
{
if( firstToken == LA(1) )
throw backtrack;
declarator.setHasFunctionBody(true);
hasFunctionBody = true;
}
if( hasFunctionTryBlock && ! hasFunctionBody )
throw backtrack;
}
List l = null;
try
{
@ -1031,6 +1042,10 @@ public class Parser implements IParser
lastToken.getEndOffset());
declaration.exitScope( requestor );
if( hasFunctionTryBlock )
catchHandlerSequence( scope );
}
}
else
@ -1057,28 +1072,32 @@ public class Parser implements IParser
{
if ( mode == ParserMode.QUICK_PARSE || isInlineFunction )
{
// speed up the parser by skiping the body
// simply look for matching brace and return
consume(IToken.tLBRACE);
int depth = 1;
while (depth > 0)
{
switch (consume().getType())
{
case IToken.tRBRACE :
--depth;
break;
case IToken.tLBRACE :
++depth;
break;
}
}
skipOverCompoundStatement();
}
else
{
functionBody(scope);
}
}
protected void skipOverCompoundStatement() throws Backtrack, EndOfFile
{
// speed up the parser by skiping the body
// simply look for matching brace and return
consume(IToken.tLBRACE);
int depth = 1;
while (depth > 0)
{
switch (consume().getType())
{
case IToken.tRBRACE :
--depth;
break;
case IToken.tLBRACE :
++depth;
break;
}
}
}
/**
* This method parses a constructor chain
* ctorinitializer: : meminitializerlist
@ -1090,7 +1109,7 @@ public class Parser implements IParser
* @param declarator IParserCallback object that represents the declarator (constructor) that owns this initializer
* @throws Backtrack request a backtrack
*/
protected void ctorInitializer(Declarator d)
protected void ctorInitializer(Declarator d )
throws Backtrack
{
consume(IToken.tCOLON);
@ -1149,7 +1168,7 @@ public class Parser implements IParser
DeclarationWrapper sdw =
new DeclarationWrapper(scope, current.getOffset(), null);
declSpecifierSeq(true, false, sdw, false);
declSpecifierSeq(true, false, sdw);
if (sdw.getTypeSpecifier() == null
&& sdw.getSimpleType()
!= IASTSimpleTypeSpecifier.Type.UNSPECIFIED)
@ -1175,7 +1194,7 @@ public class Parser implements IParser
}
if (LT(1) != IToken.tSEMI)
initDeclarator(sdw, false, SimpleDeclarationStrategy.TRY_FUNCTION );
initDeclarator(sdw, SimpleDeclarationStrategy.TRY_FUNCTION );
if( lastToken != null )
sdw.setEndingOffset( lastToken.getEndOffset() );
@ -1250,70 +1269,57 @@ public class Parser implements IParser
* @return whether or not this looks like a constructor (true or false)
* @throws EndOfFile we could encounter EOF while looking ahead
*/
private boolean lookAheadForConstructorOrConversion(Flags flags)
private boolean lookAheadForConstructorOrConversion(Flags flags, DeclarationWrapper sdw )
throws EndOfFile
{
if (flags.isForParameterDeclaration())
return false;
if (LT(2) == IToken.tLPAREN && flags.isForConstructor())
return true;
boolean continueProcessing = true;
// Portions of qualified name
// ...::secondLastID<template-args>::lastID ...
int secondLastIDTokenPos = -1;
int lastIDTokenPos = 1;
int tokenPos = 2;
do
IToken mark = mark();
Declarator d = new Declarator( sdw );
try
{
if (LT(tokenPos) == IToken.tLT)
{
// a case for template instantiation, like CFoobar<A,B>::CFoobar
tokenPos++;
// until we get all the names sorted out
int depth = 1;
while (depth > 0)
{
switch (LT(tokenPos++))
{
case IToken.tGT :
--depth;
break;
case IToken.tLT :
++depth;
break;
}
}
}
if (LT(tokenPos) == IToken.tCOLONCOLON)
{
tokenPos++;
switch (LT(tokenPos))
{
case IToken.tCOMPL : // for destructors
case IToken.t_operator : // for conversion operators
return true;
case IToken.tIDENTIFIER :
secondLastIDTokenPos = lastIDTokenPos;
lastIDTokenPos = tokenPos;
tokenPos++;
break;
default :
// Something unexpected after ::
return false;
}
}
else
{
continueProcessing = false;
}
consumeTemplatedOperatorName( d );
}
while (continueProcessing);
// for constructors
if (secondLastIDTokenPos < 0)
catch (Backtrack e)
{
backup( mark );
return false;
String secondLastID = LA(secondLastIDTokenPos).getImage();
String lastID = LA(lastIDTokenPos).getImage();
return secondLastID.equals(lastID);
}
ITokenDuple duple = d.getNameDuple();
if( duple == null )
{
backup( mark );
return false;
}
int lastColon = duple.findLastTokenType(IToken.tCOLON);
if( lastColon == -1 )
{
int lt1 = LT(1);
backup( mark );
return flags.isForConstructor() && (lt1 == IToken.tLPAREN);
}
IToken className = null;
int index = lastColon - 1;
if( duple.getToken( index ).getType() == IToken.tGT )
{
int depth = -1;
while( depth == -1 )
{
if( duple.getToken( --index ).getType() == IToken.tLT )
++depth;
}
className = duple.getToken( index );
}
boolean result = className.getImage().equals( duple.getLastToken());
backup( mark );
return result;
}
/**
* @param flags input flags that are used to make our decision
@ -1359,8 +1365,7 @@ public class Parser implements IParser
protected void declSpecifierSeq(
boolean parm,
boolean tryConstructor,
DeclarationWrapper sdw,
boolean forKR )
DeclarationWrapper sdw )
throws Backtrack
{
Flags flags = new Flags(parm, tryConstructor);
@ -1536,7 +1541,7 @@ public class Parser implements IParser
new TokenDuple(typeNameBegin, typeNameEnd));
return;
}
if (lookAheadForConstructorOrConversion(flags))
if (lookAheadForConstructorOrConversion(flags, sdw))
{
if (typeNameBegin != null)
sdw.setTypeName(
@ -1559,7 +1564,7 @@ public class Parser implements IParser
case IToken.t_class :
case IToken.t_struct :
case IToken.t_union :
if (!parm && !forKR )
if (!parm )
{
try
{
@ -1581,7 +1586,7 @@ public class Parser implements IParser
break;
}
case IToken.t_enum :
if (!parm || !forKR )
if (!parm )
{
try
{
@ -1675,7 +1680,7 @@ public class Parser implements IParser
* @return Last consumed token, or <code>previousLast</code> if nothing was consumed
* @throws Backtrack request a backtrack
*/
private IToken consumeTemplateParameters(IToken previousLast)
protected IToken consumeTemplateParameters(IToken previousLast)
throws Backtrack
{
IToken last = previousLast;
@ -1874,10 +1879,10 @@ public class Parser implements IParser
* @throws Backtrack request a backtrack
*/
protected Declarator initDeclarator(
DeclarationWrapper sdw, boolean forKR, SimpleDeclarationStrategy strategy )
DeclarationWrapper sdw, SimpleDeclarationStrategy strategy )
throws Backtrack
{
Declarator d = declarator(sdw, sdw.getScope(), forKR, strategy );
Declarator d = declarator(sdw, sdw.getScope(), strategy );
// handle = initializerClause
if (LT(1) == IToken.tASSIGN)
{
@ -1998,7 +2003,7 @@ public class Parser implements IParser
* @throws Backtrack request a backtrack
*/
protected Declarator declarator(
IDeclaratorOwner owner, IASTScope scope, boolean forKR, SimpleDeclarationStrategy strategy )
IDeclaratorOwner owner, IASTScope scope, SimpleDeclarationStrategy strategy )
throws Backtrack
{
Declarator d = null;
@ -2012,56 +2017,17 @@ public class Parser implements IParser
if (LT(1) == IToken.tLPAREN)
{
consume();
declarator(d, scope, forKR, strategy );
declarator(d, scope, strategy );
consume(IToken.tRPAREN);
}
else if (LT(1) == IToken.t_operator)
operatorId(d, null);
else
{
try
{
ITokenDuple duple = name();
d.setName(duple);
}
catch (Backtrack bt)
{
IToken start = null;
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
start = consume();
IToken end = null;
if (start.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
while (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
end = consume();
if (end.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
}
if (LT(1) == IToken.t_operator)
operatorId(d, start);
else
{
backup(mark);
throw backtrack;
}
}
}
}
consumeTemplatedOperatorName(d);
for (;;)
{
switch (LT(1))
{
case IToken.tLPAREN :
if( forKR )
throw backtrack;
// temporary fix for initializer/function declaration ambiguity
if (!LA(2).looksLikeExpression() && strategy != SimpleDeclarationStrategy.TRY_VARIABLE )
@ -2120,10 +2086,9 @@ public class Parser implements IParser
}
}
if (LT(1) == IToken.tCOLON)
{
if (LT(1) == IToken.tCOLON || LT(1) == IToken.t_try )
break overallLoop;
}
IToken beforeCVModifier = mark();
IToken cvModifier = null;
IToken afterCVModifier = beforeCVModifier;
@ -2222,36 +2187,6 @@ public class Parser implements IParser
// In this case (method) we can't expect K&R parameter declarations,
// but we'll check anyway, for errorhandling
}
else
{
// let's try this modifier as part of K&R parameter declaration
if (cvModifier != null)
backup(beforeCVModifier);
}
if (LT(1) != IToken.tSEMI)
{
// try K&R-style parameter declarations
try
{
do
{
simpleDeclaration(
null,
true,
sdw.getScope(),
sdw.getOwnerTemplate());
}
while (LT(1) != IToken.tLBRACE);
}
catch (Backtrack bt)
{
// Something is wrong,
// this is not a proper K&R declaration clause
backup(afterCVModifier);
}
}
}
break;
case IToken.tLBRACKET :
@ -2276,7 +2211,50 @@ public class Parser implements IParser
((Declarator)d.getOwner()).setOwnedDeclarator(d);
return d;
}
protected void consumeTemplatedOperatorName(Declarator d)
throws EndOfFile, Backtrack
{
if (LT(1) == IToken.t_operator)
operatorId(d, null);
else
{
try
{
ITokenDuple duple = name();
d.setName(duple);
}
catch (Backtrack bt)
{
Declarator d1 = d;
Declarator d11 = d1;
IToken start = null;
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
start = consume();
IToken end = null;
if (start.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
while (LT(1) == IToken.tCOLONCOLON
|| LT(1) == IToken.tIDENTIFIER)
{
end = consume();
if (end.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
}
if (LT(1) == IToken.t_operator)
operatorId(d11, start);
else
{
backup(mark);
throw backtrack;
}
}
}
}
}
protected void consumeArrayModifiers( IDeclarator d, IASTScope scope )
throws EndOfFile, Backtrack
{
@ -2886,14 +2864,7 @@ public class Parser implements IParser
case IToken.t_try :
consume();
compoundStatement(scope,true);
while (LT(1) == IToken.t_catch)
{
consume();
consume(IToken.tLPAREN);
declaration(scope, null); // was exceptionDeclaration
consume(IToken.tRPAREN);
compoundStatement(scope, true);
}
catchHandlerSequence(scope);
return;
case IToken.tSEMI :
consume();
@ -2927,6 +2898,27 @@ public class Parser implements IParser
declaration(scope, null);
}
}
protected void catchHandlerSequence(IASTScope scope)
throws EndOfFile, Backtrack
{
if( LT(1) != IToken.t_catch )
throw backtrack; // error, need at least one of these
while (LT(1) == IToken.t_catch)
{
consume(IToken.t_catch);
consume(IToken.tLPAREN);
if( LT(1) == IToken.tELIPSE )
consume( IToken.tELIPSE );
else
declaration(scope, null); // was exceptionDeclaration
consume(IToken.tRPAREN);
if( mode == ParserMode.COMPLETE_PARSE )
compoundStatement(scope, true);
else
skipOverCompoundStatement();
}
}
protected void singleStatementScope(IASTScope scope) throws Backtrack
{
IASTCodeScope newScope;
@ -3923,7 +3915,11 @@ public class Parser implements IParser
throw backtrack;
TypeId id = new TypeId();
IToken last = lastToken;
IToken last = lastToken;
lastToken = consumeTemplateParameters( last );
if( lastToken == null ) lastToken = last;
consumePointerOperators( id );
if( lastToken == null ) lastToken = last;
@ -4869,8 +4865,46 @@ public class Parser implements IParser
}
case IToken.tIDENTIFIER :
case IToken.tCOLONCOLON :
ITokenDuple duple = name();
//TODO should be an ID Expression really
case IToken.t_operator :
ITokenDuple duple = null;
try
{
duple = name();
}
catch( Backtrack bt )
{
Declarator d = new Declarator( new DeclarationWrapper(scope, 0, null) );
IToken mark = mark();
if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER)
{
IToken start = consume();
IToken end = null;
if (start.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER)
{
end = consume();
if (end.getType() == IToken.tIDENTIFIER)
end = consumeTemplateParameters(end);
}
if (LT(1) == IToken.t_operator)
operatorId(d, start);
else
{
backup(mark);
throw backtrack;
}
}
else if( LT(1) == IToken.t_operator )
operatorId( d, null);
duple = d.getNameDuple();
}
try
{
return astFactory.createExpression(

View file

@ -443,32 +443,7 @@ public class Scanner implements IScanner {
// past the end of file
return c;
boolean done;
do {
done = true;
if (contextStack.getCurrentContext().undoStackSize() != 0 ) {
c = contextStack.getCurrentContext().popUndo();
} else {
try {
c = contextStack.getCurrentContext().read();
if (c == NOCHAR) {
if (contextStack.rollbackContext(requestor) == false) {
c = NOCHAR;
break;
} else {
done = false;
}
}
} catch (IOException e) {
if (contextStack.rollbackContext(requestor) == false) {
c = NOCHAR;
} else {
done = false;
}
}
}
} while (!done);
c = accountForUndo(c);
int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
@ -597,6 +572,39 @@ public class Scanner implements IScanner {
return c;
}
protected int accountForUndo(int c)
{
boolean done;
do {
done = true;
if (contextStack.getCurrentContext().undoStackSize() != 0 ) {
c = contextStack.getCurrentContext().popUndo();
} else {
try {
c = contextStack.getCurrentContext().read();
if (c == NOCHAR) {
if (contextStack.rollbackContext(requestor) == false) {
c = NOCHAR;
break;
} else {
done = false;
}
}
} catch (IOException e) {
if (contextStack.rollbackContext(requestor) == false) {
c = NOCHAR;
} else {
done = false;
}
}
}
} while (!done);
return c;
}
private void ungetChar(int c) throws ScannerException{
contextStack.getCurrentContext().pushUndo(c);
contextStack.undoRollback( lastContext, requestor );
@ -700,6 +708,10 @@ public class Scanner implements IScanner {
for( ; ; )
{
if ( ( c =='"' ) && ( previous != '\\' || beforePrevious == '\\') ) break;
if ( ( c == '\n' ) && ( previous != '\\' || beforePrevious == '\\') )
if (throwExceptionOnUnboundedString)
throw new ScannerException( ScannerException.ErrorCode.UNBOUNDED_STRING, getCurrentFile(), getCurrentOffset() );
if( c == NOCHAR) break;
buff.append((char) c);
beforePrevious = previous;
@ -862,7 +874,7 @@ public class Scanner implements IScanner {
} else if (c == 'x') {
if( ! firstCharZero )
throw new ScannerException( ScannerException.ErrorCode.BAD_HEXIDECIMAL_FORMAT, getCurrentFile(), getCurrentOffset() );
buff.append( (char)c );
hex = true;
c = getChar();
}
@ -958,7 +970,7 @@ public class Scanner implements IScanner {
contextStack.updateContext( new StringReader( buff.toString()), PASTING, IScannerContext.MACROEXPANSION, null, requestor );
storageBuffer = null;
c = getChar();
continue;
continue;
}
}
}
@ -1189,21 +1201,7 @@ public class Scanner implements IScanner {
} else {
switch (c) {
case '\'' :
int type = wideLiteral ? IToken.tLCHAR : IToken.tCHAR;
c = getChar( true );
int next = getChar( true );
if( c == '\\' ){
c = next;
next = getChar( true );
if( next == '\'' )
return newToken( type, '\\' + new Character( (char)c ).toString(), contextStack.getCurrentContext() );
else if( throwExceptionOnBadCharacterRead )
throw new ScannerException( ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE, getCurrentFile(), getCurrentOffset() );
} else if( next == '\'' )
return newToken( type, new Character( (char)c ).toString(), contextStack.getCurrentContext() );
else
if( throwExceptionOnBadCharacterRead )
throw new ScannerException( ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE, getCurrentFile(), getCurrentOffset() );
return processCharacterLiteral( c, wideLiteral );
case ':' :
c = getChar();
switch (c) {
@ -1515,9 +1513,8 @@ public class Scanner implements IScanner {
contextStack.getCurrentContext());
}
default :
// Bad character
if( throwExceptionOnBadCharacterRead )
throw new ScannerException( ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE, getCurrentFile(), getCurrentOffset() );
throw new ScannerException( ScannerException.ErrorCode.BAD_CHARACTER, new Character( (char)c ).toString(), getCurrentFile(), getCurrentOffset() );
else
{
c = ' ';
@ -1541,6 +1538,72 @@ public class Scanner implements IScanner {
/**
* @param c
* @param wideLiteral
*/
protected IToken processCharacterLiteral(int c, boolean wideLiteral)
throws ScannerException
{
int type = wideLiteral ? IToken.tLCHAR : IToken.tCHAR;
StringBuffer buffer = new StringBuffer();
int prev = c;
int prevPrev = c;
c = getChar(true);
for( ; ; )
{
// error conditions
if( ( c == '\n' ) ||
( ( c == '\\' || c =='\'' )&& prev == '\\' ) ||
( c == NOCHAR ) )
if( throwExceptionOnBadCharacterRead )
throw new ScannerException( ScannerException.ErrorCode.BAD_CHARACTER, new Character( (char)c ).toString(), getCurrentFile(), getCurrentOffset() );
else
c = ' ';
// exit condition
if ( ( c =='\'' ) && ( prev != '\\' || prevPrev == '\\' ) ) break;
// System.out.println( "Adding character " + (char)c + " to buffer");
buffer.append( (char)c);
prevPrev = prev;
prev = c;
c = getChar(true);
}
return newToken( type, buffer.toString(), contextStack.getCurrentContext());
// int next = getChar(true);
//
// if (c == '\\')
// {
// c = next;
// next = getChar(true);
// if (next == '\'')
// return newToken( type, '\\' + new Character((char)c).toString(), contextStack.getCurrentContext());
// else
// if( throwExceptionOnBadCharacterRead )
// throw new ScannerException( ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE,
// getCurrentFile(),
// getCurrentOffset());
// }
// else if (next == '\'')
// return newToken(
// type,
// new Character((char)c).toString(),
// contextStack.getCurrentContext());
//
// throw new ScannerException(
// ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE,
// getCurrentFile(),
// getCurrentOffset());
}
protected void repackageScannerExceptionAndThrow(ScannerException se)
throws ScannerException
{
@ -1610,21 +1673,8 @@ public class Scanner implements IScanner {
} else {
switch (c) {
case '\'' :
if (tokenImage.length() > 0) throw endOfMacroToken;
c = getChar( true );
int next = getChar( true );
if( c == '\\' ){
c = next;
next = getChar( true );
if( next == '\'' )
return newToken( IToken.tCHAR, '\\' + new Character( (char)c ).toString(), contextStack.getCurrentContext() );
else if( throwExceptionOnBadCharacterRead )
throw new ScannerException( ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE, getCurrentFile(), getCurrentOffset());
} else if( next == '\'' )
return newToken( IToken.tCHAR, new Character( (char)c ).toString(), contextStack.getCurrentContext() );
else
if( throwExceptionOnBadCharacterRead )
throw new ScannerException( ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE, getCurrentFile(), getCurrentOffset());
if (tokenImage.length() > 0) throw endOfMacroToken;
return processCharacterLiteral( c, false );
case ',' :
if (tokenImage.length() > 0) throw endOfMacroToken;
return newToken(IToken.tCOMMA, ",", contextStack.getCurrentContext());
@ -2224,6 +2274,7 @@ public class Scanner implements IScanner {
protected Vector getMacroParameters (String params, boolean forStringizing) throws ScannerException {
Scanner tokenizer = new Scanner(new StringReader(params), TEXT, new ScannerInfo( definitions, originalConfig.getIncludePaths() ), problemReporter, translationResult, new NullSourceElementRequestor(), mode, language);
tokenizer.setThrowExceptionOnBadCharacterRead(false);
Vector parameterValues = new Vector();
Token t = null;
String str = new String();

View file

@ -53,7 +53,7 @@ public class ASTFunction extends ASTScope implements IASTFunction
* @param ownerTemplate
* @param references
*/
public ASTFunction(IParameterizedSymbol symbol, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, int startOffset, int nameOffset, IASTTemplate ownerTemplate, List references, boolean previouslyDeclared )
public ASTFunction(IParameterizedSymbol symbol, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, int startOffset, int nameOffset, IASTTemplate ownerTemplate, List references, boolean previouslyDeclared, boolean hasFunctionTryBlock )
{
super( symbol );
this.parameters = parameters;
@ -67,6 +67,7 @@ public class ASTFunction extends ASTScope implements IASTFunction
this.references = new ASTReferenceStore( references );
qualifiedName = new ASTQualifiedNamedElement( getOwnerScope(), symbol.getName() );
this.previouslyDeclared =previouslyDeclared;
this.hasFunctionTryBlock = hasFunctionTryBlock;
}
@ -299,4 +300,22 @@ public class ASTFunction extends ASTScope implements IASTFunction
{
offsets.setNameEndOffset(o);
}
private boolean hasFunctionTryBlock = false;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFunction#setHasFunctionTryBlock(boolean)
*/
public void setHasFunctionTryBlock(boolean b)
{
hasFunctionTryBlock = b;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFunction#hasFunctionTryBlock()
*/
public boolean hasFunctionTryBlock()
{
return hasFunctionTryBlock;
}
}

View file

@ -46,7 +46,7 @@ public class ASTMethod extends ASTFunction implements IASTMethod
* @param references
*/
public ASTMethod(IParameterizedSymbol symbol, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, int startOffset, int nameOffset, IASTTemplate ownerTemplate, List references, boolean previouslyDeclared,
boolean isConstructor, boolean isDestructor, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain )
boolean isConstructor, boolean isDestructor, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean hasFunctionTryBlock )
{
super(
symbol,
@ -57,7 +57,7 @@ public class ASTMethod extends ASTFunction implements IASTMethod
startOffset,
nameOffset,
ownerTemplate,
references, previouslyDeclared );
references, previouslyDeclared, hasFunctionTryBlock );
this.visibility = visibility;
this.isConstructor = isConstructor;
this.isDestructor = isDestructor;

View file

@ -1435,7 +1435,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
boolean isExplicit,
boolean isPureVirtual,
List constructorChain,
boolean isFunctionDefinition ) throws ASTSemanticException
boolean isFunctionDefinition, boolean hasFunctionTryBlock ) throws ASTSemanticException
{
List references = new ArrayList();
IContainerSymbol ownerScope = scopeToSymbol( scope );
@ -1481,7 +1481,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
ASTAccessVisibility.PRIVATE,
constructorChain,
references,
isFunctionDefinition);
isFunctionDefinition, hasFunctionTryBlock );
}
}
@ -1524,7 +1524,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
{
throw new ASTSemanticException();
}
ASTFunction function = new ASTFunction( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared );
ASTFunction function = new ASTFunction( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, hasFunctionTryBlock );
try
{
attachSymbolExtension(symbol, function);
@ -1732,12 +1732,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual,
ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition ) throws ASTSemanticException
ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock ) throws ASTSemanticException
{
return createMethod(scope, name, parameters, returnType, exception,
isInline, isFriend, isStatic, startOffset, nameOffset, nameEndOffset,
ownerTemplate, isConst, isVolatile, isVirtual, isExplicit, isPureVirtual,
visibility, constructorChain, null, isFunctionDefinition );
visibility, constructorChain, null, isFunctionDefinition, hasFunctionTryBlock );
}
public IASTMethod createMethod(
@ -1760,7 +1760,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
boolean isPureVirtual,
ASTAccessVisibility visibility,
List constructorChain,
List references, boolean isFunctionDefinition ) throws ASTSemanticException
List references, boolean isFunctionDefinition, boolean hasFunctionTryBlock ) throws ASTSemanticException
{
boolean isConstructor = false;
boolean isDestructor = false;
@ -1836,7 +1836,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain );
ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock );
try
{
attachSymbolExtension( symbol, method );

View file

@ -102,7 +102,22 @@ public class ASTExpression implements IASTExpression {
public int evaluateExpression() throws ExpressionEvaluationException {
// primary expressions
if( getExpressionKind() == IASTExpression.Kind.PRIMARY_INTEGER_LITERAL )
return Integer.parseInt( getLiteralString() );
{
try
{
if( getLiteralString().startsWith( "0x") || getLiteralString().startsWith( "0x") )
{
return Integer.parseInt( getLiteralString().substring(2), 16 );
}
if( getLiteralString().startsWith( "0") && getLiteralString().length() > 1 )
return Integer.parseInt( getLiteralString().substring(1), 8 );
return Integer.parseInt( getLiteralString() );
}
catch( NumberFormatException nfe )
{
throw new ExpressionEvaluationException();
}
}
if( getExpressionKind() == IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION )
return getLHSExpression().evaluateExpression();
// unary not

View file

@ -35,7 +35,7 @@ public class ASTFunction extends ASTDeclaration implements IASTFunction
* @param scope
*/
public ASTFunction(IASTScope scope, String name, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception,
boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, IASTTemplate ownerTemplate )
boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, IASTTemplate ownerTemplate, boolean hasFunctionTryBlock )
{
super(ownerTemplate != null ? null : scope );
this.name = name;
@ -52,6 +52,7 @@ public class ASTFunction extends ASTDeclaration implements IASTFunction
offsets.setNameOffset( nameOffset );
qualifiedName = new ASTQualifiedNamedElement( scope, name );
setNameEndOffset(nameEndOffset);
this.hasFunctionTryBlock = hasFunctionTryBlock;
}
private boolean previouslyDeclared;
@ -261,4 +262,24 @@ public class ASTFunction extends ASTDeclaration implements IASTFunction
public void setNameEndOffset(int o)
{
offsets.setNameEndOffset(o);
}}
}
private boolean hasFunctionTryBlock = false;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFunction#setHasFunctionTryBlock(boolean)
*/
public void setHasFunctionTryBlock(boolean b)
{
hasFunctionTryBlock = b;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFunction#hasFunctionTryBlock()
*/
public boolean hasFunctionTryBlock()
{
return hasFunctionTryBlock;
}
}

View file

@ -70,7 +70,8 @@ public class ASTMethod extends ASTFunction implements IASTMethod
boolean isDestructor,
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChainElements )
boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChainElements,
boolean hasFunctionTryBlock )
{
super(
scope,
@ -84,7 +85,7 @@ public class ASTMethod extends ASTFunction implements IASTMethod
isStatic,
startOffset,
nameOffset,
ownerTemplate);
ownerTemplate, hasFunctionTryBlock);
this.isVirtual = isVirtual;
this.isPureVirtual = isPureVirtual;
this.isConstructor = isConstructor;

View file

@ -184,17 +184,17 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createFunction(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, java.util.List, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration)
*/
public IASTFunction createFunction(IASTScope scope, ITokenDuple name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, List constructorChain, boolean isFunctionDefinition )
public IASTFunction createFunction(IASTScope scope, ITokenDuple name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock )
{
return new ASTFunction(scope, name.toString(), nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate );
return new ASTFunction(scope, name.toString(), nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, hasFunctionTryBlock );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createMethod(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, java.util.List, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration, boolean, boolean, boolean, boolean, boolean, boolean, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility)
*/
public IASTMethod createMethod(IASTScope scope, String name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition )
public IASTMethod createMethod(IASTScope scope, String name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock )
{
return new ASTMethod(scope, name, nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, isConst, isVolatile, false, false, isVirtual, isExplicit, isPureVirtual, visibility, constructorChain);
return new ASTMethod(scope, name, nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, isConst, isVolatile, false, false, isVirtual, isExplicit, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock);
}
/* (non-Javadoc)

View file

@ -484,7 +484,8 @@ public abstract class CSearchPattern implements ICSearchConstants, ICSearchPatte
try{
token = scanner.nextToken();
} catch ( ScannerException e ){
if( e.getErrorCode() == ScannerException.ErrorCode.INVALID_ESCAPE_CHARACTER_SEQUENCE ){
if( e.getErrorCode() == ScannerException.ErrorCode.BAD_CHARACTER ){
//TODO : This may not //, it could be another bad character
if( !encounteredWild && !lastTokenWasOperator ) name += " ";
name += "\\";
encounteredWild = true;