blob: 959053770fea9206b4c947f5b37100520f83b867 [file] [log] [blame]
/**********************************************************************
* 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:
* Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.parser.tests;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind;
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTClassSpecifier;
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTCompilationUnit;
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTField;
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension;
import org.eclipse.cdt.internal.core.parser.pst.TemplateInstance;
import org.eclipse.cdt.internal.core.parser.pst.TypeFilter;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.OperatorExpression;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
/**
* @author aniefer
*
* To change this generated comment edit the template variable "typecomment":
* Window>Preferences>Java>Templates.
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/
public class ParserSymbolTableTest extends TestCase {
public ParserSymbolTable table = null;
public ParserSymbolTableTest( String arg )
{
super( arg );
}
public ParserSymbolTable newTable(){
return newTable( ParserLanguage.CPP );
}
public ParserSymbolTable newTable( ParserLanguage language ){
table = new ParserSymbolTable( language );
return table;
}
/**
* testSimpleAdd.
* Add a declaration to the table and confirm it is there.
*
* @throws Exception
*/
public void testSimpleAdd() throws Exception{
newTable(); //create the symbol table
ISymbol x = table.newSymbol( "x" );
IContainerSymbol compUnit = table.getCompilationUnit();
compUnit.addSymbol( x );
Map declarations = compUnit.getContainedSymbols();
assertEquals( 1, declarations.size() );
Iterator iter = declarations.values().iterator();
ISymbol contained = (ISymbol) iter.next();
assertEquals( false, iter.hasNext() );
assertEquals( x, contained );
assertEquals( contained.getName(), "x" );
}
/**
* testSimpleLookup
* Add a declaration to the table, then look it up.
* @throws Exception
*/
public void testSimpleLookup() throws Exception{
newTable(); //new symbol table
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( x );
ISymbol look = table.getCompilationUnit().lookup( "x" );
assertEquals( x, look );
}
public void testLookupNonExistant() throws Exception{
newTable();
ISymbol look = table.getCompilationUnit().lookup("boo");
assertEquals( look, null );
}
public void testSimpleSetGetObject() throws Exception{
newTable();
IContainerSymbol x = table.newContainerSymbol( "x", TypeInfo.t_namespace );
ISymbolASTExtension extension = new StandardSymbolExtension(x,null);
x.setASTExtension( extension );
table.getCompilationUnit().addSymbol( x );
ISymbol look = table.getCompilationUnit().lookup( "x" );
assertEquals( look.getASTExtension(), extension );
}
/**
* testHide
* test that a declaration in a scope hides declarations in containing
* scopes
* @throws Exception
*/
public void testHide() throws Exception{
newTable();
ISymbol firstX = table.newSymbol("x");
table.getCompilationUnit().addSymbol( firstX );
IDerivableContainerSymbol firstClass = table.newDerivableContainerSymbol("class");
firstClass.setType( TypeInfo.t_class );
table.getCompilationUnit().addSymbol( firstClass );
ISymbol look = firstClass.lookup( "x" );
assertEquals( look, firstX );
ISymbol secondX = table.newSymbol("x");
firstClass.addSymbol( secondX );
look = firstClass.lookup( "x" );
assertEquals( look, secondX );
look = table.getCompilationUnit().lookup( "x" );
assertEquals( look, firstX );
}
/**
* testContainingScopeLookup
* test lookup of something declared in the containing scope
* @throws Exception
*/
public void testContainingScopeLookup() throws Exception{
newTable();
ISymbol x = table.newSymbol("x");
table.getCompilationUnit().addSymbol( x );
IDerivableContainerSymbol decl = table.newDerivableContainerSymbol("class");
decl.setType( TypeInfo.t_class );
table.getCompilationUnit().addSymbol( decl );
ISymbol look = decl.lookup( "x" );
assertEquals( x, look );
}
/**
* testParentLookup
* test lookup of a variable declaration in the parent
*
* @throws Exception
*/
public void testParentLookup() throws Exception{
newTable();
IDerivableContainerSymbol parent = table.newDerivableContainerSymbol("parent");
parent.setType( TypeInfo.t_class );
IDerivableContainerSymbol class1 = table.newDerivableContainerSymbol("class");
class1.setType( TypeInfo.t_class );
class1.addParent( parent );
ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
parent.addSymbol( decl );
table.getCompilationUnit().addSymbol( parent );
table.getCompilationUnit().addSymbol( class1 );
ISymbol look = class1.lookup( "x" );
assertEquals( look, decl );
}
/**
* testAmbiguousParentLookup
* calls testParentLookup
*
* tests that if a variable is declared in two parents that the lookup
* returns an ambiguous result.
*
* @throws Exception
*/
public void testAmbiguousParentLookup() throws Exception{
testParentLookup();
IDerivableContainerSymbol parent2 = table.newDerivableContainerSymbol("parent2");
table.getCompilationUnit().addSymbol( parent2 );
IDerivableContainerSymbol class1 = (IDerivableContainerSymbol) table.getCompilationUnit().lookup( "class" );
class1.addParent( parent2 );
ISymbol decl = table.newSymbol( "x", TypeInfo.t_int );
parent2.addSymbol( decl );
try{
class1.lookup( "x" );
assertTrue( false );
}
catch ( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
*
* @throws Exception
* test for circular inheritance
*/
public void testCircularParentLookup() throws Exception{
newTable();
IDerivableContainerSymbol a = table.newDerivableContainerSymbol("a");
table.getCompilationUnit().addSymbol( a );
IDerivableContainerSymbol b = table.newDerivableContainerSymbol("b");
b.addParent( a );
table.getCompilationUnit().addSymbol( b );
a.addParent( b );
try{
a.lookup("foo");
assertTrue( false );
} catch ( ParserSymbolTableException e) {
assertEquals( e.reason, ParserSymbolTableException.r_CircularInheritance );
}
}
/**
* testVirtualParentLookup
*
* @throws Exception
* tests lookup of name in virtual baseclass C
*
* C
* / \
* A B
* \ /
* class
*/
public void testVirtualParentLookup() throws Exception{
newTable();
IDerivableContainerSymbol decl = table.newDerivableContainerSymbol("class");
IDerivableContainerSymbol c = table.newDerivableContainerSymbol("C");
IDerivableContainerSymbol a = table.newDerivableContainerSymbol("A");
a.addParent( c, true, ASTAccessVisibility.PUBLIC, 3, null );
IDerivableContainerSymbol b = table.newDerivableContainerSymbol("B");
b.addParent( c, true, ASTAccessVisibility.PUBLIC, 6, null );
decl.addParent( a );
decl.addParent( b );
IContainerSymbol compUnit = table.getCompilationUnit();
compUnit.addSymbol( c );
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
c.addSymbol( x );
compUnit.addSymbol( decl );
compUnit.addSymbol( a );
compUnit.addSymbol( b );
ISymbol look = decl.lookup( "x" );
assertEquals( look, x );
}
/**
* testAmbiguousVirtualParentLookup
* @throws Exception
*
* tests lookup of name in base class C in the following hierarchy
* C C
* / \ |
* A B D
* \ / /
* class
*/
public void testAmbiguousVirtualParentLookup() throws Exception{
testVirtualParentLookup();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol cls = (IDerivableContainerSymbol) compUnit.lookup("class");
IDerivableContainerSymbol c = (IDerivableContainerSymbol) compUnit.lookup("C");
IDerivableContainerSymbol d = table.newDerivableContainerSymbol("D");
d.addParent( c );
cls.addParent( d );
compUnit.addSymbol( d );
try{
cls.lookup( "x" );
assertTrue( false );
}
catch( ParserSymbolTableException e){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
* testStaticEnumParentLookup
*
* @throws Exception
*
* D D
* | |
* B C
* \ /
* A
*
* Things defined in D are not ambiguous if they are static or an enum
*/
public void testStaticEnumParentLookup() throws Exception{
newTable();
IDerivableContainerSymbol a = table.newDerivableContainerSymbol("a" );
IDerivableContainerSymbol b = table.newDerivableContainerSymbol( "b" );
IDerivableContainerSymbol c = table.newDerivableContainerSymbol( "c" );
IDerivableContainerSymbol d = table.newDerivableContainerSymbol( "d" );
IContainerSymbol compUnit = table.getCompilationUnit();
compUnit.addSymbol( a );
compUnit.addSymbol( b );
compUnit.addSymbol( c );
compUnit.addSymbol( d );
IContainerSymbol enum = table.newContainerSymbol( "enum", TypeInfo.t_enumeration );
ISymbol enumerator = table.newSymbol( "enumerator", TypeInfo.t_enumerator );
ISymbol stat = table.newSymbol( "static", TypeInfo.t_int );
stat.getTypeInfo().setBit( true, TypeInfo.isStatic );
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
d.addSymbol( enum );
d.addSymbol( stat );
d.addSymbol( x );
enum.addSymbol( enumerator );
a.addParent( b );
a.addParent( c );
b.addParent( d );
c.addParent( d );
try{
a.lookup( "enumerator" );
assertTrue( true );
}
catch ( ParserSymbolTableException e){
assertTrue( false );
}
try{
a.lookup( "static" );
assertTrue( true );
}
catch ( ParserSymbolTableException e){
assertTrue( false );
}
try{
a.lookup( "x" );
assertTrue( false );
}
catch ( ParserSymbolTableException e){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
* testElaboratedLookup
* @throws Exception
* test lookup of hidden names using elaborated type spec
*/
public void testElaboratedLookup() throws Exception{
newTable();
IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class" );
cls.setType( TypeInfo.t_class );
IDerivableContainerSymbol struct = table.newDerivableContainerSymbol("struct");
struct.setType( TypeInfo.t_struct );
IContainerSymbol union = table.newContainerSymbol("union");
union.setType( TypeInfo.t_union );
IDerivableContainerSymbol hideCls = table.newDerivableContainerSymbol( "class" );
IDerivableContainerSymbol hideStruct = table.newDerivableContainerSymbol("struct");
IContainerSymbol hideUnion = table.newContainerSymbol("union");
IDerivableContainerSymbol a = table.newDerivableContainerSymbol("a");
IDerivableContainerSymbol b = table.newDerivableContainerSymbol("b");
a.addSymbol(hideCls);
a.addSymbol(hideStruct);
a.addSymbol(hideUnion);
a.addParent( b );
b.addSymbol(cls);
b.addSymbol(struct);
b.addSymbol(union);
table.getCompilationUnit().addSymbol( a );
table.getCompilationUnit().addSymbol( b );
ISymbol look = a.elaboratedLookup( TypeInfo.t_class, "class" );
assertEquals( look, cls );
look = a.elaboratedLookup( TypeInfo.t_struct, "struct" );
assertEquals( look, struct );
look = a.elaboratedLookup( TypeInfo.t_union, "union" );
assertEquals( look, union );
}
/**
* testDeclarationType
* @throws Exception
* test the use of ParserSymbolTable.Declaration type in the scenario
* A a;
* a.member <=...>;
* where A was previously declared
*/
public void testDeclarationType() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
//pre-condition
IContainerSymbol A = table.newContainerSymbol("A");
compUnit.addSymbol(A);
ISymbol member = table.newSymbol("member");
A.addSymbol(member);
//at time of "A a;"
ISymbol look = compUnit.lookup("A");
assertEquals( look, A );
ISymbol a = table.newSymbol("a");
a.setTypeSymbol( look );
compUnit.addSymbol( a );
//later "a.member"
look = compUnit.lookup("a");
assertEquals( look, a );
IContainerSymbol type = (IContainerSymbol) look.getTypeSymbol();
assertEquals( type, A );
look = type.lookup("member");
assertEquals( look, member );
}
/**
*
* @throws Exception
*
* struct stat {
* //...
* }
* int stat( struct stat* );
* void f()
* {
* struct stat *ps;
* stat(ps);
* }
*/
public void testFunctionHidesClass() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol struct = table.newDerivableContainerSymbol("stat");
struct.setType( TypeInfo.t_struct );
compUnit.addSymbol( struct );
IParameterizedSymbol function = table.newParameterizedSymbol( "stat" );
function.setType( TypeInfo.t_function );
compUnit.addSymbol( function );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
f.setType( TypeInfo.t_function );
compUnit.addSymbol( f );
ISymbol look = f.elaboratedLookup( TypeInfo.t_struct, "stat" );
assertEquals( look, struct );
look = f.lookup( "stat" );
assertEquals( look, function );
}
/**
*
* @throws Exception
*
* namespace A {
* int i;
* namespace B {
* namespace C{
* int i;
* }
* using namespace A::B::C;
* void f1() {
* i = 5; //OK, C::i visible and hides A::i
* }
* }
* namespace D{
* using namespace B;
* using namespace C;
* void f2(){
* i = 5; //ambiguous, B::C and A::i
* }
* }
* void f3() {
* i = 5; //uses A::i
* }
* }
* void f4(){
* i = 5; //no i is visible here
* }
*
*/
public void testUsingDirectives_1() throws Exception{
newTable();
IContainerSymbol nsA = table.newContainerSymbol("A");
nsA.setType( TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( nsA );
ISymbol nsA_i = table.newSymbol("i");
nsA.addSymbol( nsA_i );
IContainerSymbol nsB = table.newContainerSymbol("B");
nsB.setType( TypeInfo.t_namespace );
nsA.addSymbol( nsB );
IContainerSymbol nsC = table.newContainerSymbol("C");
nsC.setType( TypeInfo.t_namespace );
nsB.addSymbol( nsC );
ISymbol nsC_i = table.newSymbol("i");
nsC.addSymbol( nsC_i );
ISymbol look = nsB.lookup("C");
assertEquals( look, nsC );
nsB.addUsingDirective( nsC );
IParameterizedSymbol f1 = table.newParameterizedSymbol("f");
f1.setType( TypeInfo.t_function );
nsB.addSymbol( f1 );
look = f1.lookup( "i" );
assertEquals( look, nsC_i ); //C::i visible and hides A::i
IContainerSymbol nsD = table.newContainerSymbol("D");
nsD.setType( TypeInfo.t_namespace );
nsA.addSymbol( nsD );
look = nsD.lookup("B");
assertEquals( look, nsB );
nsD.addUsingDirective( nsB );
look = nsD.lookup("C");
assertEquals( look, nsC );
nsD.addUsingDirective( nsC );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f2" );
f2.setType( TypeInfo.t_function );
nsD.addSymbol( f2 );
try
{
look = f2.lookup( "i" );
assertTrue( false );
}
catch ( ParserSymbolTableException e )
{
//ambiguous B::C::i and A::i
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
IParameterizedSymbol f3 = table.newParameterizedSymbol("f3");
f3.setType( TypeInfo.t_function );
nsA.addSymbol( f3 );
look = f3.lookup("i");
assertEquals( look, nsA_i ); //uses A::i
IParameterizedSymbol f4 = table.newParameterizedSymbol("f4");
f4.setType( TypeInfo.t_function );
table.getCompilationUnit().addSymbol( f4 );
look = f4.lookup("i");
assertEquals( look, null );//neither i is visible here.
}
/**
*
* @throws Exception
*
* namespace M {
* int i;
* }
* namespace N {
* int i;
* using namespace M;
* }
*
* void f() {
* using namespace N;
* i = 7; //error, both M::i and N::i are visible
* N::i = 5; //ok, i directly declared in N, using M not
* considered (since this is a qualified lookup)
* }
*
*/
public void testTransitiveUsingDirective() throws Exception
{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol nsM = table.newContainerSymbol( "M" );
nsM.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsM );
ISymbol nsM_i = table.newSymbol("i");
nsM.addSymbol( nsM_i );
IContainerSymbol nsN = table.newContainerSymbol( "N" );
nsN.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsN );
ISymbol nsN_i = table.newSymbol("i");
nsN.addSymbol( nsN_i );
nsN.addUsingDirective( nsM );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
compUnit.addSymbol( f );
f.addUsingDirective( nsN );
ISymbol look = null;
try
{
look = f.lookup( "i" );
assertTrue( false );
}
catch ( ParserSymbolTableException e )
{
//ambiguous, both M::i and N::i are visible.
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
look = f.lookupNestedNameSpecifier("N");
assertEquals( look, nsN );
look = ((IContainerSymbol) look).qualifiedLookup("i"); //ok
assertEquals( look, nsN_i );
}
/**
*
* @throws Exception
* The same declaration found more than once is not an ambiguity
* namespace A{
* int a;
* }
* namespace B{
* using namespace A;
* }
* namespace C{
* using namespace A;
* }
*
* namespace BC{
* using namespace B;
* using namespace C;
* }
*
* void f(){
* BC::a++; //ok
* }
*/
public void testUsing_SameDeclarationTwice() throws Exception
{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol nsA = table.newContainerSymbol("A");
nsA.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsA );
ISymbol a = table.newSymbol("a");
nsA.addSymbol( a );
IContainerSymbol nsB = table.newContainerSymbol("B");
nsB.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsB );
nsB.addUsingDirective( nsA );
IContainerSymbol nsC = table.newContainerSymbol("C");
nsC.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsC );
nsC.addUsingDirective( nsA );
IContainerSymbol nsBC = table.newContainerSymbol("BC");
nsBC.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsBC );
nsBC.addUsingDirective( nsB );
nsBC.addUsingDirective( nsC );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
f.setType(TypeInfo.t_function);
compUnit.addSymbol( f );
ISymbol look = f.lookupNestedNameSpecifier("BC");
assertEquals( look, nsBC );
look = ((IContainerSymbol)look).qualifiedLookup("a");
assertEquals( look, a );
}
/**
*
* @throws Exception
*
* namespace B {
* int b;
* }
* namespace A {
* using namespace B;
* int a;
* }
* namespace B {
* using namespace A;
* }
*
* void f(){
* A::a++; //ok
* A::b++; //ok
* B::a++; //ok
* B::b++; //ok
* }
*/
public void testUsing_SearchedOnce() throws Exception
{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol nsB = table.newContainerSymbol( "B" );
nsB.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsB );
ISymbol b = table.newSymbol("b");
nsB.addSymbol( b );
IContainerSymbol nsA = table.newContainerSymbol( "A" );
nsA.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsA );
nsA.addUsingDirective( nsB );
ISymbol a = table.newSymbol("a");
nsA.addSymbol( a );
nsB.addUsingDirective( nsA );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
compUnit.addSymbol(f);
IContainerSymbol lookA = f.lookupNestedNameSpecifier("A");
assertEquals( lookA, nsA );
ISymbol look = lookA.qualifiedLookup("a");
assertEquals( look, a );
look = lookA.qualifiedLookup("b");
assertEquals( look, b );
IContainerSymbol lookB = f.lookupNestedNameSpecifier("B");
look = lookB.qualifiedLookup("a");
assertEquals( look, a );
look = lookB.qualifiedLookup("b");
assertEquals( look, b );
}
/**
* we pass if we don't go into an infinite loop.
* TBD: we need a mechanism to detect failure of this
* test instead of just looping forever.
*
* @throws Exception
*
* namespace A{
* }
* namespace B{
* using namespace A;
* }
* namespace A{
* using namespace B;
* }
* void f(){
* using namespace A;
* using namespace B;
* i = 1; //not declared anywhere.
* }
*/
public void testUsing_SearchedOnce_2() throws Exception
{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol nsA = table.newContainerSymbol( "A" );
nsA.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsA );
IContainerSymbol nsB = table.newContainerSymbol( "B" );
nsB.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsB );
nsB.addUsingDirective( nsA );
nsA.addUsingDirective( nsB );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
compUnit.addSymbol(f);
f.addUsingDirective(nsA);
f.addUsingDirective(nsB);
ISymbol look = f.lookup("i");
assertEquals( look, null );
}
/**
* During lookup of a qualified namespace member name, if the lookup finds
* more than one declaration of the member, non-type names hide class or
* enumeration names if and only if the declarations are from the same
* namespace
* @throws Exception
*
* namespace A {
* struct x { };
* int x;
* int y;
* }
* namespace B {
* struct y { };
* }
*
* namespace C {
* using namespace A;
* using namespace B;
*
* int i = C::x; //ok, finds A::x
* int j = C::y; //ambiguous, A::y or B::y
* }
*/
public void testNamespaceMemberHiding() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol nsA = table.newContainerSymbol("A");
nsA.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsA );
IContainerSymbol structX = table.newContainerSymbol("x");
structX.setType( TypeInfo.t_struct );
nsA.addSymbol( structX );
ISymbol intX = table.newSymbol("x");
intX.setType( TypeInfo.t_int );
nsA.addSymbol( intX );
ISymbol intY = table.newSymbol("y");
intY.setType( TypeInfo.t_int );
nsA.addSymbol( intY );
IContainerSymbol nsB = table.newContainerSymbol("B");
nsB.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsB );
IContainerSymbol structY = table.newContainerSymbol("y");
structY.setType( TypeInfo.t_struct );
nsB.addSymbol( structY );
IContainerSymbol nsC = table.newContainerSymbol("C");
nsC.setType( TypeInfo.t_namespace);
compUnit.addSymbol( nsC );
ISymbol look = nsC.lookup("A");
assertEquals( look, nsA );
nsC.addUsingDirective( nsA );
look = nsC.lookup("B");
assertEquals( look, nsB );
nsC.addUsingDirective( nsB );
//lookup C::x
look = nsC.lookupNestedNameSpecifier("C");
assertEquals( look, nsC );
look = ((IContainerSymbol)look).qualifiedLookup( "x" );
assertEquals( look, intX );
//lookup C::y
look = nsC.lookupNestedNameSpecifier("C");
assertEquals( look, nsC );
try{
look = ((IContainerSymbol)look).qualifiedLookup( "y" );
assertTrue(false);
} catch ( ParserSymbolTableException e ) {
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
* In a definition for a namespace member in which the declarator-id is a
* qualified-id, given that the qualified-id for the namespace member has
* the form "nested-name-specifier unqualified-id", the unqualified-id shall
* name a member of the namespace designated by the nested-name-specifier.
*
* namespace A{
* namespace B{
* void f1(int);
* }
* using namespace B;
* }
* void A::f1(int) { ... } //ill-formed, f1 is not a member of A
*/
public void testLookupMemberForDefinition() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol nsA = table.newContainerSymbol( "A" );
nsA.setType( TypeInfo.t_namespace );
compUnit.addSymbol( nsA );
IContainerSymbol nsB = table.newContainerSymbol( "B" );
nsB.setType( TypeInfo.t_namespace );
nsA.addSymbol( nsB );
IParameterizedSymbol f1 = table.newParameterizedSymbol("f1");
f1.setType( TypeInfo.t_function );
nsB.addSymbol( f1 );
nsA.addUsingDirective( nsB );
IContainerSymbol lookA = compUnit.lookupNestedNameSpecifier( "A" );
assertEquals( nsA, lookA );
ISymbol look = lookA.lookupMemberForDefinition( "f1" );
assertEquals( look, null );
//but notice if you wanted to do A::f1 as a function call, it is ok
look = lookA.qualifiedLookup( "f1" );
assertEquals( look, f1 );
}
/**
* testUsingDeclaration
* @throws Exception
* 7.3.3-4 A using-declaration used as a member-declaration shall refer to a
* member of a base-class of the class being defined, shall refer to a
* member of an anonymous union that is a member of a base class of the
* class being defined or shall refer to an enumerator for an enumeration
* type that is a member of a base class of the class being defined
*
* struct B {
* void f( char );
* enum E { e };
* union { int x; };
* };
* class C {
* int g();
* }
* struct D : B {
* using B::f; //ok, B is a base class of D
* using B::e; //ok, e is an enumerator in base class B
* using B::x; //ok, x is an union member of base class B
* using C::g; //error, C isn't a base class of D
* }
*/
public void testUsingDeclaration() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol B = table.newDerivableContainerSymbol("B");
B.setType( TypeInfo.t_struct );
compUnit.addSymbol( B );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
f.setType( TypeInfo.t_function );
B.addSymbol( f );
IContainerSymbol E = table.newContainerSymbol( "E" );
E.setType( TypeInfo.t_enumeration );
B.addSymbol( E );
ISymbol e = table.newSymbol( "e" );
e.setType( TypeInfo.t_enumerator );
E.addSymbol( e );
/**
* TBD: Anonymous unions are not yet implemented
*/
IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C" );
C.setType( TypeInfo.t_class );
compUnit.addSymbol( C );
IParameterizedSymbol g = table.newParameterizedSymbol( "g" );
g.setType( TypeInfo.t_function );
C.addSymbol( g );
IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D" );
D.setType( TypeInfo.t_struct );
ISymbol look = compUnit.lookup( "B" );
assertEquals( look, B );
D.addParent( B );
compUnit.addSymbol( D );
IContainerSymbol lookB = D.lookupNestedNameSpecifier("B");
assertEquals( lookB, B );
D.addUsingDeclaration( "f", lookB );
D.addUsingDeclaration( "e", lookB );
//TBD anonymous union
//D.addUsingDeclaration( "x", lookB );
look = D.lookupNestedNameSpecifier("C");
assertEquals( look, C );
try{
D.addUsingDeclaration( "g", C );
assertTrue( false );
}
catch ( ParserSymbolTableException exception ){
assertTrue( true );
}
}
/**
* testUsingDeclaration_2
* @throws Exception
* 7.3.3-9 The entity declared by a using-declaration shall be known in the
* context using it according to its definition at the point of the using-
* declaration. Definitions added to the namespace after the using-
* declaration are not considered when a use of the name is made.
*
* namespace A {
* void f(int);
* }
* using A::f;
*
* namespace A {
* void f(char);
* }
* void foo(){
* f('a'); //calls f( int )
* }
* void bar(){
* using A::f;
* f('a'); //calls f( char );
* }
*/
public void testUsingDeclaration_2() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol A = table.newContainerSymbol( "A", TypeInfo.t_namespace );
compUnit.addSymbol( A );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_int, 0, null, false );
A.addSymbol( f1 );
ISymbol look = compUnit.lookupNestedNameSpecifier("A");
assertEquals( look, A );
IParameterizedSymbol usingF = (IParameterizedSymbol) compUnit.addUsingDeclaration( "f", A );
look = compUnit.lookup("A");
assertEquals( look, A );
IParameterizedSymbol f2 = table.newParameterizedSymbol("f");
f2.setType( TypeInfo.t_function );
f2.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f2.addParameter( TypeInfo.t_char, 0, null, false );
A.addSymbol( f2 );
IParameterizedSymbol foo = table.newParameterizedSymbol("foo");
foo.setType( TypeInfo.t_function );
compUnit.addSymbol( foo );
LinkedList paramList = new LinkedList();
TypeInfo param = new TypeInfo( TypeInfo.t_char, 0, null );
paramList.add( param );
look = foo.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, usingF );
assertTrue( usingF.hasSameParameters( f1 ) );
IParameterizedSymbol bar = table.newParameterizedSymbol( "bar" );
bar.setType( TypeInfo.t_function );
bar.addParameter( TypeInfo.t_char, 0, null, false );
compUnit.addSymbol( bar );
look = bar.lookupNestedNameSpecifier( "A" );
assertEquals( look, A );
bar.addUsingDeclaration( "f", A );
look = bar.unqualifiedFunctionLookup( "f", paramList );
assertTrue( look != null );
assertTrue( ((IParameterizedSymbol) look).hasSameParameters( f2 ) );
}
/**
* testThisPointer
* @throws Exception
* In the body of a nonstatic member function... the type of this of a class
* X is X*. If the member function is declared const, the type of this is
* const X*, if the member function is declared volatile, the type of this
* is volatile X*....
*/
public void testThisPointer() throws Exception{
newTable();
IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class", TypeInfo.t_class );
IParameterizedSymbol fn = table.newParameterizedSymbol("function");
fn.setType( TypeInfo.t_function );
fn.getTypeInfo().addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) );
//fn.setCVQualifier( ParserSymbolTable.TypeInfo.cvConst );
table.getCompilationUnit().addSymbol( cls );
cls.addSymbol( fn );
ISymbol look = fn.lookup("this");
assertTrue( look != null );
assertEquals( look.getType(), TypeInfo.t_type );
assertEquals( look.getTypeSymbol(), cls );
assertEquals( ((PtrOp)look.getPtrOperators().iterator().next()).getType(), TypeInfo.PtrOp.t_pointer );
assertTrue( ((PtrOp)look.getPtrOperators().iterator().next()).isConst() );
assertEquals( look.getContainingSymbol(), fn );
}
/**
* testEnumerator
* @throws Exception
* Following the closing brace of an enum-specifier, each enumerator has the
* type of its enumeration.
* The enum-name and each enumerator declared by an enum-specifier is
* declared in the scope that immediately contains the enum-specifier
*/
public void testEnumerator() throws Exception{
newTable();
IContainerSymbol cls = table.newContainerSymbol("class");
cls.setType( TypeInfo.t_class );
IContainerSymbol enumeration = table.newContainerSymbol("enumeration");
enumeration.setType( TypeInfo.t_enumeration );
table.getCompilationUnit().addSymbol( cls );
cls.addSymbol( enumeration );
ISymbol enumerator = table.newSymbol( "enumerator" );
enumerator.setType( TypeInfo.t_enumerator );
enumeration.addSymbol( enumerator );
ISymbol look = cls.lookup( "enumerator" );
assertEquals( look, enumerator );
assertEquals( look.getContainingSymbol(), cls );
assertEquals( look.getTypeSymbol(), enumeration );
}
/**
*
* @throws Exception
*
* namespace NS{
* class T {};
* void f( T );
* }
* NS::T parm;
* int main(){
* f( parm ); //ok, calls NS::f
* }
*/
public void testArgumentDependentLookup() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol NS = table.newContainerSymbol("NS");
NS.setType( TypeInfo.t_namespace );
compUnit.addSymbol( NS );
IDerivableContainerSymbol T = table.newDerivableContainerSymbol("T");
T.setType( TypeInfo.t_class );
NS.addSymbol( T );
IParameterizedSymbol f = table.newParameterizedSymbol("f");
f.setType( TypeInfo.t_function );
f.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
ISymbol look = NS.lookup( "T" );
assertEquals( look, T );
f.addParameter( look, null, false );
NS.addSymbol( f );
look = compUnit.lookupNestedNameSpecifier( "NS" );
assertEquals( look, NS );
look = NS.qualifiedLookup( "T" );
assertEquals( look, T );
ISymbol param = table.newSymbol("parm");
param.setType( TypeInfo.t_type );
param.setTypeSymbol( look );
compUnit.addSymbol( param );
IParameterizedSymbol main = table.newParameterizedSymbol("main");
main.setType( TypeInfo.t_function );
main.setReturnType( table.newSymbol( "", TypeInfo.t_int ) );
compUnit.addSymbol( main );
LinkedList paramList = new LinkedList();
look = main.lookup( "parm" );
assertEquals( look, param );
TypeInfo p = new TypeInfo( TypeInfo.t_type, 0, look );
paramList.add( p );
look = main.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f );
}
/**
* testArgumentDependentLookup_2
* @throws Exception
* in the following, NS2 is an associated namespace of class B which is an
* associated namespace of class A, so we should find f in NS2, we should
* not find f in NS1 because usings are ignored for associated scopes.
*
*
* namespace NS1{
* void f( void * ){};
* }
* namespace NS2{
* using namespace NS1;
* class B {};
* void f( void * ){};
* }
*
* class A : public NS2::B {};
*
* A a;
* f( &a );
*
*/
public void testArgumentDependentLookup_2() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IContainerSymbol NS1 = table.newContainerSymbol( "NS1" );
NS1.setType( TypeInfo.t_namespace );
compUnit.addSymbol( NS1 );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
NS1.addSymbol( f1 );
IContainerSymbol NS2 = table.newContainerSymbol( "NS2" );
NS2.setType( TypeInfo.t_namespace );
compUnit.addSymbol( NS2 );
ISymbol look = NS2.lookup( "NS1" );
assertEquals( look, NS1 );
NS2.addUsingDirective( NS1 );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" );
B.setType( TypeInfo.t_class );
NS2.addSymbol( B );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
f2.setType( TypeInfo.t_function );
f2.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f2.addParameter( TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false );
NS2.addSymbol( f2 );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" );
A.setType( TypeInfo.t_class );
look = compUnit.lookupNestedNameSpecifier( "NS2" );
assertEquals( look, NS2 );
look = NS2.qualifiedLookup( "B" );
assertEquals( look, B );
A.addParent( B );
compUnit.addSymbol( A );
look = compUnit.lookup( "A" );
assertEquals( look, A );
ISymbol a = table.newSymbol( "a" );
a.setType( TypeInfo.t_type );
a.setTypeSymbol( look );
compUnit.addSymbol( a );
LinkedList paramList = new LinkedList();
look = compUnit.lookup( "a" );
assertEquals( look, a );
TypeInfo param = new TypeInfo( look.getType(), 0, look, null, false );
//new PtrOp( PtrOp.t_reference )
param.addOperatorExpression( OperatorExpression.addressof );
paramList.add( param );
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
}
/**
* testFunctionOverloading
* @throws Exception
* Note that this test has been contrived to not strain the resolution as
* that aspect is not yet complete.
*
* class C
* {
* void foo( int i );
* void foo( int i, char c );
* void foo( int i, char c, C * ptr );
* }
*
* C * c = new C;
* c->foo( 1 );
* c->foo( 1, 'a' );
* c->foo( 1, 'a', c );
*
*/
public void testFunctionOverloading() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C" );
C.setType( TypeInfo.t_class );
compUnit.addSymbol(C);
IParameterizedSymbol f1 = table.newParameterizedSymbol("foo");
f1.setType( TypeInfo.t_function );
f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f1.addParameter( TypeInfo.t_int, 0, null, false );
C.addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol("foo");
f2.setType( TypeInfo.t_function );
f2.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f2.addParameter( TypeInfo.t_int, 0, null, false );
f2.addParameter( TypeInfo.t_char, 0, null, false );
C.addSymbol( f2 );
IParameterizedSymbol f3 = table.newParameterizedSymbol("foo");
f3.setType( TypeInfo.t_function );
f3.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
f3.addParameter( TypeInfo.t_int, 0, null, false );
f3.addParameter( TypeInfo.t_char, 0, null, false );
f3.addParameter( C, new PtrOp( PtrOp.t_pointer ), false );
C.addSymbol( f3 );
ISymbol look = compUnit.lookup("C");
assertEquals( look, C );
ISymbol c = table.newSymbol("c");
c.setType( TypeInfo.t_type );
c.setTypeSymbol( look );
c.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
compUnit.addSymbol( c );
look = compUnit.lookup( "c" );
assertEquals( look, c );
assertEquals( look.getTypeSymbol(), C );
LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_int, 0, null );
TypeInfo p2 = new TypeInfo( TypeInfo.t_char, 0, null );
TypeInfo p3 = new TypeInfo( TypeInfo.t_type, 0, c );
paramList.add( p1 );
look = C.memberFunctionLookup( "foo", paramList );
assertEquals( look, f1 );
paramList.add( p2 );
look = C.memberFunctionLookup( "foo", paramList );
assertEquals( look, f2 );
paramList.add( p3 );
look = C.memberFunctionLookup( "foo", paramList );
assertEquals( look, f3 );
}
/**
*
* @throws Exception
* test basic function resolution
*
* void f( int i );
* void f( char c = 'c' );
*
* f( 1 ); //calls f( int );
* f( 'b' ); //calls f( char );
* f(); //calls f( char );
*/
public void testFunctionResolution() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IParameterizedSymbol f1 = table.newParameterizedSymbol("f");
f1.setType( TypeInfo.t_function );
f1.addParameter( TypeInfo.t_int, 0, null, false );
compUnit.addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol("f");
f2.setType( TypeInfo.t_function );
f2.addParameter( TypeInfo.t_char, 0, null, true );
compUnit.addSymbol( f2 );
LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_int, 0, null );
paramList.add( p1 );
ISymbol look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
paramList.clear();
TypeInfo p2 = new TypeInfo( TypeInfo.t_char, 0, null );
paramList.add( p2 );
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
paramList.clear();
TypeInfo p3 = new TypeInfo( TypeInfo.t_bool, 0, null );
paramList.add( p3 );
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
look = compUnit.unqualifiedFunctionLookup( "f", null );
assertEquals( look, f2 );
}
/**
*
* @throws Exception
*
* class A { };
* class B : public A {};
* class C : public B {};
*
* void f ( A * );
* void f ( B * );
*
* A* a = new A();
* C* c = new C();
*
* f( a ); //calls f( A * );
* f( c ); //calls f( B * );
*/
public void testFunctionResolution_PointersAndBaseClasses() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" );
A.setType( TypeInfo.t_class );
compUnit.addSymbol( A );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" );
B.setType( TypeInfo.t_class );
B.addParent( A );
compUnit.addSymbol( B );
IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C" );
C.setType( TypeInfo.t_class );
C.addParent( B );
compUnit.addSymbol( C );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
f1.setType( TypeInfo.t_function );
f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false );
compUnit.addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
f2.setType( TypeInfo.t_function );
f2.addParameter( B, new PtrOp( PtrOp.t_pointer ), false );
compUnit.addSymbol( f2 );
ISymbol a = table.newSymbol( "a" );
a.setType( TypeInfo.t_type );
a.setTypeSymbol( A );
a.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
ISymbol c = table.newSymbol( "c" );
c.setType( TypeInfo.t_type );
c.setTypeSymbol( C );
c.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_type, 0, a );
paramList.add( p1 );
ISymbol look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
paramList.clear();
TypeInfo p2 = new TypeInfo( TypeInfo.t_type, 0, c );
paramList.add( p2 );
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
}
/**
*
* @throws Exception
*
* class A {};
* typedef B A *;
*
* void f( A * );
* void f( A );
*
* A a;
* B b;
* A [] array;
*
* f( a ); //calls f( A );
* f( &a ); //calls f( A * );
* f( b ); //calls f( A * );
* f( *b ); //calls f( A );
* f( array ); //calls f( A * );
*/
public void testFunctionResolution_TypedefsAndPointers() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" );
A.setType( TypeInfo.t_class );
compUnit.addSymbol( A );
ISymbol B = table.newSymbol( "B" );
B.setType( TypeInfo.t_type );
B.setTypeSymbol( A );
B.getTypeInfo().setBit( true, TypeInfo.isTypedef );
B.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
compUnit.addSymbol( B );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
f1.setType( TypeInfo.t_function );
f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false );
compUnit.addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
f2.setType( TypeInfo.t_function );
f2.addParameter( A, null, false );
compUnit.addSymbol( f2 );
ISymbol a = table.newSymbol( "a" );
a.setType( TypeInfo.t_type );
a.setTypeSymbol( A );
compUnit.addSymbol( a );
ISymbol b = table.newSymbol( "b" );
b.setType( TypeInfo.t_type );
b.setTypeSymbol( B );
compUnit.addSymbol( b );
ISymbol array = table.newSymbol( "array" );
array.setType( TypeInfo.t_type );
array.setTypeSymbol( A );
array.addPtrOperator( new PtrOp( PtrOp.t_array, false, false ) );
LinkedList paramList = new LinkedList();
TypeInfo p = new TypeInfo( TypeInfo.t_type, 0, a );
paramList.add( p );
ISymbol look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
p.addOperatorExpression( OperatorExpression.addressof );
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
p.setTypeSymbol( b );
p.getOperatorExpressions().clear();
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
p.addOperatorExpression( OperatorExpression.indirection );
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
p.setTypeSymbol( array );
p.getOperatorExpressions().clear();
look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
}
/**
*
* @throws Exception
*
* class A {};
*
* class B
* {
* B( A a ){ };
* };
*
* void f( B b ){};
*
* A a;
* f( a );
*/
public void testUserDefinedConversionSequences() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" );
A.setType( TypeInfo.t_class );
compUnit.addSymbol( A );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" );
B.setType( TypeInfo.t_class );
compUnit.addSymbol( B );
IParameterizedSymbol constructor = table.newParameterizedSymbol("B");
constructor.setType( TypeInfo.t_constructor );
constructor.addParameter( A, null, false );
B.addConstructor( constructor );
IParameterizedSymbol f = table.newParameterizedSymbol( "f" );
f.setType( TypeInfo.t_function );
f.addParameter( B, null, false );
compUnit.addSymbol( f );
ISymbol a = table.newSymbol( "a" );
a.setType( TypeInfo.t_type );
a.setTypeSymbol( A );
compUnit.addSymbol( a );
LinkedList paramList = new LinkedList();
TypeInfo p = new TypeInfo( TypeInfo.t_type, 0, a );
paramList.add( p );
ISymbol look = compUnit.unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f );
}
/**
*
* @throws Exception
*
* void f( const int *, short );
* void f( int *, int );
*
* int i;
* short s;
*
* void main() {
* f( &i, s ); //ambiguous because &i->int* is better than &i->const int *
* //but s-> short is better than s->int
* f( &i, 1L ); //calls f(int *, int) because &i->int* is better than &i->const int *
* //and 1L->short and 1L->int are indistinguishable
* f( &i, 'c' ); //calls f( int*, int) because &i->int * is better than &i->const int *
* //and c->int is better than c->short
* f( (const)&i, 1L ); //calls f(const int *, short ) because const &i->int* is better than &i->int *
* //and 1L->short and 1L->int are indistinguishable
* }
*/
public void testOverloadRanking() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
f1.setType( TypeInfo.t_function );
f1.addParameter( TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer, true, false ), false );
f1.addParameter( TypeInfo.t_int, TypeInfo.isShort, null, false );
compUnit.addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
f2.setType( TypeInfo.t_function );
f2.addParameter( TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer ), false );
f2.addParameter( TypeInfo.t_int, 0, null, false );
compUnit.addSymbol( f2 );
ISymbol i = table.newSymbol( "i" );
i.setType( TypeInfo.t_int );
compUnit.addSymbol( i );
ISymbol s = table.newSymbol( "s" );
s.setType( TypeInfo.t_int );
s.getTypeInfo().setBit( true, TypeInfo.isShort );
compUnit.addSymbol( s );
IParameterizedSymbol main = table.newParameterizedSymbol( "main" );
main.setType( TypeInfo.t_function );
compUnit.addSymbol( main );
LinkedList params = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_type, 0, i );
p1.addOperatorExpression( OperatorExpression.addressof );
TypeInfo p2 = new TypeInfo( TypeInfo.t_type, 0, s );
params.add( p1 );
params.add( p2 );
ISymbol look = null;
try{
look = main.unqualifiedFunctionLookup( "f", params );
assertTrue( false );
} catch ( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
params.clear();
TypeInfo p3 = new TypeInfo( TypeInfo.t_int, TypeInfo.isLong, null );
params.add( p1 );
params.add( p3 );
look = main.unqualifiedFunctionLookup( "f", params );
assertEquals( look, f2 );
params.clear();
TypeInfo p4 = new TypeInfo( TypeInfo.t_char, 0, null );
params.add( p1 );
params.add( p4 );
look = main.unqualifiedFunctionLookup( "f", params );
assertEquals( look, f2 );
params.clear();
p1.addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) );
//((PtrOp)p1.getPtrOperators().iterator().next()).setConst( true );
params.add( p1 );
params.add( p3 );
look = main.unqualifiedFunctionLookup( "f", params );
assertEquals( look, f1 );
}
/**
*
* @throws Exception
*
* class B;
* class A { A( B& ); };
* class B { operator A(); };
*
* void f(A){}
*
* B b;
* f( b ); //ambiguous because b->A via constructor or conversion
*
* class C { C( B& ); };
*
* void f(C){}
*
* f( b ); //ambiguous because b->C via constructor and b->a via constructor/conversion
*
* void f(B){}
*
* f( b ); //calls f(B)
*/
public void testUserDefinedConversionByOperator() throws Exception{
newTable();
IContainerSymbol compUnit = table.getCompilationUnit();
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" );
B.setType( TypeInfo.t_class );
compUnit.addSymbol( B );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" );
A.setType( TypeInfo.t_class );
compUnit.addSymbol( A );
IParameterizedSymbol constructA = table.newParameterizedSymbol( "A" );
constructA.setType( TypeInfo.t_constructor );
constructA.addParameter( B, new PtrOp( PtrOp.t_reference ), false );
A.addConstructor( constructA );
IParameterizedSymbol operator = table.newParameterizedSymbol( "operator A" );
operator.setType( TypeInfo.t_function );
B.addSymbol( operator );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" );
f1.setType( TypeInfo.t_function );
f1.addParameter( A, null, false );
compUnit.addSymbol( f1 );
ISymbol b = table.newSymbol( "b" );
b.setType( TypeInfo.t_type );
b.setTypeSymbol( B );
LinkedList params = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_type, 0, b );
params.add( p1 );
ISymbol look = null;
try{
look = compUnit.unqualifiedFunctionLookup( "f", params );
assertTrue( false );
} catch( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
IDerivableContainerSymbol C = table.newDerivableContainerSymbol("C");
C.setType( TypeInfo.t_class );
compUnit.addSymbol( C );
IParameterizedSymbol constructC = table.newParameterizedSymbol("C");
constructC.setType( TypeInfo.t_constructor );
constructC.addParameter( B, new PtrOp( PtrOp.t_reference ), false );
C.addConstructor( constructC );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" );
f2.setType( TypeInfo.t_function );
f2.addParameter( C, null, false );
compUnit.addSymbol( f2 );
try{
look = compUnit.unqualifiedFunctionLookup( "f", params );
assertTrue( false );
} catch( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
IParameterizedSymbol f3 = table.newParameterizedSymbol( "f" );
f3.setType( TypeInfo.t_function );
f3.addParameter( B, null, false );
compUnit.addSymbol( f3 );
look = compUnit.unqualifiedFunctionLookup( "f", params );
assertEquals( look, f3 );
}
public void testMarkRollback() throws Exception{
newTable();
IDerivableContainerSymbol A = table.newDerivableContainerSymbol("A");
A.setType( TypeInfo.t_class );
table.getCompilationUnit().addSymbol( A );
Mark mark = table.setMark();
ISymbol f = table.newSymbol("f");
A.addSymbol( f );
ISymbol look = A.lookup("f");
assertEquals( look, f );
assertTrue( table.rollBack( mark ) );
look = A.lookup("f");
assertEquals( look, null );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol("B");
B.setType( TypeInfo.t_class );
mark = table.setMark();
table.getCompilationUnit().addSymbol( B );
Mark mark2 = table.setMark();
A.addParent( B );
Mark mark3 = table.setMark();
IParameterizedSymbol C = table.newParameterizedSymbol("C");
C.addParameter( TypeInfo.t_class, 0, null, false );
assertEquals( C.getParameterList().size(), 1 );
table.rollBack( mark3 );
assertEquals( C.getParameterList().size(), 0 );
assertEquals( A.getParents().size(), 1 );
table.rollBack( mark2 );
assertEquals( A.getParents().size(), 0 );
assertFalse( table.commit( mark2 ) );
assertFalse( table.rollBack( mark2 ) );
B.setType( TypeInfo.t_namespace );
mark = table.setMark();
C.addUsingDirective( B );
assertEquals( C.getUsingDirectives().size(), 1 );
table.rollBack( mark );
assertEquals( C.getUsingDirectives().size(), 0 );
}
/**
*
* @throws Exception
*
* template < class T > class A : public T {};
*
* class B
* {
* int i;
* }
*
* A<B> a;
* a.i; //finds B::i;
*/
public void testTemplateParameterAsParent() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol param = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( param );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
template.addSymbol( A );
A.addParent( param );
table.getCompilationUnit().addSymbol( template );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
B.addSymbol( i );
TypeInfo type = new TypeInfo( TypeInfo.t_class, 0, B );
LinkedList args = new LinkedList();
args.add( type );
TemplateInstance instance = table.getCompilationUnit().templateLookup( "A", args );
assertEquals( instance.getInstantiatedSymbol(), A );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( instance );
table.getCompilationUnit().addSymbol( a );
ISymbol look = table.getCompilationUnit().lookup( "a" );
assertEquals( look, a );
ISymbol symbol = a.getTypeSymbol();
assertEquals( symbol, instance );
look = ((IContainerSymbol)instance.getInstantiatedSymbol()).lookup( "i" );
assertEquals( look, i );
}
/**
*
* @throws Exception
*
* template < class T > class A { T t; }
* class B : public A< int > { }
*
* B b;
* b.t; //finds A::t, will be type int
*/
public void testTemplateInstanceAsParent() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol param = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( param );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
ISymbol look = template.lookup( "T" );
assertEquals( look, param );
t.setTypeSymbol( param );
template.addSymbol( A );
A.addSymbol( t );
table.getCompilationUnit().addSymbol( template );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
TypeInfo type = new TypeInfo( TypeInfo.t_int, 0 , null );
LinkedList args = new LinkedList();
args.add( type );
look = table.getCompilationUnit().templateLookup( "A", args );
assertTrue( look instanceof TemplateInstance );
B.addParent( look );
table.getCompilationUnit().addSymbol( B );
ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
b.setTypeSymbol( B );
table.getCompilationUnit().addSymbol( b );
look = table.getCompilationUnit().lookup( "b" );
assertEquals( look, b );
look = ((IDerivableContainerSymbol) b.getTypeSymbol()).lookup( "t" );
assertTrue( look instanceof TemplateInstance );
TemplateInstance instance = (TemplateInstance) look;
assertEquals( instance.getInstantiatedSymbol(), t );
assertTrue( instance.isType( TypeInfo.t_int ) );
}
/**
* The scope of a template-parameter extends from its point of declaration
* until the end of its template. In particular, a template parameter can be used
* in the declaration of a subsequent template-parameter and its default arguments.
* @throws Exception
*
* template< class T, class U = T > class X
* {
* T t;
* U u;
* };
*
* X< char > x;
* x.t;
* x.u;
*/
public void testTemplateParameterDefaults() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "X", TypeInfo.t_template );
ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( paramT );
ISymbol look = template.lookup( "T" );
assertEquals( look, paramT );
ISymbol paramU = table.newSymbol( "U", TypeInfo.t_undef );
paramU.getTypeInfo().setDefault( new TypeInfo( TypeInfo.t_type, 0, look ) );
template.addParameter( paramU );
IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class );
template.addSymbol( X );
look = X.lookup( "T" );
assertEquals( look, paramT );
ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
t.setTypeSymbol( look );
X.addSymbol( t );
look = X.lookup( "U" );
assertEquals( look, paramU );
ISymbol u = table.newSymbol( "u", TypeInfo.t_type );
u.setTypeSymbol( look );
X.addSymbol( u );
table.getCompilationUnit().addSymbol( template );
TypeInfo type = new TypeInfo( TypeInfo.t_char, 0, null );
LinkedList args = new LinkedList();
args.add( type );
look = table.getCompilationUnit().templateLookup( "X", args );
assertTrue( look instanceof TemplateInstance );
TemplateInstance instance = (TemplateInstance) look;
look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).lookup( "t" );
assertTrue( look instanceof TemplateInstance );
assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) );
look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).lookup( "u" );
assertTrue( look instanceof TemplateInstance );
assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) );
}
/**
*
* @throws Exception
* template < class T > class A {
* T t;
* };
* class B {};
* void f( char c ) {}
* void f( A<B> b ) { ... }
* void f( int i ) {}
*
* A<B> a;
* f( a ); //calls f( A<B> )
*
*/
public void testTemplateParameterAsFunctionArgument() throws Exception{
newTable();
IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef );
template.addParameter( paramT );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
template.addSymbol( A );
ISymbol t = table.newSymbol( "t", TypeInfo.t_type );
t.setTypeSymbol( paramT );
A.addSymbol( t );
table.getCompilationUnit().addSymbol( template );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( B );
IParameterizedSymbol temp = (IParameterizedSymbol) table.getCompilationUnit().lookup( "A" );
assertEquals( temp, template );
LinkedList args = new LinkedList();
TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, B );
args.add( arg );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.addParameter( TypeInfo.t_char, 0, null, false );
table.getCompilationUnit().addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f2.addParameter( temp.instantiate( args ), null, false );
table.getCompilationUnit().addSymbol( f2 );
IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f3.addParameter( TypeInfo.t_int, 0, null, false );
table.getCompilationUnit().addSymbol( f3 );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( temp.instantiate( args ) );
table.getCompilationUnit().addSymbol( a );
LinkedList params = new LinkedList();
params.add( new TypeInfo( TypeInfo.t_type, 0, a ) );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", params );
assertEquals( look, f2 );
}
/**
*
* template < class T1, class T2, int I > class A {} //#1
* template < class T, int I > class A < T, T*, I > {} //#2
* template < class T1, class T2, int I > class A < T1*, T2, I > {} //#3
* template < class T > class A < int, T*, 5 > {} //#4
* template < class T1, class T2, int I > class A < T1, T2*, I > {} //#5
*
* A <int, int, 1> a1; //uses #1
* A <int, int*, 1> a2; //uses #2, T is int, I is 1
* A <int, char*, 5> a3; //uses #4, T is char
* A <int, char*, 1> a4; //uses #5, T is int, T2 is char, I is1
* A <int*, int*, 2> a5; //ambiguous, matches #3 & #5.
*
* @throws Exception
*/
//TODO
public void incompletetestTemplateSpecialization() throws Exception{
newTable();
IDerivableContainerSymbol cls1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls3 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls4 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol cls5 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IParameterizedSymbol template1 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T1p1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T1p2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T1p3 = table.newSymbol( "I", TypeInfo.t_int );
template1.addParameter( T1p1 );
template1.addParameter( T1p2 );
template1.addParameter( T1p3 );
template1.addSymbol( cls1 );
table.getCompilationUnit().addSymbol( template1 );
IParameterizedSymbol template2 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T2p1 = table.newSymbol( "T", TypeInfo.t_undef );
ISymbol T2p2 = table.newSymbol( "I", TypeInfo.t_int );
template2.addParameter( T2p1 );
template2.addParameter( T2p2 );
ISymbol T2a1 = table.newSymbol( "T", TypeInfo.t_undef );
ISymbol T2a2 = table.newSymbol( "T", TypeInfo.t_undef );
T2a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T2a3 = table.newSymbol( "I", TypeInfo.t_int );
template2.addArgument( T2a1 );
template2.addArgument( T2a2 );
template2.addArgument( T2a3 );
template2.addSymbol( cls2 );
template1.addSpecialization( template2 );
IParameterizedSymbol template3 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T3p1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T3p2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T3p3 = table.newSymbol( "I", TypeInfo.t_int );
template3.addParameter( T3p1 );
template3.addParameter( T3p2 );
template3.addParameter( T3p3 );
ISymbol T3a1 = table.newSymbol( "T1", TypeInfo.t_undef );
T3a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T3a2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T3a3 = table.newSymbol( "I", TypeInfo.t_int );
template3.addArgument( T3a1 );
template3.addArgument( T3a2 );
template3.addArgument( T3a3 );
template3.addSymbol( cls3 );
template1.addSpecialization( template3 );
IParameterizedSymbol template4 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T4p1 = table.newSymbol( "T", TypeInfo.t_undef );
template4.addParameter( T4p1 );
ISymbol T4a1 = table.newSymbol( "", TypeInfo.t_int );
ISymbol T4a2 = table.newSymbol( "T", TypeInfo.t_undef );
T4a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T4a3 = table.newSymbol( "", TypeInfo.t_int );
T4a3.getTypeInfo().setDefault( new Integer(5) );
template4.addArgument( T4a1 );
template4.addArgument( T4a2 );
template4.addArgument( T4a3 );
template4.addSymbol( cls4 );
template1.addSpecialization( template4 );
IParameterizedSymbol template5 = table.newParameterizedSymbol( "A", TypeInfo.t_template );
ISymbol T5p1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T5p2 = table.newSymbol( "T2", TypeInfo.t_undef );
ISymbol T5p3 = table.newSymbol( "I", TypeInfo.t_int );
template5.addParameter( T5p1 );
template5.addParameter( T5p2 );
template5.addParameter( T5p3 );
ISymbol T5a1 = table.newSymbol( "T1", TypeInfo.t_undef );
ISymbol T5a2 = table.newSymbol( "T2", TypeInfo.t_undef );
T5a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
ISymbol T5a3 = table.newSymbol( "I", TypeInfo.t_int );
template5.addArgument( T5a1 );
template5.addArgument( T5a2 );
template5.addArgument( T5a3 );
template5.addSymbol( cls5 );
template1.addSpecialization( template5 );
IParameterizedSymbol a = (IParameterizedSymbol) table.getCompilationUnit().lookup( "A" );
LinkedList args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
TemplateInstance a1 = a.instantiate( args );
assertEquals( a1.getInstantiatedSymbol(), cls1 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
TemplateInstance a2 = a.instantiate( args );
assertEquals( a2.getInstantiatedSymbol(), cls2 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(5) ) );
TemplateInstance a3 = a.instantiate( args );
assertEquals( a3.getInstantiatedSymbol(), cls4 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) );
TemplateInstance a4 = a.instantiate( args );
assertEquals( a4.getInstantiatedSymbol(), cls5 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) );
args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(2) ) );
try{
a.instantiate( args );
} catch ( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
* class A;
*
* A * a;
*
* class A {};
*
* @throws Exception
*/
public void testForwardClassDeclaration() throws Exception{
newTable();
ISymbol forwardSymbol = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
forwardSymbol.setIsForwardDeclaration( true );
table.getCompilationUnit().addSymbol( forwardSymbol );
/*...*/
ISymbol lookup = table.getCompilationUnit().lookup( "A" );
ISymbol otherLookup = table.getCompilationUnit().elaboratedLookup( TypeInfo.t_class, "A" );
assertEquals( lookup, otherLookup );
assertEquals( lookup, forwardSymbol );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( forwardSymbol );
a.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
table.getCompilationUnit().addSymbol( a );
/*...*/
lookup = table.getCompilationUnit().lookup( "A" );
IDerivableContainerSymbol classA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
assertTrue( lookup.isForwardDeclaration() );
lookup.setTypeSymbol( classA );
table.getCompilationUnit().addSymbol( classA );
lookup = table.getCompilationUnit().lookup( "a" );
assertEquals( lookup, a );
assertEquals( a.getTypeSymbol(), classA );
lookup = table.getCompilationUnit().lookup( "A" );
assertEquals( lookup, classA );
lookup = table.getCompilationUnit().elaboratedLookup( TypeInfo.t_class, "A" );
assertEquals( lookup, classA );
}
/**
* class A;
*
* class B {
* static void f( A * );
* static void f( int );
* };
*
* A* a1;
*
* class A {};
*
* void B::f( A * ) {}
* void B::f( int ) {}
*
* A* a2;
*
* B::f( a1 );
* B::f( a2 );
*
* @throws Exception
*/
public void testForwardDeclarationUsedAsFunctionParam() throws Exception{
newTable();
ISymbol forwardSymbol = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
forwardSymbol.setIsForwardDeclaration( true );
table.getCompilationUnit().addSymbol( forwardSymbol );
/*...*/
IDerivableContainerSymbol classB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
IParameterizedSymbol fn1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
ISymbol lookup = table.getCompilationUnit().lookup( "A" );
assertEquals( lookup, forwardSymbol );
fn1.addParameter( lookup, new PtrOp( PtrOp.t_pointer ), false );
fn1.getTypeInfo().setBit( true, TypeInfo.isStatic );
classB.addSymbol( fn1 );
IParameterizedSymbol fn2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
fn2.addParameter( TypeInfo.t_int, 0, null, false );
fn2.getTypeInfo().setBit( true, TypeInfo.isStatic );
classB.addSymbol( fn2 );
table.getCompilationUnit().addSymbol( classB );
/*...*/
ISymbol a1 = table.newSymbol( "a1", TypeInfo.t_type );
lookup = table.getCompilationUnit().lookup( "A" );
assertEquals( lookup, forwardSymbol );
a1.setTypeSymbol( lookup );
a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
table.getCompilationUnit().addSymbol( a1 );
/*...*/
lookup = table.getCompilationUnit().lookup( "A" );
IDerivableContainerSymbol classA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
assertTrue( lookup.isForwardDeclaration() );
lookup.setTypeSymbol( classA );
table.getCompilationUnit().addSymbol( classA );
/*..*/
ISymbol a2 = table.newSymbol( "a2", TypeInfo.t_type );
lookup = table.getCompilationUnit().lookup( "A" );
assertEquals( lookup, classA );
a2.setTypeSymbol( lookup );
a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) );
table.getCompilationUnit().addSymbol( a2 );
/*..*/
LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_type, 0, a1 );
paramList.add( p1 );
ISymbol look = classB.memberFunctionLookup( "f", paramList );
assertEquals( look, fn1 );
paramList.clear();
p1 = new TypeInfo( TypeInfo.t_type, 0, a2 );
paramList.add( p1 );
look = classB.memberFunctionLookup( "f", paramList );
assertEquals( look, fn1 );
}
public void testConstructors() throws Exception{
newTable();
IDerivableContainerSymbol classA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IParameterizedSymbol constructor1 = table.newParameterizedSymbol( "A", TypeInfo.t_constructor );
constructor1.addParameter( classA, new PtrOp( PtrOp.t_reference ), false );
IParameterizedSymbol constructor2 = table.newParameterizedSymbol( "A", TypeInfo.t_constructor );
constructor2.addParameter( TypeInfo.t_int, 0, null, false );
IParameterizedSymbol constructor3 = table.newParameterizedSymbol( "A", TypeInfo.t_constructor );
constructor3.addParameter( TypeInfo.t_char, 0, null, false );
classA.addConstructor( constructor1 );
classA.addConstructor( constructor2 );
classA.addConstructor( constructor3 );
assertEquals( classA.getConstructors().size(), 3 );
IParameterizedSymbol cloned = (IParameterizedSymbol) constructor2.clone();
try{
classA.addConstructor( cloned );
} catch ( ParserSymbolTableException e ) {
assertEquals( e.reason, ParserSymbolTableException.r_InvalidOverload );
}
LinkedList paramList = new LinkedList();
paramList.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
ISymbol lookup = classA.lookupConstructor( paramList );
assertEquals( lookup, constructor2 );
}
/**
*
* @throws Exception
*
* namespace A
* {
* int x;
* }
* namespace B = A;
*
* ++B::x;
*/
public void testNamespaceAlias() throws Exception{
newTable();
IContainerSymbol NSA = table.newContainerSymbol( "A", TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( NSA );
ISymbol x = table.newSymbol( "x", TypeInfo.t_int );
NSA.addSymbol( x );
IContainerSymbol NSB = table.newContainerSymbol( "B", TypeInfo.t_namespace );
NSB.setTypeSymbol( NSA ); //alias B to A
table.getCompilationUnit().addSymbol( NSB );
ISymbol lookup = table.getCompilationUnit().lookup( "B" );
assertEquals( lookup, NSB );
lookup = NSB.lookup( "x" );
assertEquals( lookup, x );
}
/**
*
* @throws Exception
* namespace A
* {
* void f( );
* }
* namespace B = A;
*
* B::f();
*
* using namespace B;
* f();
*/
public void testUsingNamespaceAlias() throws Exception{
newTable();
IContainerSymbol NSA = table.newContainerSymbol( "A", TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( NSA );
IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
NSA.addSymbol( f );
IContainerSymbol NSB = table.newContainerSymbol( "B", TypeInfo.t_namespace );
NSB.setTypeSymbol( NSA );
table.getCompilationUnit().addSymbol( NSB );
//look for function that has no parameters
LinkedList paramList = new LinkedList();
ISymbol look = NSB.qualifiedFunctionLookup( "f", paramList );
assertEquals( look, f );
table.getCompilationUnit().addUsingDirective( NSB );
look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f );
}
/**
*
* @throws Exception
*
* The general rule is that when you set a TypeInfo's type to be t_type, you
* should set the type symbol to be something. This is to test that the function
* resolution can handle a bad typeInfo that has a null symbol without throwing a NPE
*/
public void testBadParameterInfo() throws Exception{
newTable();
IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f.setReturnType( table.newSymbol( "", TypeInfo.t_void ) );
IDerivableContainerSymbol a = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( a );
f.addParameter( a, null, false );
table.getCompilationUnit().addSymbol( f );
LinkedList paramList = new LinkedList ();
TypeInfo param = new TypeInfo( TypeInfo.t_type, 0, null );
paramList.add( param );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, null );
ISymbol intermediate = table.newSymbol( "", TypeInfo.t_type );
param.setTypeSymbol( intermediate );
look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", paramList );
assertEquals( look, null );
}
/**
* class A {
* A ( C ) {};
* } a;
* class B : public A {} b;
* class C {
* C ( A ) {};
* } c;
*
* isTrue ? &a : &b; //expect type = 2nd operand ( A )
* isTrue ? &a : &c; //expect null, neither converts
* isTrue ? a : c; //expect exception, both convert
*
* @throws Exception
*/
public void testGetConditionalOperand_bug43106() throws Exception{
newTable();
IDerivableContainerSymbol clsA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol clsB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
clsB.addParent( clsA );
table.getCompilationUnit().addSymbol( clsA );
table.getCompilationUnit().addSymbol( clsB );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( clsA );
ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
b.setTypeSymbol( clsB );
table.getCompilationUnit().addSymbol( a );
table.getCompilationUnit().addSymbol( b );
TypeInfo secondOp = new TypeInfo( TypeInfo.t_type, 0, a );
secondOp.addOperatorExpression( OperatorExpression.addressof );
TypeInfo thirdOp = new TypeInfo( TypeInfo.t_type, 0, b );
thirdOp.addOperatorExpression( OperatorExpression.addressof );
TypeInfo returned = ParserSymbolTable.getConditionalOperand( secondOp, thirdOp );
assertEquals( returned, secondOp );
IDerivableContainerSymbol clsC = table.newDerivableContainerSymbol( "C", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( clsC );
ISymbol c = table.newSymbol( "c", TypeInfo.t_type );
c.setTypeSymbol( clsC );
table.getCompilationUnit().addSymbol( c );
TypeInfo anotherOp = new TypeInfo( TypeInfo.t_type, 0, c );
anotherOp.addOperatorExpression( OperatorExpression.addressof );
returned = ParserSymbolTable.getConditionalOperand( secondOp, anotherOp );
assertEquals( returned, null );
IParameterizedSymbol constructorA = table.newParameterizedSymbol( "A", TypeInfo.t_constructor );
constructorA.addParameter( clsC, null, false );
clsA.addConstructor( constructorA );
IParameterizedSymbol constructorC = table.newParameterizedSymbol( "C", TypeInfo.t_constructor );
constructorC.addParameter( clsA, null, false );
clsC.addConstructor( constructorC );
secondOp.getOperatorExpressions().clear();
anotherOp.getOperatorExpressions().clear();
try{
returned = ParserSymbolTable.getConditionalOperand( secondOp, anotherOp );
assertTrue( false );
} catch ( ParserSymbolTableException e ){
//good
}
}
/**
*
* @throws Exception
* class A {};
* class B : public A {} b;
* class C : private A {} c;
* int f ( A & );
*
* int i = f ( b ); //calls f( A & );
*
* int f ( B & );
* i = f( b ); //now calls f( B& );
*
* i = f( c ); //exception, A is not an accessible base class
*/
public void testDerivedReference() throws Exception{
newTable();
IDerivableContainerSymbol clsA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
IDerivableContainerSymbol clsB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
IDerivableContainerSymbol clsC = table.newDerivableContainerSymbol( "C", TypeInfo.t_class );
clsB.addParent( clsA );
clsC.addParent( clsA, false, ASTAccessVisibility.PRIVATE, 0, null );
ISymbol b = table.newSymbol("b", TypeInfo.t_type );
b.setTypeSymbol( clsB );
ISymbol c = table.newSymbol("c", TypeInfo.t_type );
c.setTypeSymbol( clsC );
table.getCompilationUnit().addSymbol( clsA );
table.getCompilationUnit().addSymbol( clsB );
table.getCompilationUnit().addSymbol( clsC );
table.getCompilationUnit().addSymbol( b );
table.getCompilationUnit().addSymbol( c );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.addParameter( clsA, new PtrOp( PtrOp.t_reference ), false );
table.getCompilationUnit().addSymbol( f1 );
LinkedList parameters = new LinkedList();
TypeInfo param = new TypeInfo( TypeInfo.t_type, 0, b );
parameters.add( param );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", parameters );
assertEquals( look, f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f2.addParameter( clsB, new PtrOp( PtrOp.t_reference ), false );
table.getCompilationUnit().addSymbol( f2 );
look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", parameters );
assertEquals( look, f2 );
parameters.clear();
param = new TypeInfo( TypeInfo.t_type, 0, c );
parameters.add( param );
try{
look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", parameters );
assertTrue( false );
} catch ( ParserSymbolTableException e ){
//good
}
}
/**
*
* @throws Exception
*
* class A {
* private :
* A ( const A & ) {}
* } a;
*
* class B : public A {
* } b;
*
* 1 > 2 ? a : b; //fails, b can't be converted to a without the A( const A & ) copy constructor
* -----------------------
* class A {
* A ( const A & ) {}
* } a;
* class B : public A {} b;
*
* 1 > 2 ? a : b; //succeeds, b can be converted to a using copy constructor
*
*/
public void testAddCopyConstructor() throws Exception {
newTable();
IDerivableContainerSymbol clsA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( clsA );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( clsA );
table.getCompilationUnit().addSymbol( a );
IDerivableContainerSymbol clsB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
clsB.addParent( clsA );
table.getCompilationUnit().addSymbol( clsB );
ISymbol b = table.newSymbol( "b", TypeInfo.t_type );
b.setTypeSymbol( clsB );
table.getCompilationUnit().addSymbol( b );
TypeInfo secondOp = new TypeInfo( TypeInfo.t_type, 0, a, null, false );
TypeInfo thirdOp = new TypeInfo( TypeInfo.t_type, 0, b, null, false );
TypeInfo returned = ParserSymbolTable.getConditionalOperand( secondOp, thirdOp );
assertEquals( returned, null );
clsA.addCopyConstructor();
clsB.addCopyConstructor();
returned = ParserSymbolTable.getConditionalOperand( secondOp, thirdOp );
assertEquals( returned, secondOp );
}
public void testbug43834() throws Exception{
newTable();
IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
table.getCompilationUnit().addSymbol( f );
LinkedList parameters = new LinkedList();
TypeInfo param = new TypeInfo( TypeInfo.t_void, 0, null );
parameters.add( param );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", parameters );
assertEquals( look, f );
f.addParameter( TypeInfo.t_void, 0, null, false );
parameters.clear();
look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", parameters );
assertEquals( look, f );
}
/**
*
* namespace A{
* void f();
* }
* namespace B{
* int f;
* }
* namespace C{
* using namespace A;
* using namespace B;
* using f; //ambiguous, int f or void f()?
* }
*/
public void testBug43503_AmbiguousUsing() throws Exception{
newTable();
IContainerSymbol NSA = table.newContainerSymbol( "A", TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( NSA );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
NSA.addSymbol( f1 );
IContainerSymbol NSB = table.newContainerSymbol( "B", TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( NSB );
ISymbol f2 = table.newSymbol( "f", TypeInfo.t_int );
NSB.addSymbol( f2 );
IContainerSymbol NSC = table.newContainerSymbol( "C", TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( NSC );
NSC.addUsingDirective( NSA );
NSC.addUsingDirective( NSB );
try{
NSC.addUsingDeclaration( "f" );
assertTrue( false );
} catch ( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
}
/**
* void f( void );
* void f( int );
*
* void * pF = &f; //lookup without function parameters, should be ambiguous
* @throws Exception
*/
public void testBug43503_UnableToResolveFunction() throws Exception{
newTable();
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f2.addParameter( TypeInfo.t_int, 0, null, false );
table.getCompilationUnit().addSymbol( f1 );
table.getCompilationUnit().addSymbol( f2 );
try{
table.getCompilationUnit().lookup( "f" );
assertTrue( false );
} catch( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_UnableToResolveFunction );
}
}
/**
* int initialize();
* int initialize(){
* return 3;
* }
*
* int i = initialize();
*
* @throws Exception
*/
public void testBug44510() throws Exception{
newTable();
IParameterizedSymbol init1 = table.newParameterizedSymbol( "initialize", TypeInfo.t_function );
table.getCompilationUnit().addSymbol( init1 );
IParameterizedSymbol init2 = table.newParameterizedSymbol( "initialize", TypeInfo.t_function );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "initialize", new LinkedList() );
assertEquals( look, init1 );
init1.getTypeInfo().setIsForwardDeclaration( true );
init1.setTypeSymbol( init2 );
table.getCompilationUnit().addSymbol( init2 );
look = table.getCompilationUnit().unqualifiedFunctionLookup( "initialize", new LinkedList() );
assertEquals( look, init2 );
}
/**
* class A {
* void f( int ) {}
* void f( ) {}
* };
* class B : public A {
* void f( char ) { }
* } b;
*
* b.f( 1 ); //calls B::f
* b.f(); //error
* @throws Exception
*/
public void testBug46882() throws Exception{
newTable();
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( A );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.addParameter( TypeInfo.t_int, 0, null, false );
A.addSymbol( f1 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
A.addSymbol( f2 );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
B.addParent( A );
table.getCompilationUnit().addSymbol( B );
IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f3.addParameter( TypeInfo.t_char, 0, null, false );
B.addSymbol( f3 );
List params = new LinkedList();
params.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
ISymbol look = B.qualifiedFunctionLookup( "f", params );
assertEquals( look, f3 );
params.clear();
look = B.qualifiedFunctionLookup( "f", params );
assertEquals( look, null );
}
/**
* int aVar;
* void foo( ) {
* int anotherVar;
* a(CTRL+SPACE)
* }
*/
public void testPrefixLookup_Unqualified() throws Exception {
newTable();
ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aVar );
IParameterizedSymbol foo = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
table.getCompilationUnit().addSymbol( foo );
ISymbol anotherVar = table.newSymbol( "anotherVar", TypeInfo.t_int );
foo.addSymbol( anotherVar );
List results = foo.prefixLookup( null, "a", false );
assertTrue( results != null );
assertEquals( results.size(), 2 );
assertTrue( results.contains( aVar ) );
assertTrue( results.contains( anotherVar ) );
}
/**
* int aVar; //not a member of D, not reported
*
* class D{
* int aField;
* void aMethod();
* };
*
* D d;
* d.a(CTRL+SPACE)
*/
public void testPrefixLookup_Qualified() throws Exception {
newTable();
ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aVar );
IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( D );
ISymbol aField = table.newSymbol( "aField", TypeInfo.t_int );
IParameterizedSymbol aMethod = table.newParameterizedSymbol( "aMethod", TypeInfo.t_function );
D.addSymbol( aField );
D.addSymbol( aMethod );
List results = D.prefixLookup( null, "a", true );
assertTrue( results != null );
assertEquals( results.size(), 2 );
assertTrue( !results.contains( aVar ) );
assertTrue( results.contains( aField ) );
assertTrue( results.contains( aMethod ) );
}
/**
* class A {
* int aVar
* int anotherVar; //hidden, not reported
* void af (); //hidden, not reported
* };
*
* class B : public A {
* int anotherVar;
* void af( char );
* } b;
*
* b.a(CTRL+SPACE)
* @throws Exception
*/
public void testPrefixLookup_Inheritance() throws Exception {
newTable();
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( A );
ISymbol aVar = table.newSymbol( "aVar", TypeInfo.t_int );
ISymbol anotherVar1 = table.newSymbol( "anotherVar", TypeInfo.t_int );
A.addSymbol( aVar );
A.addSymbol( anotherVar1 );
IParameterizedSymbol af1 = table.newParameterizedSymbol( "af", TypeInfo.t_function );
A.addSymbol( af1 );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
B.addParent( A );
table.getCompilationUnit().addSymbol( B );
ISymbol anotherVar2 = table.newSymbol( "anotherVar", TypeInfo.t_int );
B.addSymbol( anotherVar2 );
IParameterizedSymbol af2 = table.newParameterizedSymbol( "af", TypeInfo.t_function );
af2.addParameter( TypeInfo.t_char, 0, null, false );
B.addSymbol( af2 );
List results = B.prefixLookup( null, "a", true );
assertTrue( results != null );
assertEquals( results.size(), 3 );
assertTrue( ! results.contains( anotherVar1 ) );
assertTrue( ! results.contains( af1 ) );
assertTrue( results.contains( aVar ) );
assertTrue( results.contains( anotherVar2 ) );
assertTrue( results.contains( af2 ) );
}
/**
* int aa;
* namespace {
* namespace U {
* int a;
* }
* namespace V{
* int a;
* }
* namespace W{
* int a;
* }
*
* void f(){
* using namespace U;
* using namespace V;
* using namespace W;
* a(CTRL+SPACE)
* }
* }
*
* @throws Exception
*/
public void testPrefixLookup_Ambiguities() throws Exception{
newTable();
ISymbol aa = table.newSymbol( "aa", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aa );
IContainerSymbol ns = table.newContainerSymbol( "", TypeInfo.t_namespace );
table.getCompilationUnit().addSymbol( ns );
IContainerSymbol U = table.newContainerSymbol( "U", TypeInfo.t_namespace );
ns.addSymbol( U );
ISymbol a1 = table.newSymbol( "a", TypeInfo.t_int );
U.addSymbol( a1 );
IContainerSymbol V = table.newContainerSymbol( "V", TypeInfo.t_namespace );
ns.addSymbol( V );
ISymbol a2 = table.newSymbol( "a", TypeInfo.t_int );
V.addSymbol( a2 );
IContainerSymbol W = table.newContainerSymbol( "W", TypeInfo.t_namespace );
ns.addSymbol( W );
ISymbol a3 = table.newSymbol( "a", TypeInfo.t_int );
W.addSymbol( a3 );
IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
ns.addSymbol( f );
f.addUsingDirective( U );
f.addUsingDirective( V );
f.addUsingDirective( W );
List results = f.prefixLookup( null, "a", false );
assertTrue( results != null );
assertEquals( results.size(), 1 );
assertTrue( results.contains( aa ) );
}
/**
* int i;
* class A {
* void g(){
* A a;
* a.i++; //fail qualified lookup, no i in A
* i++; //success unqualified lookup
* }
* };
*
* @throws Exception
*/
public void testQualifiedUnqualifiedLookup() throws Exception{
newTable();
ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( i );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( A );
IParameterizedSymbol g = table.newParameterizedSymbol( "g", TypeInfo.t_function );
A.addSymbol( g );
assertEquals( null, A.qualifiedLookup( "i" ) );
assertEquals( i, g.lookup( "i" ) );
}
/**
* class D { };
* class A {
* public: static int i;
* private: static int j;
* friend class D;
* };
* class B : private A {};
* class C : public B, public A {};
*
*
* @throws Exception
*/
public void testVisibilityDetermination() throws Exception{
newTable();
IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( D );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
ISymbol j = table.newSymbol( "j", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( A );
ISymbol friend = A.lookupForFriendship( "D" );
assertEquals( friend, D );
A.addFriend( friend );
A.addSymbol( i );
A.addSymbol( j );
IASTCompilationUnit compUnit = new ASTCompilationUnit(table.getCompilationUnit() );
ISymbolASTExtension cuExtension = new StandardSymbolExtension( table.getCompilationUnit(), (ASTSymbol) compUnit );
table.getCompilationUnit().setASTExtension( cuExtension );
IASTClassSpecifier clsSpec = new ASTClassSpecifier( A, ASTClassKind.CLASS, ClassNameType.IDENTIFIER, ASTAccessVisibility.PUBLIC, 0, 0, 0, new ArrayList( ) );
ISymbolASTExtension clsExtension = new StandardSymbolExtension( A, (ASTSymbol) clsSpec );
A.setASTExtension( clsExtension );
IASTField field = new ASTField(i, null, null, null, 0, 0, 0, new ArrayList(), false, null, ASTAccessVisibility.PUBLIC );
ISymbolASTExtension extension = new StandardSymbolExtension( i, (ASTSymbol) field );
i.setASTExtension( extension );
field = new ASTField(i, null, null, null, 0, 0, 0, new ArrayList(), false, null, ASTAccessVisibility.PRIVATE );
extension = new StandardSymbolExtension( j, (ASTSymbol) field );
j.setASTExtension( extension );
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
B.addParent( A, false, ASTAccessVisibility.PRIVATE, 0, null );
table.getCompilationUnit().addSymbol( B );
IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C", TypeInfo.t_class );
C.addParent( B );
C.addParent( A );
table.getCompilationUnit().addSymbol( C );
assertTrue( table.getCompilationUnit().isVisible( i, A ) );
assertFalse( table.getCompilationUnit().isVisible( i, B ) );
assertTrue( table.getCompilationUnit().isVisible(i, C ) );
assertTrue( D.isVisible( j, A ) );
assertFalse( D.isVisible( j, B ) );
}
/**
* struct a1{};
* void aFoo() {}
* int aa;
* class A2{
* struct a3 {};
* int a3;
* void aF();
* void f() {
* int aLocal;
* A(CTRL+SPACE)
* };
* };
* @throws Exception
*/
public void testPrefixFiltering() throws Exception{
newTable();
IDerivableContainerSymbol a1 = table.newDerivableContainerSymbol( "a1", TypeInfo.t_struct );
table.getCompilationUnit().addSymbol( a1 );
IParameterizedSymbol aFoo = table.newParameterizedSymbol( "aFoo", TypeInfo.t_function );
table.getCompilationUnit().addSymbol( aFoo );
ISymbol aa = table.newSymbol( "aa", TypeInfo.t_int );
table.getCompilationUnit().addSymbol( aa );
IDerivableContainerSymbol A2 = table.newDerivableContainerSymbol( "A2", TypeInfo.t_class );
table.getCompilationUnit().addSymbol( A2 );
IDerivableContainerSymbol a3 = table.newDerivableContainerSymbol( "a3", TypeInfo.t_struct );
A2.addSymbol( a3 );
ISymbol a3_int = table.newSymbol( "a3", TypeInfo.t_int );
A2.addSymbol( a3_int );
IParameterizedSymbol aF = table.newParameterizedSymbol( "aF", TypeInfo.t_function );
A2.addSymbol( aF );
IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
A2.addSymbol( f );
ISymbol aLocal = table.newSymbol( "aLocal", TypeInfo.t_int );
f.addSymbol( aLocal );
List results = f.prefixLookup( new TypeFilter( LookupKind.STRUCTURES ), "A", false );
assertEquals( results.size(), 3 );
assertTrue( results.contains( a1 ) );
assertTrue( results.contains( A2 ) );
assertTrue( results.contains( a3 ) );
results = f.prefixLookup( null, "a", false );
assertEquals( results.size(), 7 );
assertTrue( results.contains( aF ) );
assertTrue( results.contains( A2 ) );
assertTrue( results.contains( a3_int ) );
assertTrue( results.contains( a1 ) );
assertTrue( results.contains( aFoo ) );
assertTrue( results.contains( aa ) );
assertTrue( results.contains( aLocal ) );
results = f.prefixLookup( new TypeFilter( LookupKind.FUNCTIONS ), "a", false );
assertEquals( results.size(), 1 );
assertTrue( results.contains( aFoo ) );
results = f.prefixLookup( new TypeFilter( LookupKind.METHODS ), "a", false );
assertEquals( results.size(), 1 );
assertTrue( results.contains( aF ) );
results = f.prefixLookup( new TypeFilter( LookupKind.LOCAL_VARIABLES ), "a", false );
assertEquals( results.size(), 1 );
assertTrue( results.contains( aLocal ) );
results = f.prefixLookup( new TypeFilter( LookupKind.VARIABLES ), "a", false );
assertEquals( results.size(), 1 );
assertTrue( results.contains( aa ) );
results = f.prefixLookup( new TypeFilter( LookupKind.FIELDS), "a", false );
assertEquals( results.size(), 1 );
assertTrue( results.contains( a3_int ) );
};
/**
* void foo( ... ){ }
*
* foo( 1 );
*
* @throws Exception
*/
public void testBug43110_Ellipses() throws Exception{
newTable();
IParameterizedSymbol foo = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
foo.setHasVariableArgs( true );
table.getCompilationUnit().addSymbol( foo );
List params = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_int, 0, null );
params.add( p1 );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "foo", params );
assertEquals( foo, look );
}
/**
* void foo( ... ) {}; //#1
* void foo( int i ) {}; //#2
*
* foo( 1 ); // calls foo #2
* @throws Exception
*/
public void testBug43110_EllipsesRanking() throws Exception{
newTable();
IParameterizedSymbol foo1 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
foo1.setHasVariableArgs( true );
table.getCompilationUnit().addSymbol( foo1 );
IParameterizedSymbol foo2 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
foo2.addParameter( TypeInfo.t_int, 0, null, false );
table.getCompilationUnit().addSymbol( foo2 );
List params = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_int, 0, null );
params.add( p1 );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "foo", params );
assertEquals( foo2, look );
}
/**
* void foo( int i = 0 ) {}; //#1
* void foo( ... ) {}; //#2
*
* foo(); //calls #1
* @throws Exception
*/
public void testBug43110_ElipsesRanking_2() throws Exception{
newTable();
IParameterizedSymbol foo1 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
foo1.addParameter( TypeInfo.t_int, 0, null, true );
table.getCompilationUnit().addSymbol( foo1 );
IParameterizedSymbol foo2 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
foo2.setHasVariableArgs( true );
table.getCompilationUnit().addSymbol( foo2 );
List params = new LinkedList();
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "foo", params );
assertEquals( foo1, look );
}
}