1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00
Fixed bug36693 - Problem parsing Loki's Reference SmallObj.cpp Impl
	Fixed bug36696 - Problem parsing Loki's Reference SmartPtr.h Impl
	Improved our error handling robustness so that we don't mistake function bodies for CElements. 
	Fixed bug36713 - Parser fails on definitions of pointers to functions 
	Fixed Dave's performance test parse failure. 
	Fixed bug36811 - The using directive causes parser to fail
	Fixed bug36794 - ClassCastException for A template with no parameters 

TESTS
	Moved fixed tests from FailedTests to DOMTests. 
	Added LokiFailures.java to failed tests directory.

JohnC
This commit is contained in:
John Camelon 2003-04-24 18:36:22 +00:00
parent d64dd56f51
commit ce2d966a88
12 changed files with 392 additions and 265 deletions

View file

@ -34,6 +34,7 @@ public class DeclSpecifier {
public static final int isLong = 0x80000;
private int declSpecifierSeq = 0;
private boolean isTypename = false;
public int getDeclSpecifierSeq() {
return declSpecifierSeq;
}
@ -168,6 +169,9 @@ public class DeclSpecifier {
public void setType(Token token) {
switch (token.getType()) {
case Token.t_typename:
setTypename(true);
break;
case Token.t_auto :
setAuto(true);
break;
@ -319,6 +323,8 @@ public class DeclSpecifier {
type.append("void");
break;
case t_type :
if (isTypename() )
type.append("typename ");
if (getName() != null)
type.append(getName().toString());
else {
@ -336,4 +342,18 @@ public class DeclSpecifier {
return type.toString();
}
/**
* @return
*/
public boolean isTypename() {
return isTypename;
}
/**
* @param b
*/
public void setTypename(boolean b) {
isTypename = b;
}
}

View file

@ -2,7 +2,7 @@ package org.eclipse.cdt.internal.core.dom;
/**
*/
public class Declaration {
public class Declaration implements IOffsetable {
public Declaration( IScope scope )
{
@ -18,4 +18,72 @@ public class Declaration {
return ownerScope;
}
private int startingOffset, endingOffset;
private int startingLine, endingLine;
private int totalLength;
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getStartingOffset()
*/
public int getStartingOffset()
{
return startingOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTotalLength()
*/
public int getTotalLength()
{
return totalLength;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setStartingOffset(int)
*/
public void setStartingOffset(int i)
{
startingOffset = i;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTotalLength(int)
*/
public void setTotalLength(int i)
{
totalLength = i;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int)
*/
public void setTopLine(int lineNumber)
{
startingLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int)
*/
public void setBottomLine(int lineNumber)
{
endingLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine()
*/
public int getTopLine()
{
return startingLine;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine()
*/
public int getBottomLine()
{
return endingLine;
}
}

View file

@ -22,11 +22,10 @@ import org.eclipse.cdt.internal.core.parser.Token;
* @author jcamelon
*
*/
public class NamespaceDefinition extends Declaration implements IScope, IOffsetable {
public class NamespaceDefinition extends Declaration implements IScope {
private List declarations = new LinkedList();
private Name name = null;
private int startingOffset = 0, totalLength = 0;
private Token startToken = null;
public NamespaceDefinition( IScope owner )
@ -65,34 +64,6 @@ public class NamespaceDefinition extends Declaration implements IScope, IOffseta
this.name = name;
}
/**
* @return
*/
public int getStartingOffset() {
return startingOffset;
}
/**
* @return
*/
public int getTotalLength() {
return totalLength;
}
/**
* @param i
*/
public void setStartingOffset(int i) {
startingOffset = i;
}
/**
* @param i
*/
public void setTotalLength(int i) {
totalLength = i;
}
/**
* Returns the startToken.
* @return Token
@ -109,32 +80,5 @@ public class NamespaceDefinition extends Declaration implements IScope, IOffseta
this.startToken = startToken;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int)
*/
public void setTopLine(int lineNumber) {
topLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int)
*/
public void setBottomLine(int lineNumber) {
bottomLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine()
*/
public int getTopLine() {
return topLine;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine()
*/
public int getBottomLine() {
return bottomLine;
}
private int topLine = 0, bottomLine = 0;
}

View file

@ -5,9 +5,8 @@ import java.util.LinkedList;
import java.util.List;
public class SimpleDeclaration extends Declaration implements DeclSpecifier.IContainer, IOffsetable, TypeSpecifier.IOwner {
public class SimpleDeclaration extends Declaration implements DeclSpecifier.IContainer, TypeSpecifier.IOwner {
private int startingOffset = 0, totalLength = 0;
private AccessSpecifier accessSpecifier = null;
private DeclSpecifier declSpec = null;
private boolean isFunctionDefinition = false;
@ -85,62 +84,4 @@ public class SimpleDeclaration extends Declaration implements DeclSpecifier.ICon
public void setFunctionDefinition(boolean b) {
isFunctionDefinition = b;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsettable#getStartingOffset()
*/
public int getStartingOffset() {
return startingOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsettable#getTotalLength()
*/
public int getTotalLength() {
return totalLength;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsettable#setStartingOffset(int)
*/
public void setStartingOffset(int i) {
startingOffset = i;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsettable#setTotalLength(int)
*/
public void setTotalLength(int i) {
totalLength = i;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int)
*/
public void setTopLine(int lineNumber) {
topLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int)
*/
public void setBottomLine(int lineNumber) {
bottomLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine()
*/
public int getTopLine() {
return topLine;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine()
*/
public int getBottomLine() {
return bottomLine;
}
private int topLine = 0, bottomLine = 0;
}

View file

@ -22,7 +22,7 @@ import org.eclipse.cdt.internal.core.parser.Token;
* @author jcamelon
*
*/
public class TemplateDeclaration extends Declaration implements IScope, IAccessable, ITemplateParameterListOwner, IOffsetable {
public class TemplateDeclaration extends Declaration implements IScope, IAccessable, ITemplateParameterListOwner {
private final boolean exported;
private AccessSpecifier visibility = null;
@ -91,6 +91,7 @@ public class TemplateDeclaration extends Declaration implements IScope, IAccessa
*/
public void setFirstToken(Token token) {
firstToken = token;
setStartingOffset( getFirstToken().getOffset() );
}
/**
@ -98,34 +99,7 @@ public class TemplateDeclaration extends Declaration implements IScope, IAccessa
*/
public void setLastToken(Token token) {
lastToken = token;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getStartingOffset()
*/
public int getStartingOffset() {
return getFirstToken().getOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTotalLength()
*/
public int getTotalLength() {
return getLastToken().getOffset() + getLastToken().getLength() - getStartingOffset();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setStartingOffset(int)
*/
public void setStartingOffset(int i) {
throw new Error( "Offset should not be set");
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTotalLength(int)
*/
public void setTotalLength(int i) {
throw new Error( "Offset should not be set");
setTotalLength( getLastToken().getOffset() + getLastToken().getLength() - getStartingOffset() );
}
/**
@ -144,34 +118,6 @@ public class TemplateDeclaration extends Declaration implements IScope, IAccessa
else this.visibility.setAccess(visibility);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int)
*/
public void setTopLine(int lineNumber) {
topLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int)
*/
public void setBottomLine(int lineNumber) {
bottomLine = lineNumber;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine()
*/
public int getTopLine() {
return topLine;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine()
*/
public int getBottomLine() {
return bottomLine;
}
private int topLine = 0, bottomLine = 0;
}

View file

@ -1,3 +1,12 @@
2003-04-24 John Camelon
Fixed bug36693 - Problem parsing Loki's Reference SmallObj.cpp Impl
Fixed bug36696 - Problem parsing Loki's Reference SmartPtr.h Impl
Improved our error handling robustness.
Fixed bug36713 - Parser fails on definitions of pointers to functions
Fixed Dave's performance test parse failure.
Fixed bug36811 - The using directive causes parser to fail
Fixed bug36794 - ClassCastException for A template with no parameters
2003-04-21 John Camelon
Revisited bug36247 Parser confused by symbols #defined elsewhere
Fixed Bug36708 Problem parsing Loki's Reference TypeTraits.h

View file

@ -131,14 +131,26 @@ c, quick);
try{ callback.translationUnitEnd(translationUnit);} catch( Exception e ) {}
}
protected void consumeToNextSemicolon() throws EndOfFile {
protected void consumeToNextSemicolon() throws Backtrack {
failParse();
consume();
// TODO - we should really check for matching braces too
while (LT(1) != Token.tSEMI) {
int depth = 0;
while (LT(1) != Token.tSEMI || depth != 0 ) {
switch( LT(1))
{
case Token.tLBRACE:
++depth;
break;
case Token.tRBRACE:
--depth;
break;
}
consume();
}
consume();
// eat the SEMI as well
consume(Token.tSEMI);
}
/**
@ -156,12 +168,12 @@ c, quick);
*/
protected void usingClause( Object container ) throws Backtrack
{
consume( Token.t_using );
Token firstToken = consume( Token.t_using );
if( LT(1) == Token.t_namespace )
{
Object directive = null;
try{ directive = callback.usingDirectiveBegin( container );} catch( Exception e ) {}
try{ directive = callback.usingDirectiveBegin( container);} catch( Exception e ) {}
// using-directive
consume( Token.t_namespace );
@ -222,13 +234,8 @@ c, quick);
{
try{ callback.usingDeclarationAbort( usingDeclaration );} catch( Exception e ) {}
throw backtrack;
}
}
}
}
/**
@ -482,7 +489,16 @@ c, quick);
return;
}
default:
simpleDeclaration( container );
Token mark = mark();
try
{
simpleDeclaration( container, true );
}
catch( Backtrack bt)
{
backup( mark );
simpleDeclaration( container, false );
}
}
}
@ -556,10 +572,10 @@ c, quick);
* To do:
* - work in ctorInitializer and functionTryBlock
*/
protected void simpleDeclaration( Object container ) throws Backtrack {
protected void simpleDeclaration( Object container, boolean tryConstructor ) throws Backtrack {
Object simpleDecl = null;
try{ simpleDecl = callback.simpleDeclarationBegin( container, LA(1));} catch( Exception e ) {}
declSpecifierSeq(simpleDecl, false);
declSpecifierSeq(simpleDecl, false, tryConstructor);
Object declarator = null;
if (LT(1) != Token.tSEMI)
@ -670,7 +686,7 @@ c, quick);
Token current = LA(1);
Object parameterDecl = null;
try{ parameterDecl = callback.parameterDeclarationBegin( containerObject );} catch( Exception e ) {}
declSpecifierSeq( parameterDecl, true );
declSpecifierSeq( parameterDecl, true, false );
if (LT(1) != Token.tSEMI)
try {
@ -687,6 +703,107 @@ c, quick);
}
private class Flags
{
private boolean encounteredTypename = false;
private boolean encounteredRawType = false;
private final boolean parm;
private final boolean constructor;
public Flags( boolean parm, boolean c)
{
this.parm = parm;
constructor = c;
}
/**
* @return
*/
public boolean haveEncounteredRawType() {
return encounteredRawType;
}
/**
* @return
*/
public boolean haveEncounteredTypename() {
return encounteredTypename;
}
/**
* @param b
*/
public void setEncounteredRawType(boolean b) {
encounteredRawType = b;
}
/**
* @param b
*/
public void setEncounteredTypename(boolean b) {
encounteredTypename = b;
}
/**
* @return
*/
public boolean isForParameterDeclaration() {
return parm;
}
/**
* @return
*/
public boolean isForConstructor() {
return constructor;
}
}
private boolean lookAheadForConstructor( Flags flags ) throws EndOfFile
{
return (
!flags.isForParameterDeclaration()
) &&
(
(
(
LT(2) == Token.tCOLONCOLON &&
(
LA(3).getImage().equals( LA(1).getImage() ) ||
LT(3) == Token.tCOMPL
)
) ||
(
LT(2) == Token.tLPAREN &&
flags.isForConstructor()
)
)
)
;
}
private boolean lookAheadForDeclarator( Flags flags ) throws EndOfFile
{
return
flags.haveEncounteredTypename() &&
(
(
LT(2) != Token.tIDENTIFIER ||
(
LT(3) != Token.tLPAREN &&
LT(3) != Token.tASSIGN
)
) &&
!LA(2).isPointer()
)
;
}
/**
* declSpecifier
* : "auto" | "register" | "static" | "extern" | "mutable"
@ -704,26 +821,23 @@ c, quick);
* - folded elaboratedTypeSpecifier into classSpecifier and enumSpecifier
* - find template names in name
*/
protected void declSpecifierSeq( Object decl, boolean parm ) throws Backtrack {
boolean encounteredTypename = false;
boolean encounteredRawType = false;
boolean modifierEncountered = false;
protected void declSpecifierSeq( Object decl, boolean parm, boolean tryConstructor ) throws Backtrack {
Flags flags = new Flags( parm, tryConstructor );
declSpecifiers:
for (;;) {
switch (LT(1)) {
case Token.t_inline:
case Token.t_auto:
case Token.t_register:
case Token.t_static:
case Token.t_extern:
case Token.t_mutable:
case Token.t_inline:
case Token.t_virtual:
case Token.t_explicit:
case Token.t_typedef:
case Token.t_friend:
case Token.t_const:
case Token.t_volatile:
modifierEncountered = true;
try{ callback.simpleDeclSpecifier(decl, consume());} catch( Exception e ) {}
break;
case Token.t_signed:
@ -737,7 +851,7 @@ c, quick);
case Token.t_float:
case Token.t_double:
case Token.t_void:
encounteredRawType = true;
flags.setEncounteredRawType(true);
try{ callback.simpleDeclSpecifier(decl, consume());} catch( Exception e ) {}
break;
case Token.t_typename:
@ -751,19 +865,19 @@ c, quick);
case Token.tIDENTIFIER:
// TODO - Kludgy way to handle constructors/destructors
// handle nested later:
if ((modifierEncountered && ! encounteredRawType && LT(2) != Token.tLPAREN)|| (parm && !encounteredRawType) || (!encounteredRawType && LT(2) != Token.tCOLONCOLON && LT(2) != Token.tLPAREN))
{
if( ! encounteredTypename || ( LT(2) == Token.tIDENTIFIER &&
( LT(3) == Token.tLPAREN || LT(3) == Token.tASSIGN ) || LT(2) == Token.tSTAR || LT(2) == Token.tAMPER ) )
{
try{ callback.simpleDeclSpecifier(decl,LA(1));} catch( Exception e ) {}
name();
try{ callback.simpleDeclSpecifierName( decl );} catch( Exception e ) {}
encounteredTypename = true;
break;
}
}
return;
if ( flags.haveEncounteredRawType() )
return;
if ( lookAheadForConstructor( flags ) )
return;
if ( lookAheadForDeclarator( flags ) )
return;
try{ callback.simpleDeclSpecifier(decl,LA(1));} catch( Exception e ) {}
name();
try{ callback.simpleDeclSpecifierName( decl );} catch( Exception e ) {}
flags.setEncounteredTypename(true);
break;
case Token.t_class:
case Token.t_struct:
case Token.t_union:
@ -1991,8 +2105,16 @@ c, quick);
case Token.t_short:
case Token.t_unsigned:
case Token.t_long:
case Token.t_const:
end = consume();
break;
case Token.tAMPER:
case Token.tSTAR:
case Token.tIDENTIFIER:
if( end == null )
throw backtrack;
end = consume();
break;
case Token.t_int:
case Token.t_char:
case Token.t_bool:

View file

@ -76,6 +76,11 @@ public class Token {
return false;
}
public boolean isPointer()
{
return (getType() == tAMPER || getType() == tSTAR);
}
public boolean isOperator()
{
switch( getType() )

View file

@ -1,3 +1,7 @@
2003-04-24 John Camelon
Moved fixed tests from FailedTests to DOMTests.
Added LokiFailures.java to failed tests directory.
2003-04-24 John Camelon
Fixed Java 1.3 compliance issue w/AutomatedTest.java
Fixed False failure in HelloWorld.java.

View file

@ -33,8 +33,6 @@ public class DOMFailedTest extends DOMTests {
TestSuite suite = new TestSuite();
suite.addTest(new DOMFailedTest("testBug36691"));
suite.addTest(new DOMFailedTest("testBug36693"));
suite.addTest(new DOMFailedTest("testBug36696"));
suite.addTest(new DOMFailedTest("testBug36699"));
suite.addTest(new DOMFailedTest("testBug36704"));
suite.addTest(new DOMFailedTest("testBug36707"));
@ -66,42 +64,6 @@ public class DOMFailedTest extends DOMTests {
}
}
public void testBug36693() {
boolean testPassed = false;
try {
TranslationUnit tu =
parse("FixedAllocator::Chunk* FixedAllocator::VicinityFind(void* p){}");
testPassed = true;
fail( "We should not reach this point");
} catch (Throwable e) {
if (!(e instanceof ParserException))
fail("Unexpected Error: " + e.getMessage());
if (testPassed)
fail("The expected error did not occur.");
}
}
public void testBug36696() {
boolean testPassed = false;
try {
Writer code = new StringWriter();
code.write(
"template <typename P1> RefCounted(const RefCounted<P1>& rhs)\n");
code.write(
": pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_) {}\n");
TranslationUnit tu = parse(code.toString());
testPassed = true;
fail( "We should not reach this point");
} catch (Throwable e) {
if (!(e instanceof ParserException))
fail("Unexpected Error: " + e.getMessage());
if (testPassed)
fail("The expected error did not occur.");
}
}
public void testBug36699() {
boolean testPassed = false;
try {
@ -173,23 +135,6 @@ public class DOMFailedTest extends DOMTests {
}
}
public void testBug36713(){
boolean testPassed = false;
try{
Writer code = new StringWriter();
code.write("A (const * fPtr) (void *); \n");
code.write("A (const * fPtr2) ( A * ); \n");
code.write("A (const * fPtr3) ( A * ) = function\n");
TranslationUnit tu = parse(code.toString());
testPassed = true;
} catch (Throwable e ) {
if( ! (e instanceof ParserException))
fail( "Unexpected Error: " + e.getMessage() );
}
if( testPassed )
fail( "The expected error did not occur.");
}
public void testBug36714(){
boolean testPassed = false;
try{

View file

@ -0,0 +1,78 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.parser.failedTests;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.parser.tests.DOMTests;
import org.eclipse.cdt.internal.core.dom.TranslationUnit;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
* @author jcamelon
*/
public class LokiFailures extends DOMTests {
public LokiFailures(String name) {
super(name);
}
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new LokiFailures("testBugSingleton192"));
suite.addTest(new LokiFailures("testBugFunctor758"));
return suite;
}
public void testBugSingleton192() {
failTest("int Test::* pMember_;" );
}
public void testBugFunctor758() {
failTest( "template <typename Fun> Functor(Fun fun) : spImpl_(new FunctorHandler<Functor, Fun>(fun)){}" );
}
public void testBugTypeManip151()
{
Writer code = new StringWriter();
try
{
code.write( "template <class T, class U> struct SuperSubclass {\n" );
code.write( "enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists && \n" );
code.write( "!::Loki::Conversion<const volatile T*, const volatile void*>::sameType) }; };" );
} catch( IOException ioe ){}
failTest( code.toString() );
}
public void failTest( String code )
{
boolean testPassed = false;
try {
TranslationUnit tu = parse(code);
testPassed = true;
fail( "We should not reach this point");
} catch (Throwable e) {
if (!(e instanceof ParserException))
fail("Unexpected Error: " + e.getMessage());
}
if (testPassed)
fail("The expected error did not occur.");
}
}

View file

@ -3,6 +3,7 @@ package org.eclipse.cdt.core.parser.tests;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
@ -1615,5 +1616,49 @@ public class DOMTests extends TestCase {
public void testBug36717() throws Exception {
TranslationUnit tu = parse("enum { eA = A::b };");
}
public void testBug36693() throws Exception {
TranslationUnit tu =
parse("FixedAllocator::Chunk* FixedAllocator::VicinityFind(void* p){}");
}
public void testBug36696() throws Exception {
Writer code = new StringWriter();
code.write(
"template <typename P1> RefCounted(const RefCounted<P1>& rhs)\n");
code.write(
": pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_) {}\n");
TranslationUnit tu = parse(code.toString());
}
public void testBug36713() throws Exception {
Writer code = new StringWriter();
code.write("A ( * const fPtr) (void *); \n");
code.write("A (* const fPtr2) ( A * ); \n");
code.write("A (*const fPtr3) ( A * ) = function\n");
TranslationUnit tu = parse(code.toString());
}
public void testBug36794() throws Exception
{
TranslationUnit tu = parse( "template<> class allocator<void> {};");
Iterator i = tu.iterateOffsetableElements();
while( i.hasNext() )
assertNotNull( i.next() );
}
public void testBug36811() throws Exception
{
Writer code = new StringWriter();
code.write( "using namespace std;\n" );
code.write( "class Test {};" );
TranslationUnit tu = parse( code.toString() );
assertEquals( tu.getDeclarations().size(), 2 );
Iterator i = tu.iterateOffsetableElements();
while( i.hasNext() )
assertNotNull( i.next() );
}
}