blob: c68f7b28b3ff0b063aa7b48b7d08c3ff543f33f2 [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:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.ast.complete;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.cdt.core.parser.Enum;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.ITokenDuple;
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.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.ASTPointerOperator;
import org.eclipse.cdt.core.parser.ast.ASTSemanticException;
import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
import org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
import org.eclipse.cdt.core.parser.ast.IASTConstructorMemberInitializer;
import org.eclipse.cdt.core.parser.ast.IASTDesignator;
import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
import org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification;
import org.eclipse.cdt.core.parser.ast.IASTExpression;
import org.eclipse.cdt.core.parser.ast.IASTFactory;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTInitializerClause;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceAlias;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTTemplate;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter;
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
import org.eclipse.cdt.core.parser.ast.IASTTypeId;
import org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType;
import org.eclipse.cdt.core.parser.ast.IASTExpression.IASTNewExpressionDescriptor;
import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type;
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter.ParamKind;
import org.eclipse.cdt.internal.core.parser.ast.BaseASTFactory;
import org.eclipse.cdt.internal.core.parser.pst.ForewardDeclaredSymbolExtension;
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.ISymbolOwner;
import org.eclipse.cdt.internal.core.parser.pst.NamespaceSymbolExtension;
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.TypeInfo;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension.ExtensionException;
/**
* @author jcamelon
*
* The CompleteParseASTFactory class creates a complete AST
* for a given parsed code.
*
*/
public class CompleteParseASTFactory extends BaseASTFactory implements IASTFactory
{
/**
*
*/
private final static List SUBSCRIPT;
static
{
SUBSCRIPT = new ArrayList();
SUBSCRIPT.add( TypeInfo.OperatorExpression.subscript );
}
static private class LookupType extends Enum {
public static final LookupType QUALIFIED = new LookupType( 1 );
public static final LookupType UNQUALIFIED = new LookupType( 2 );
public static final LookupType FORDEFINITION = new LookupType( 3 );
public static final LookupType FORFRIENDSHIP = new LookupType( 4 );
private LookupType( int constant)
{
super( constant );
}
}
public CompleteParseASTFactory( ParserLanguage language )
{
super();
pst = new ParserSymbolTable( language );
}
/*
* Adds a reference to a reference list
* Overrides an existing reference if it has the same name and offset
*/
protected void addReference(List references, IASTReference reference){
if( references == null ) return;
Iterator i = references.iterator();
while (i.hasNext()){
IASTReference ref = (IASTReference)i.next();
if (ref != null){
if( (ref.getName().equals(reference.getName()))
&& (ref.getOffset() == reference.getOffset())
){
i.remove();
break;
}
}
}
references.add(reference);
}
/*
* Test if the provided list is a valid parameter list
* Parameters are list of TypeInfos
*/
protected boolean validParameterList(List parameters){
Iterator i = parameters.iterator();
while (i.hasNext()){
TypeInfo info = (TypeInfo)i.next();
if (info != null){
if((info.getType() == TypeInfo.t_type)
&& (info.getTypeSymbol() == null))
return false;
}else
return false;
}
return true;
}
private ISymbol lookupElement (IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, LookupType lookupType ) throws ParserSymbolTableException{
ISymbol result = null;
try {
if((type == TypeInfo.t_function) || (type == TypeInfo.t_constructor)){
// looking for a function
if(validParameterList(parameters))
if(type == TypeInfo.t_constructor){
IDerivableContainerSymbol startingDerivableScope = (IDerivableContainerSymbol) startingScope;
result = startingDerivableScope.lookupConstructor( new LinkedList(parameters));
}
else {
if( lookupType == LookupType.QUALIFIED )
result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters));
else if( lookupType == LookupType.UNQUALIFIED )
result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) );
else if( lookupType == LookupType.FORDEFINITION )
result = startingScope.lookupMethodForDefinition( name, new LinkedList( parameters ) );
else if( lookupType == LookupType.FORFRIENDSHIP ){
result = ((IDerivableContainerSymbol)startingScope).lookupFunctionForFriendship( name, new LinkedList( parameters) );
}
}
else
result = null;
}else{
// looking for something else
if( lookupType == LookupType.QUALIFIED )
result = startingScope.qualifiedLookup(name, type);
else if( lookupType == LookupType.UNQUALIFIED )
result = startingScope.elaboratedLookup( type, name );
else if( lookupType == LookupType.FORDEFINITION )
result = startingScope.lookupMemberForDefinition( name );
else if( lookupType == LookupType.FORFRIENDSHIP )
result = ((IDerivableContainerSymbol)startingScope).lookupForFriendship( name );
}
} catch (ParserSymbolTableException e) {
if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction )
throw e;
}
return result;
}
protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, String name, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException{
return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, 0, references, throwOnError, lookup );
}
protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, String name, TypeInfo.eType type, List parameters, int offset, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException
{
ISymbol result = null;
try
{
if( name == null ) throw new ASTSemanticException();
try
{
result = lookupElement(startingScope, name, type, parameters, lookup);
if( result != null )
addReference(references, createReference( result, name, offset ));
else
throw new ASTSemanticException();
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
}
catch( ASTSemanticException se )
{
if( throwOnError )
throw se;
return null;
}
return result;
}
protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, List references, boolean throwOnError ) throws ASTSemanticException{
return lookupQualifiedName(startingScope, name, references, throwOnError, LookupType.UNQUALIFIED);
}
protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException{
return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, references, throwOnError, lookup );
}
protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, TypeInfo.eType type, List parameters, List references, boolean throwOnError ) throws ASTSemanticException{
return lookupQualifiedName( startingScope, name, type, parameters, references, throwOnError, LookupType.UNQUALIFIED );
}
protected ISymbol lookupQualifiedName( IContainerSymbol startingScope, ITokenDuple name, TypeInfo.eType type, List parameters, List references, boolean throwOnError, LookupType lookup ) throws ASTSemanticException
{
ISymbol result = null;
IToken firstSymbol = null;
try
{
if( name == null ) throw new ASTSemanticException();
switch( name.length() )
{
case 0:
if( throwOnError )
throw new ASTSemanticException();
case 1:
firstSymbol = name.getFirstToken();
try
{
result = lookupElement(startingScope, firstSymbol.getImage(), type, parameters, lookup );
if( result != null )
addReference( references, createReference( result, firstSymbol.getImage(), firstSymbol.getOffset() ));
else
throw new ASTSemanticException();
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
break;
default:
Iterator iter = name.iterator();
firstSymbol = name.getFirstToken();
result = startingScope;
if( firstSymbol.getType() == IToken.tCOLONCOLON )
result = pst.getCompilationUnit();
while( iter.hasNext() )
{
IToken t = (IToken)iter.next();
if( t.getType() == IToken.tCOLONCOLON ) continue;
if( t.isPointer() ) break;
try
{
if( t == name.getLastToken() )
result = lookupElement((IContainerSymbol)result, t.getImage(), type, parameters, ( lookup == LookupType.FORDEFINITION ) ? lookup : LookupType.QUALIFIED );
else
result = ((IContainerSymbol)result).lookupNestedNameSpecifier( t.getImage() );
addReference( references, createReference( result, t.getImage(), t.getOffset() ));
}
catch( ParserSymbolTableException pste )
{
throw new ASTSemanticException();
}
}
}
}
catch( ASTSemanticException se )
{
if( throwOnError )
throw se;
return null;
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createUsingDirective(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ITokenDuple, int, int)
*/
public IASTUsingDirective createUsingDirective(
IASTScope scope,
ITokenDuple duple,
int startingOffset,
int endingOffset)
throws ASTSemanticException
{
List references = new ArrayList();
ISymbol symbol = lookupQualifiedName(
scopeToSymbol( scope), duple, references, true );
try {
((ASTScope)scope).getContainerSymbol().addUsingDirective( (IContainerSymbol)symbol );
} catch (ParserSymbolTableException pste) {
throw new ASTSemanticException();
}
IASTUsingDirective astUD = new ASTUsingDirective( scopeToSymbol(scope), ((IASTNamespaceDefinition)symbol.getASTExtension().getPrimaryDeclaration()), startingOffset, endingOffset, references );
return astUD;
}
protected IContainerSymbol getScopeToSearchUpon(
IASTScope currentScope,
IToken firstToken, Iterator iterator ) throws ASTSemanticException
{
if( firstToken.getType() == IToken.tCOLONCOLON )
{
iterator.next();
return pst.getCompilationUnit();
}
else
{
return (IContainerSymbol)scopeToSymbol(currentScope);
}
}
protected IContainerSymbol scopeToSymbol(IASTScope currentScope)
{
if( currentScope instanceof ASTScope )
return ((ASTScope)currentScope).getContainerSymbol();
else
return scopeToSymbol(((ASTAnonymousDeclaration)currentScope).getOwnerScope());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createUsingDeclaration(org.eclipse.cdt.core.parser.ast.IASTScope, boolean, org.eclipse.cdt.core.parser.ITokenDuple, int, int)
*/
public IASTUsingDeclaration createUsingDeclaration(
IASTScope scope,
boolean isTypeName,
ITokenDuple name,
int startingOffset,
int endingOffset) throws ASTSemanticException
{
List references = new ArrayList();
ISymbol symbol = lookupQualifiedName( scopeToSymbol(scope), name, references, true );
try
{
scopeToSymbol(scope).addUsingDeclaration( name.getLastToken().getImage(), symbol.getContainingSymbol() );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
return new ASTUsingDeclaration( scope,
symbol.getASTExtension().getPrimaryDeclaration(), isTypeName, startingOffset, endingOffset, references );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createASMDefinition(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, int, int)
*/
public IASTASMDefinition createASMDefinition(
IASTScope scope,
String assembly,
int first,
int last)
{
return new ASTASMDefinition( scopeToSymbol(scope), assembly, first, last );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createNamespaceDefinition(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, int, int)
*/
public IASTNamespaceDefinition createNamespaceDefinition(
IASTScope scope,
String identifier,
int startingOffset,
int nameOffset, int nameEndOffset) throws ASTSemanticException
{
IContainerSymbol pstScope = scopeToSymbol(scope);
ISymbol namespaceSymbol = null;
if( ! identifier.equals( "" ) )
{
try
{
namespaceSymbol = pstScope.qualifiedLookup( identifier );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
}
if( namespaceSymbol != null )
{
if( namespaceSymbol.getType() != TypeInfo.t_namespace )
throw new ASTSemanticException();
}
else
{
namespaceSymbol = pst.newContainerSymbol( identifier, TypeInfo.t_namespace );
if( identifier.equals( "" ) )
namespaceSymbol.setContainingSymbol( pstScope );
else
{
try
{
pstScope.addSymbol( namespaceSymbol );
}
catch (ParserSymbolTableException e1)
{
// not overloading, should never happen
}
}
}
ASTNamespaceDefinition namespaceDef = new ASTNamespaceDefinition( namespaceSymbol, startingOffset, nameOffset, nameEndOffset );
try
{
attachSymbolExtension( namespaceSymbol, namespaceDef );
}
catch (ExtensionException e1)
{
// will not happen with namespaces
}
return namespaceDef;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createCompilationUnit()
*/
public IASTCompilationUnit createCompilationUnit()
{
ISymbol symbol = pst.getCompilationUnit();
ASTCompilationUnit compilationUnit = new ASTCompilationUnit( symbol );
try
{
attachSymbolExtension(symbol, compilationUnit );
}
catch (ExtensionException e)
{
//should not happen with CompilationUnit
}
return compilationUnit;
}
protected void attachSymbolExtension(
ISymbol symbol,
ASTSymbol astSymbol ) throws ExtensionException
{
ISymbolASTExtension extension = symbol.getASTExtension();
if( extension == null )
{
if( astSymbol instanceof IASTNamespaceDefinition ||
astSymbol instanceof IASTEnumerationSpecifier ||
astSymbol instanceof IASTClassSpecifier ||
astSymbol instanceof IASTElaboratedTypeSpecifier )
extension = new NamespaceSymbolExtension( symbol, astSymbol );
else if( astSymbol instanceof IASTFunction || astSymbol instanceof IASTMethod )
{
extension = new ForewardDeclaredSymbolExtension( symbol, astSymbol );
}
else
{
extension = new StandardSymbolExtension( symbol, astSymbol );
}
symbol.setASTExtension( extension );
}
else
{
extension.addDefinition( astSymbol );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createLinkageSpecification(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, int)
*/
public IASTLinkageSpecification createLinkageSpecification(
IASTScope scope,
String spec,
int startingOffset)
{
return new ASTLinkageSpecification( scopeToSymbol( scope ), spec, startingOffset );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createClassSpecifier(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, org.eclipse.cdt.core.parser.ast.ASTClassKind, org.eclipse.cdt.core.parser.ast.IASTClassSpecifier.ClassNameType, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility, org.eclipse.cdt.core.parser.ast.IASTTemplate, int, int)
*/
public IASTClassSpecifier createClassSpecifier(
IASTScope scope,
ITokenDuple name,
ASTClassKind kind,
ClassNameType type,
ASTAccessVisibility access,
int startingOffset,
int nameOffset, int nameEndOffset) throws ASTSemanticException
{
IContainerSymbol currentScopeSymbol = scopeToSymbol(scope);
TypeInfo.eType pstType = classKindToTypeInfo(kind);
List references = new ArrayList();
String newSymbolName = "";
if( name != null ){
IToken lastToken = name.getLastToken();
if( name.length() != 1 ) // qualified name
{
ITokenDuple containerSymbolName =
name.getSubrange( 0, name.length() - 3 ); // -1 for index, -2 for last hop of qualified name
currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol,
containerSymbolName, references, true);
if( currentScopeSymbol == null )
throw new ASTSemanticException();
}
newSymbolName = lastToken.getImage();
}
ISymbol classSymbol = null;
if( !newSymbolName.equals("") ){
try
{
classSymbol = currentScopeSymbol.lookupMemberForDefinition(newSymbolName);
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
if( classSymbol != null && ! classSymbol.isForwardDeclaration() )
throw new ASTSemanticException();
if( classSymbol != null && classSymbol.getType() != pstType )
throw new ASTSemanticException();
}
IDerivableContainerSymbol newSymbol = pst.newDerivableContainerSymbol( newSymbolName, pstType );
if( classSymbol != null )
classSymbol.setTypeSymbol( newSymbol );
try
{
currentScopeSymbol.addSymbol( newSymbol );
}
catch (ParserSymbolTableException e2)
{
throw new ASTSemanticException();
}
ASTClassSpecifier classSpecifier = new ASTClassSpecifier( newSymbol, kind, type, access, startingOffset, nameOffset, nameEndOffset, references );
try
{
attachSymbolExtension(newSymbol, classSpecifier );
}
catch (ExtensionException e1)
{
throw new ASTSemanticException();
}
return classSpecifier;
}
protected TypeInfo.eType classKindToTypeInfo(ASTClassKind kind)
throws ASTSemanticException
{
TypeInfo.eType pstType = null;
if( kind == ASTClassKind.CLASS )
pstType = TypeInfo.t_class;
else if( kind == ASTClassKind.STRUCT )
pstType = TypeInfo.t_struct;
else if( kind == ASTClassKind.UNION )
pstType = TypeInfo.t_union;
else if( kind == ASTClassKind.ENUM )
pstType = TypeInfo.t_enumeration;
else
throw new ASTSemanticException();
return pstType;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#addBaseSpecifier(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility, java.lang.String)
*/
public void addBaseSpecifier(
IASTClassSpecifier astClassSpec,
boolean isVirtual,
ASTAccessVisibility visibility,
ITokenDuple parentClassName) throws ASTSemanticException
{
IDerivableContainerSymbol classSymbol = (IDerivableContainerSymbol)scopeToSymbol( astClassSpec);
Iterator iterator = parentClassName.iterator();
List references = new ArrayList();
if( ! iterator.hasNext() )
throw new ASTSemanticException();
IContainerSymbol symbol = null;
symbol = getScopeToSearchUpon(astClassSpec, (IToken)parentClassName.getFirstToken(), iterator );
while( iterator.hasNext() )
{
IToken t = (IToken)iterator.next();
if( t.getType() == IToken.tCOLONCOLON ) continue;
try
{
if( t == parentClassName.getLastToken())
symbol = (IContainerSymbol)symbol.lookup( t.getImage() );
else
symbol = symbol.lookupNestedNameSpecifier( t.getImage() );
if( symbol != null )
addReference( references, createReference( symbol, t.getImage(), t.getOffset() ));
else
throw new ASTSemanticException();
}
catch( ParserSymbolTableException pste )
{
throw new ASTSemanticException();
}
}
classSymbol.addParent( symbol, isVirtual, visibility, parentClassName.getFirstToken().getOffset(), references );
}
/**
* @param symbol
* @param string
* @return
*/
protected IASTReference createReference(ISymbol symbol, String string, int offset ) throws ASTSemanticException
{
if( symbol == null )
throw new ASTSemanticException();
if( symbol.getType() == TypeInfo.t_namespace )
{
return new ASTNamespaceReference( offset, string, (IASTNamespaceDefinition)symbol.getASTExtension().getPrimaryDeclaration());
}
else if( symbol.getType() == TypeInfo.t_class ||
symbol.getType() == TypeInfo.t_struct ||
symbol.getType() == TypeInfo.t_union )
{
return new ASTClassReference( offset, string, (IASTTypeSpecifier)symbol.getASTExtension().getPrimaryDeclaration() );
}
else if( symbol.getTypeInfo().checkBit( TypeInfo.isTypedef ))
{
return new ASTTypedefReference( offset, string, (IASTTypedefDeclaration)symbol.getASTExtension().getPrimaryDeclaration());
}
else if( symbol.getType() == TypeInfo.t_enumeration )
return new ASTEnumerationReference( offset, string, (IASTEnumerationSpecifier)symbol.getASTExtension().getPrimaryDeclaration() );
else if( symbol.getType() == TypeInfo.t_enumerator )
return new ASTEnumeratorReference( offset, string, (IASTEnumerator)symbol.getASTExtension().getPrimaryDeclaration() );
else if(( symbol.getType() == TypeInfo.t_function ) || (symbol.getType() == TypeInfo.t_constructor))
{
if( symbol.getContainingSymbol().getTypeInfo().isType( TypeInfo.t_class, TypeInfo.t_union ) )
return new ASTMethodReference( offset, string, (IASTMethod)symbol.getASTExtension().getPrimaryDeclaration() );
else
return new ASTFunctionReference( offset, string, (IASTFunction)symbol.getASTExtension().getPrimaryDeclaration() );
}
else if( ( symbol.getType() == TypeInfo.t_type ) ||
( symbol.getType() == TypeInfo.t_bool )||
( symbol.getType() == TypeInfo.t_char ) ||
( symbol.getType() == TypeInfo.t_wchar_t )||
( symbol.getType() == TypeInfo.t_int ) ||
( symbol.getType() == TypeInfo.t_float )||
( symbol.getType() == TypeInfo.t_double ) ||
( symbol.getType() == TypeInfo.t_void ) )
{
if( symbol.getContainingSymbol().getType() == TypeInfo.t_class ||
symbol.getContainingSymbol().getType() == TypeInfo.t_struct ||
symbol.getContainingSymbol().getType() == TypeInfo.t_union )
{
return new ASTFieldReference( offset, string, (IASTField)symbol.getASTExtension().getPrimaryDeclaration());
}
else if( ( symbol.getContainingSymbol().getType() == TypeInfo.t_function ||
symbol.getContainingSymbol().getType() == TypeInfo.t_constructor ) &&
symbol.getContainingSymbol() instanceof IParameterizedSymbol &&
((IParameterizedSymbol)symbol.getContainingSymbol()).getParameterList() != null &&
((IParameterizedSymbol)symbol.getContainingSymbol()).getParameterList().contains( symbol ) )
{
return new ASTParameterReference( offset, string, (IASTParameterDeclaration)symbol.getASTExtension().getPrimaryDeclaration() );
}
else
{
ASTSymbol s = symbol.getASTExtension().getPrimaryDeclaration();
if(s instanceof IASTVariable)
return new ASTVariableReference( offset, string, (IASTVariable)s);
else if (s instanceof IASTParameterDeclaration)
return new ASTParameterReference( offset, string, (IASTParameterDeclaration)s);
}
}
throw new ASTSemanticException();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createEnumerationSpecifier(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, int, int)
*/
public IASTEnumerationSpecifier createEnumerationSpecifier(
IASTScope scope,
String name,
int startingOffset,
int nameOffset, int nameEndOffset) throws ASTSemanticException
{
IContainerSymbol containerSymbol = scopeToSymbol(scope);
TypeInfo.eType pstType = TypeInfo.t_enumeration;
IDerivableContainerSymbol classSymbol = pst.newDerivableContainerSymbol( name, pstType );
try
{
containerSymbol.addSymbol( classSymbol );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
ASTEnumerationSpecifier enumSpecifier = new ASTEnumerationSpecifier( classSymbol, startingOffset, nameOffset, nameEndOffset );
try
{
attachSymbolExtension(classSymbol, enumSpecifier );
}
catch (ExtensionException e1)
{
throw new ASTSemanticException();
}
return enumSpecifier;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#addEnumerator(org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier, java.lang.String, int, int, org.eclipse.cdt.core.parser.ast.IASTExpression)
*/
public void addEnumerator(
IASTEnumerationSpecifier enumeration,
String string,
int startingOffset,
int nameOffset,
int nameEndOffset, int endingOffset, IASTExpression initialValue) throws ASTSemanticException
{
IContainerSymbol enumerationSymbol = (IContainerSymbol)((ISymbolOwner)enumeration).getSymbol();
ISymbol enumeratorSymbol = pst.newSymbol( string, TypeInfo.t_enumerator );
try
{
enumerationSymbol.addSymbol( enumeratorSymbol );
}
catch (ParserSymbolTableException e1)
{
throw new ASTSemanticException();
}
ASTEnumerator enumerator = new ASTEnumerator( enumeratorSymbol, enumeration, startingOffset, nameOffset, nameEndOffset, endingOffset, initialValue );
((ASTEnumerationSpecifier)enumeration).addEnumerator( enumerator );
try
{
attachSymbolExtension( enumeratorSymbol, enumerator );
}
catch (ExtensionException e)
{
throw new ASTSemanticException();
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createExpression(org.eclipse.cdt.core.parser.ast.IASTExpression.Kind, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTExpression, java.lang.String, java.lang.String, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTExpression.IASTNewExpressionDescriptor)
*/
public IASTExpression createExpression(
IASTScope scope,
Kind kind,
IASTExpression lhs,
IASTExpression rhs,
IASTExpression thirdExpression,
IASTTypeId typeId,
ITokenDuple idExpression, String literal, IASTNewExpressionDescriptor newDescriptor) throws ASTSemanticException
{
try{
List references = new ArrayList();
ISymbol symbol = getExpressionSymbol(scope, kind, lhs, rhs, idExpression, references );
// Try to figure out the result that this expression evaluates to
ExpressionResult expressionResult = getExpressionResultType(kind, lhs, rhs, thirdExpression, typeId, literal, symbol);
// expression results could be empty, but should not be null
if(expressionResult == null)
throw new ASTSemanticException();
// create the ASTExpression
ASTExpression expression = new ASTExpression( kind, lhs, rhs, thirdExpression,
typeId, idExpression, literal, newDescriptor, references);
// Assign the result to the created expression
expression.setResultType (expressionResult);
return expression;
}catch (ASTSemanticException e){
throw e;
}
}
/*
* Try and dereference the symbol in the expression
*/
private ISymbol getExpressionSymbol(
IASTScope scope,
Kind kind,
IASTExpression lhs,
IASTExpression rhs,
ITokenDuple idExpression,
List references )throws ASTSemanticException
{
ISymbol symbol = null;
IContainerSymbol startingScope = scopeToSymbol( scope );
//If the expression has an id, look up id and add it to references
if( idExpression != null )
symbol = lookupQualifiedName( startingScope, idExpression, references, false );
// If the expression is lookup symbol if it is in the scope of a type after a "." or an "->"
IContainerSymbol searchScope = getSearchScope(kind, lhs, startingScope);
if (!searchScope.equals(startingScope))
symbol = lookupQualifiedName(searchScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false, LookupType.QUALIFIED );
// get symbol if it is the "this" pointer
// go up the scope until you hit a class
if (kind == IASTExpression.Kind.PRIMARY_THIS){
try{
symbol = startingScope.lookup("this");
}catch (ParserSymbolTableException e){
throw new ASTSemanticException();
}
}
// lookup symbol if it is a function call
if (kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
ITokenDuple functionId = getFunctionId(lhs);
IContainerSymbol functionScope = getSearchScope(lhs.getExpressionKind(), lhs.getLHSExpression(), startingScope);
ExpressionResult expResult = ((ASTExpression)rhs).getResultType();
List parameters = null;
if(expResult instanceof ExpressionResultList){
ExpressionResultList expResultList = (ExpressionResultList) expResult;
parameters = expResultList.getResultList();
}else {
parameters = new ArrayList();
parameters.add(expResult.getResult());
}
if( functionScope.equals( startingScope ) )
symbol = lookupQualifiedName(functionScope, functionId, TypeInfo.t_function, parameters, references, false);
else
symbol = lookupQualifiedName(functionScope, functionId, TypeInfo.t_function, parameters, references, false, LookupType.QUALIFIED );
}
return symbol;
}
/*
* Returns the function ID token
*/
private ITokenDuple getFunctionId (IASTExpression expression){
if((expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
|| (expression.getExpressionKind() == IASTExpression.Kind.PM_DOTSTAR)
|| (expression.getExpressionKind() == IASTExpression.Kind.PM_ARROWSTAR)
){
return ((ASTExpression)expression.getRHSExpression()).getIdExpressionTokenDuple();
}
else {
return ((ASTExpression)expression).getIdExpressionTokenDuple();
}
}
private IContainerSymbol getSearchScope (Kind kind, IASTExpression lhs, IContainerSymbol startingScope) throws ASTSemanticException{
if((kind == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
|| (kind == IASTExpression.Kind.PM_DOTSTAR)
|| (kind == IASTExpression.Kind.PM_ARROWSTAR)
){
TypeInfo lhsInfo = (TypeInfo) ((ASTExpression)lhs).getResultType().getResult();
if(lhsInfo != null){
ISymbol firstContainingScope = (ISymbol) lhsInfo.getTypeSymbol();
if(firstContainingScope != null){
ISymbol containingScope = firstContainingScope.getTypeSymbol();
if(containingScope != null){
return (IContainerSymbol)containingScope;
} else {
throw new ASTSemanticException();
}
} else {
throw new ASTSemanticException();
}
} else {
throw new ASTSemanticException();
}
}
else {
return startingScope;
}
}
/*
* Conditional Expression conversion
*/
protected TypeInfo conditionalExpressionConversions(TypeInfo second, TypeInfo third){
TypeInfo info = new TypeInfo();
if(second.equals(third)){
info = second;
return info;
}
if((second.getType() == TypeInfo.t_void) && (third.getType() != TypeInfo.t_void)){
info = third;
return info;
}
if((second.getType() != TypeInfo.t_void) && (third.getType() == TypeInfo.t_void)){
info = second;
return info;
}
if((second.getType() == TypeInfo.t_void) && (third.getType() == TypeInfo.t_void)){
info = second;
return info;
}
try{
info = ParserSymbolTable.getConditionalOperand(second, third);
return info;
} catch(ParserSymbolTableException e){
// empty info
return info;
}
}
/*
* Apply the usual arithmetic conversions to find out the result of an expression
* that has a lhs and a rhs as indicated in the specs (section 5.Expressions, page 64)
*/
protected TypeInfo usualArithmeticConversions(TypeInfo lhs, TypeInfo rhs) throws ASTSemanticException{
// if you have a variable of type basic type, then we need to go to the basic type first
while( (lhs.getType() == TypeInfo.t_type) && (lhs.getTypeSymbol() != null)){
lhs = lhs.getTypeSymbol().getTypeInfo();
}
while( (rhs.getType() == TypeInfo.t_type) && (rhs.getTypeSymbol() != null)){
rhs = rhs.getTypeSymbol().getTypeInfo();
}
if( !lhs.isType(TypeInfo.t_bool, TypeInfo.t_enumerator ) &&
!rhs.isType(TypeInfo.t_bool, TypeInfo.t_enumerator ) )
{
throw new ASTSemanticException();
}
TypeInfo info = new TypeInfo();
if(
( lhs.checkBit(TypeInfo.isLong) && lhs.getType() == TypeInfo.t_double)
|| ( rhs.checkBit(TypeInfo.isLong) && rhs.getType() == TypeInfo.t_double)
){
info.setType(TypeInfo.t_double);
info.setBit(true, TypeInfo.isLong);
return info;
}
else if(
( lhs.getType() == TypeInfo.t_double )
|| ( rhs.getType() == TypeInfo.t_double )
){
info.setType(TypeInfo.t_double);
return info;
}
else if (
( lhs.getType() == TypeInfo.t_float )
|| ( rhs.getType() == TypeInfo.t_float )
){
info.setType(TypeInfo.t_float);
return info;
} else {
// perform intergral promotions (Specs section 4.5)
info.setType(TypeInfo.t_int);
}
if(
( lhs.checkBit(TypeInfo.isUnsigned) && lhs.checkBit(TypeInfo.isLong))
|| ( rhs.checkBit(TypeInfo.isUnsigned) && rhs.checkBit(TypeInfo.isLong))
){
info.setBit(true, TypeInfo.isUnsigned);
info.setBit(true, TypeInfo.isLong);
return info;
}
else if(
( lhs.checkBit(TypeInfo.isUnsigned) && rhs.checkBit(TypeInfo.isLong) )
|| ( rhs.checkBit(TypeInfo.isUnsigned) && lhs.checkBit(TypeInfo.isLong) )
){
info.setBit(true, TypeInfo.isUnsigned);
info.setBit(true, TypeInfo.isLong);
return info;
}
else if (
( lhs.checkBit(TypeInfo.isLong))
|| ( rhs.checkBit(TypeInfo.isLong))
){
info.setBit(true, TypeInfo.isLong);
return info;
}
else if (
( lhs.checkBit(TypeInfo.isUnsigned) )
|| ( rhs.checkBit(TypeInfo.isUnsigned) )
){
info.setBit(true, TypeInfo.isUnsigned);
return info;
} else {
// it should be both = int
return info;
}
}
private TypeInfo addToInfo(ASTExpression exp, boolean flag, int mask)
throws ASTSemanticException{
if(exp == null)
throw new ASTSemanticException();
TypeInfo info = (TypeInfo)((ASTExpression)exp).getResultType().getResult();
info.setBit(flag, mask);
return info;
}
protected ExpressionResult getExpressionResultType(
Kind kind,
IASTExpression lhs,
IASTExpression rhs,
IASTExpression thirdExpression,
IASTTypeId typeId,
String literal,
ISymbol symbol)
throws ASTSemanticException{
ExpressionResult result = null;
TypeInfo info = new TypeInfo();
try {
// types that resolve to void
if ((kind == IASTExpression.Kind.PRIMARY_EMPTY)
|| (kind == IASTExpression.Kind.THROWEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_DESTRUCTOR)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_DESTRUCTOR)
|| (kind == IASTExpression.Kind.DELETE_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION)
){
info.setType(TypeInfo.t_void);
result = new ExpressionResult(info);
return result;
}
// types that resolve to int
if ((kind == IASTExpression.Kind.PRIMARY_INTEGER_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT)
){
info.setType(TypeInfo.t_int);
result = new ExpressionResult(info);
return result;
}
// size of is always unsigned int
if ((kind == IASTExpression.Kind.UNARY_SIZEOF_TYPEID)
|| (kind == IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION)
){
info.setType(TypeInfo.t_int);
info.setBit(true, TypeInfo.isUnsigned);
result = new ExpressionResult(info);
return result;
}
// types that resolve to char
if( (kind == IASTExpression.Kind.PRIMARY_CHAR_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR)){
info.setType(TypeInfo.t_char);
// check that this is really only one literal
if(literal.length() > 1){
// this is a string
info.addPtrOperator(new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
}
result = new ExpressionResult(info);
return result;
}
// types that resolve to string
if (kind == IASTExpression.Kind.PRIMARY_STRING_LITERAL){
info.setType(TypeInfo.t_char);
info.addPtrOperator(new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
result = new ExpressionResult(info);
return result;
}
// types that resolve to float
if( (kind == IASTExpression.Kind.PRIMARY_FLOAT_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT)){
info.setType(TypeInfo.t_float);
result = new ExpressionResult(info);
return result;
}
// types that resolve to double
if( kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE){
info.setType(TypeInfo.t_double);
result = new ExpressionResult(info);
return result;
}
// types that resolve to wchar
if(kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART){
info.setType(TypeInfo.t_wchar_t);
result = new ExpressionResult(info);
return result;
}
// types that resolve to bool
if( (kind == IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL)
|| (kind == IASTExpression.Kind.RELATIONAL_GREATERTHAN)
|| (kind == IASTExpression.Kind.RELATIONAL_GREATERTHANEQUALTO)
|| (kind == IASTExpression.Kind.RELATIONAL_LESSTHAN)
|| (kind == IASTExpression.Kind.RELATIONAL_LESSTHANEQUALTO)
|| (kind == IASTExpression.Kind.EQUALITY_EQUALS)
|| (kind == IASTExpression.Kind.EQUALITY_NOTEQUALS)
|| (kind == IASTExpression.Kind.LOGICALANDEXPRESSION)
|| (kind == IASTExpression.Kind.LOGICALOREXPRESSION)
)
{
info.setType(TypeInfo.t_bool);
result = new ExpressionResult(info);
return result;
}
// short added to a type
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT ){
info = addToInfo((ASTExpression)lhs, true, TypeInfo.isShort);
result = new ExpressionResult(info);
return result;
}
// long added to a type
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG ){
info = addToInfo((ASTExpression)lhs, true, TypeInfo.isLong);
result = new ExpressionResult(info);
return result;
}
// signed added to a type
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED ){
info = addToInfo((ASTExpression)lhs, false, TypeInfo.isUnsigned);
result = new ExpressionResult(info);
return result;
}
// unsigned added to a type
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED ){
info = addToInfo((ASTExpression)lhs, true, TypeInfo.isUnsigned);
result = new ExpressionResult(info);
return result;
}
// Id expressions resolve to t_type, symbol already looked up
if( kind == IASTExpression.Kind.ID_EXPRESSION )
{
info.setType(TypeInfo.t_type);
info.setTypeSymbol(symbol);
result = new ExpressionResult(info);
if (symbol == null)
result.setFailedToDereference(true);
return result;
}
// an ampersand implies a pointer operation of type reference
if (kind == IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION){
ASTExpression left =(ASTExpression)lhs;
if(left == null)
throw new ASTSemanticException();
info = (TypeInfo)left.getResultType().getResult();
if ((info != null) && (info.getTypeSymbol() != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// a star implies a pointer operation of type pointer
if (kind == IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION){
ASTExpression left =(ASTExpression)lhs;
if(left == null)
throw new ASTSemanticException();
info = (TypeInfo)left.getResultType().getResult();
if ((info != null)&& (info.getTypeSymbol() != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.indirection );
}else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// subscript
if (kind == IASTExpression.Kind.POSTFIX_SUBSCRIPT){
ASTExpression left =(ASTExpression)lhs;
if(left == null)
throw new ASTSemanticException();
info = (TypeInfo)left.getResultType().getResult();
if ((info != null) && (info.getTypeSymbol() != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.subscript );
}else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// the dot and the arrow resolves to the type of the member
if ((kind == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
){
if(symbol != null){
info = new TypeInfo(symbol.getTypeInfo());
}
// else {
// throw new ASTSemanticException();
// }
result = new ExpressionResult(info);
return result;
}
// the dot* and the arrow* are the same as dot/arrow + unary star
if ((kind == IASTExpression.Kind.PM_DOTSTAR)
|| (kind == IASTExpression.Kind.PM_ARROWSTAR)
){
ASTExpression right =(ASTExpression)rhs;
if (right == null)
throw new ASTSemanticException();
info = (TypeInfo)right.getResultType().getResult();
if ((info != null) && (symbol != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.indirection );
info.setTypeSymbol(symbol);
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// this
if (kind == IASTExpression.Kind.PRIMARY_THIS){
if(symbol != null)
{
info.setType(TypeInfo.t_type);
info.setTypeSymbol(symbol);
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// conditional
if (kind == IASTExpression.Kind.CONDITIONALEXPRESSION){
ASTExpression right = (ASTExpression)rhs;
ASTExpression third = (ASTExpression)thirdExpression;
if((right != null ) && (third != null)){
TypeInfo rightType =(TypeInfo)right.getResultType().getResult();
TypeInfo thirdType =(TypeInfo)third.getResultType().getResult();
if((rightType != null) && (thirdType != null)){
info = conditionalExpressionConversions(rightType, thirdType);
} else {
throw new ASTSemanticException();
}
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// new
if( ( kind == IASTExpression.Kind.NEW_TYPEID )
|| ( kind == IASTExpression.Kind.NEW_NEWTYPEID ) )
{
try
{
info = typeId.getTypeSymbol().getTypeInfo();
info.addPtrOperator( new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
}
catch (ASTNotImplementedException e)
{
// will never happen
}
result = new ExpressionResult(info);
return result;
}
// types that use the usual arithmetic conversions
if((kind == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY)
|| (kind == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE)
|| (kind == IASTExpression.Kind.MULTIPLICATIVE_MODULUS)
|| (kind == IASTExpression.Kind.ADDITIVE_PLUS)
|| (kind == IASTExpression.Kind.ADDITIVE_MINUS)
|| (kind == IASTExpression.Kind.ANDEXPRESSION)
|| (kind == IASTExpression.Kind.EXCLUSIVEOREXPRESSION)
|| (kind == IASTExpression.Kind.INCLUSIVEOREXPRESSION)
){
ASTExpression left = (ASTExpression)lhs;
ASTExpression right = (ASTExpression)rhs;
if((left != null ) && (right != null)){
TypeInfo leftType =(TypeInfo)left.getResultType().getResult();
TypeInfo rightType =(TypeInfo)right.getResultType().getResult();
info = usualArithmeticConversions(leftType, rightType);
}
else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// types that resolve to LHS types
if ((kind == IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_INCREMENT)
|| (kind == IASTExpression.Kind.POSTFIX_DECREMENT)
|| (kind == IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_INCREMENT)
|| (kind == IASTExpression.Kind.UNARY_DECREMENT)
|| (kind == IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.SHIFT_LEFT)
|| (kind == IASTExpression.Kind.SHIFT_RIGHT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR)
){
ASTExpression left = (ASTExpression)lhs;
if(left != null){
info =(TypeInfo)left.getResultType().getResult();
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// the cast changes the types to the type looked up in typeId = symbol
if(( kind == IASTExpression.Kind.CASTEXPRESSION )
|| ( kind == IASTExpression.Kind.POSTFIX_DYNAMIC_CAST )
|| ( kind == IASTExpression.Kind.POSTFIX_STATIC_CAST )
|| ( kind == IASTExpression.Kind.POSTFIX_REINTERPRET_CAST )
|| ( kind == IASTExpression.Kind.POSTFIX_CONST_CAST )
){
try{
info = new TypeInfo(typeId.getTypeSymbol().getTypeInfo());
}catch (ASTNotImplementedException e)
{
// will never happen
}
result = new ExpressionResult(info);
return result;
}
// a list collects all types of left and right hand sides
if(kind == IASTExpression.Kind.EXPRESSIONLIST){
result = new ExpressionResultList();
if(lhs != null){
TypeInfo leftType = ((ASTExpression)lhs).getResultType().getResult();
result.setResult(leftType);
}
if(rhs != null){
TypeInfo rightType = ((ASTExpression)rhs).getResultType().getResult();
result.setResult(rightType);
}
return result;
}
// a function call type is the return type of the function
if(kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
if(symbol != null){
IParameterizedSymbol psymbol = (IParameterizedSymbol) symbol;
ISymbol returnTypeSymbol = psymbol.getReturnType();
if(returnTypeSymbol != null){
info.setType(returnTypeSymbol.getType());
info.setTypeSymbol(returnTypeSymbol);
}else {
// this is call to a constructor
}
}
result = new ExpressionResult(info);
if(symbol == null)
result.setFailedToDereference(true);
return result;
}
// typeid
if( kind == IASTExpression.Kind.POSTFIX_TYPEID_TYPEID )
{
try
{
info = typeId.getTypeSymbol().getTypeInfo();
}
catch (ASTNotImplementedException e)
{
// will not ever happen from within CompleteParseASTFactory
}
result = new ExpressionResult(info);
return result;
}
// typename
if ( ( kind == IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER )
|| ( kind == IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID ) )
{
if(symbol != null){
info.setType(TypeInfo.t_type);
info.setTypeSymbol(symbol);
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
} catch (Exception e){
throw new ASTSemanticException();
}
return null;
}
protected void getExpressionReferences(IASTExpression expression, List references)
{
if( expression != null )
{
references.addAll( ((ASTExpression)expression).getReferences() );
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createNewDescriptor()
*/
public IASTNewExpressionDescriptor createNewDescriptor(List newPlacementExpressions,List newTypeIdExpressions,List newInitializerExpressions)
{
return new ASTNewDescriptor(newPlacementExpressions, newTypeIdExpressions, newInitializerExpressions);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createExceptionSpecification(java.util.List)
*/
public IASTExceptionSpecification createExceptionSpecification(IASTScope scope, List typeIds) throws ASTSemanticException
{
List references = new ArrayList();
List newTypeIds = new ArrayList();
if( typeIds != null )
{
Iterator iter =typeIds.iterator();
while( iter.hasNext() )
{
IASTTypeId duple = (IASTTypeId)iter.next();
if( duple != null )
{
lookupQualifiedName( scopeToSymbol( scope ), ((ASTTypeId)duple).getTokenDuple(), references, false );
newTypeIds.add( duple.toString() );
}
}
}
return new ASTExceptionSpecification( newTypeIds, references );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createConstructorMemberInitializer(org.eclipse.cdt.core.parser.ITokenDuple, org.eclipse.cdt.core.parser.ast.IASTExpression)
*/
public IASTConstructorMemberInitializer createConstructorMemberInitializer(
IASTScope scope,
ITokenDuple duple, IASTExpression expressionList) throws ASTSemanticException
{
List references = new ArrayList();
IContainerSymbol scopeSymbol = scopeToSymbol(scope);
boolean requireReferenceResolution = false;
if( duple != null )
{
try
{
lookupQualifiedName( scopeSymbol, duple, references, true );
} catch( ASTSemanticException ase )
{
requireReferenceResolution = true;
}
}
getExpressionReferences( expressionList, references );
return new ASTConstructorMemberInitializer(
expressionList,
duple == null ? "" : duple.toString(),
duple == null ? 0 : duple.getFirstToken().getOffset(),
references, requireReferenceResolution );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createSimpleTypeSpecifier(org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type, org.eclipse.cdt.core.parser.ITokenDuple, boolean, boolean, boolean, boolean, boolean)
*/
public IASTSimpleTypeSpecifier createSimpleTypeSpecifier(
IASTScope scope,
Type kind,
ITokenDuple typeName,
boolean isShort,
boolean isLong,
boolean isSigned,
boolean isUnsigned, boolean isTypename, boolean isComplex, boolean isImaginary) throws ASTSemanticException
{
TypeInfo.eType type = null;
if( kind == IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME )
type = TypeInfo.t_type;
else if( kind == IASTSimpleTypeSpecifier.Type.BOOL )
type = TypeInfo.t_bool;
else if( kind == IASTSimpleTypeSpecifier.Type.CHAR )
type = TypeInfo.t_char;
else if( kind == IASTSimpleTypeSpecifier.Type.DOUBLE ||kind == IASTSimpleTypeSpecifier.Type.FLOAT )
type = TypeInfo.t_double;
else if( kind == IASTSimpleTypeSpecifier.Type.INT )
type = TypeInfo.t_int;
else if( kind == IASTSimpleTypeSpecifier.Type.VOID )
type = TypeInfo.t_void;
else if( kind == IASTSimpleTypeSpecifier.Type.WCHAR_T)
type = TypeInfo.t_wchar_t;
else if( kind == IASTSimpleTypeSpecifier.Type._BOOL )
type = TypeInfo.t__Bool;
List references = new ArrayList();
ISymbol s = pst.newSymbol( "", type );
if( kind == IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME )
{
// lookup the duple
Iterator i = typeName.iterator();
IToken first = typeName.getFirstToken();
ISymbol typeSymbol = getScopeToSearchUpon( scope, first, i );
while( i.hasNext() )
{
IToken current = (IToken)i.next();
if( current.getType() == IToken.tCOLONCOLON ) continue;
try
{
if( current != typeName.getLastToken() )
typeSymbol = ((IContainerSymbol)typeSymbol).lookupNestedNameSpecifier( current.getImage());
else
typeSymbol = ((IContainerSymbol)typeSymbol).lookup( current.getImage());
if( typeSymbol != null )
addReference( references, createReference( typeSymbol, current.getImage(), current.getOffset() ));
else
throw new ASTSemanticException();
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
}
s.setTypeSymbol( typeSymbol );
}
s.getTypeInfo().setBit( isLong, TypeInfo.isLong );
s.getTypeInfo().setBit( isShort, TypeInfo.isShort);
s.getTypeInfo().setBit( isUnsigned, TypeInfo.isUnsigned );
s.getTypeInfo().setBit( isComplex, TypeInfo.isComplex );
s.getTypeInfo().setBit( isImaginary, TypeInfo.isImaginary );
return new ASTSimpleTypeSpecifier( s, false, typeName.toString(), references );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createFunction(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, java.util.List, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.IASTTemplate)
*/
public IASTFunction createFunction(
IASTScope scope,
ITokenDuple name,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
boolean isInline,
boolean isFriend,
boolean isStatic,
int startOffset,
int nameOffset,
int nameEndOffset,
IASTTemplate ownerTemplate,
boolean isConst,
boolean isVolatile,
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual,
List constructorChain,
boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments ) throws ASTSemanticException
{
List references = new ArrayList();
IContainerSymbol ownerScope = scopeToSymbol( scope );
// check if this is a method in a body file
if(name.length() > 1){
IContainerSymbol parentScope = (IContainerSymbol)
lookupQualifiedName(
ownerScope,
name.getSubrange( 0, name.findLastTokenType( IToken.tCOLONCOLON ) - 1),
references,
false );
if((parentScope != null) &&
( (parentScope.getType() == TypeInfo.t_class)
|| (parentScope.getType() == TypeInfo.t_struct)
|| (parentScope.getType() == TypeInfo.t_union))
){
IASTScope methodParentScope = (IASTScope)parentScope.getASTExtension().getPrimaryDeclaration();
ITokenDuple newName = name.getSubrange(
name.findLastTokenType( IToken.tCOLONCOLON) + 1,
name.length() - 1 );
return createMethod(
methodParentScope,
newName,
parameters,
returnType,
exception,
isInline,
isFriend,
isStatic,
startOffset,
newName.getFirstToken().getOffset(),
nameEndOffset,
ownerTemplate,
isConst,
isVolatile,
isVirtual,
isExplicit,
isPureVirtual,
ASTAccessVisibility.PRIVATE,
constructorChain,
references,
isFunctionDefinition, hasFunctionTryBlock, hasVariableArguments );
}
}
IParameterizedSymbol symbol = pst.newParameterizedSymbol( name.getLastToken().getImage(), TypeInfo.t_function );
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
symbol.setHasVariableArgs( hasVariableArguments );
setParameter( symbol, returnType, false, references );
setParameters( symbol, references, parameters.iterator() );
symbol.setIsForwardDeclaration(!isFunctionDefinition);
boolean previouslyDeclared = false;
if( isFunctionDefinition )
{
List functionParameters = new LinkedList();
// the lookup requires a list of type infos
// instead of a list of IASTParameterDeclaration
Iterator p = parameters.iterator();
while (p.hasNext()){
ASTParameterDeclaration param = (ASTParameterDeclaration)p.next();
functionParameters.add(param.getSymbol().getTypeInfo());
}
IParameterizedSymbol functionDeclaration = null;
functionDeclaration =
(IParameterizedSymbol) lookupQualifiedName(ownerScope, name.getLastToken().getImage(), TypeInfo.t_function, functionParameters, 0, new ArrayList(), false, LookupType.UNQUALIFIED );
if( functionDeclaration != null )
{
functionDeclaration.setTypeSymbol( symbol );
previouslyDeclared = true;
}
}
try
{
ownerScope.addSymbol( symbol );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
ASTFunction function = new ASTFunction( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, hasFunctionTryBlock );
try
{
attachSymbolExtension(symbol, function);
}
catch (ExtensionException e1)
{
throw new ASTSemanticException();
}
return function;
}
protected void setFunctionTypeInfoBits(
boolean isInline,
boolean isFriend,
boolean isStatic,
IParameterizedSymbol symbol)
{
symbol.getTypeInfo().setBit( isInline, TypeInfo.isInline );
symbol.getTypeInfo().setBit( isFriend, TypeInfo.isFriend );
symbol.getTypeInfo().setBit( isStatic, TypeInfo.isStatic );
}
/**
* @param symbol
* @param iterator
*/
protected void setParameters(IParameterizedSymbol symbol, List references, Iterator iterator) throws ASTSemanticException
{
while( iterator.hasNext() )
{
setParameter( symbol, (IASTParameterDeclaration)iterator.next(), true, references );
}
}
protected TypeInfo getParameterTypeInfo( IASTAbstractDeclaration absDecl)throws ASTSemanticException{
TypeInfo type = new TypeInfo();
if( absDecl.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier )
{
IASTSimpleTypeSpecifier.Type kind = ((IASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getType();
if( kind == IASTSimpleTypeSpecifier.Type.BOOL )
type.setType(TypeInfo.t_bool);
else if( kind == IASTSimpleTypeSpecifier.Type.CHAR )
type.setType(TypeInfo.t_char);
else if( kind == IASTSimpleTypeSpecifier.Type.DOUBLE )
type.setType(TypeInfo.t_double);
else if( kind == IASTSimpleTypeSpecifier.Type.FLOAT )
type.setType(TypeInfo.t_float);
else if( kind == IASTSimpleTypeSpecifier.Type.INT )
type.setType(TypeInfo.t_int);
else if( kind == IASTSimpleTypeSpecifier.Type.VOID )
type.setType(TypeInfo.t_void);
else if( kind == IASTSimpleTypeSpecifier.Type.WCHAR_T)
type.setType(TypeInfo.t_wchar_t);
else if( kind == IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME )
type.setType(TypeInfo.t_type);
else
throw new ASTSemanticException();
}
else if( absDecl.getTypeSpecifier() instanceof IASTClassSpecifier )
{
ASTClassKind kind = ((IASTClassSpecifier)absDecl.getTypeSpecifier()).getClassKind();
if( kind == ASTClassKind.CLASS )
type.setType(TypeInfo.t_class);
else if( kind == ASTClassKind.STRUCT )
type.setType(TypeInfo.t_struct);
else if( kind == ASTClassKind.UNION )
type.setType(TypeInfo.t_union);
else
throw new ASTSemanticException();
}
else if( absDecl.getTypeSpecifier() instanceof IASTEnumerationSpecifier )
{
type.setType(TypeInfo.t_enumeration);
}
else if( absDecl.getTypeSpecifier() instanceof IASTElaboratedTypeSpecifier )
{
ASTClassKind kind = ((IASTElaboratedTypeSpecifier)absDecl.getTypeSpecifier()).getClassKind();
if( kind == ASTClassKind.CLASS )
type.setType(TypeInfo.t_class);
else if( kind == ASTClassKind.STRUCT )
type.setType(TypeInfo.t_struct);
else if( kind == ASTClassKind.UNION )
type.setType(TypeInfo.t_union);
else if( kind == ASTClassKind.ENUM )
type.setType(TypeInfo.t_enumeration);
else
throw new ASTSemanticException();
}
else
throw new ASTSemanticException();
return type;
}
/**
* @param symbol
* @param returnType
*/
protected void setParameter(IParameterizedSymbol symbol, IASTAbstractDeclaration absDecl, boolean isParameter, List references) throws ASTSemanticException
{
if (absDecl.getTypeSpecifier() == null)
return;
// now determined by another function
TypeInfo.eType type = getParameterTypeInfo(absDecl).getType();
ISymbol xrefSymbol = null;
List newReferences = null;
if( absDecl.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier )
{
if( ((IASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getType() == IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME )
{
xrefSymbol = ((ASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getSymbol();
newReferences = ((ASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getReferences();
}
}
else if( absDecl.getTypeSpecifier() instanceof ASTElaboratedTypeSpecifier )
{
ASTElaboratedTypeSpecifier elab = (ASTElaboratedTypeSpecifier)absDecl.getTypeSpecifier();
xrefSymbol = elab.getSymbol();
newReferences = new ArrayList();
newReferences.addAll( elab.getReferences() );
newReferences.add( createReference( xrefSymbol, elab.getName(), elab.getNameOffset()) );
}
String paramName = "";
if(absDecl instanceof IASTParameterDeclaration){
paramName = ((IASTParameterDeclaration)absDecl).getName();
}
ISymbol paramSymbol = pst.newSymbol( paramName, type );
if( xrefSymbol != null )
paramSymbol.setTypeSymbol( xrefSymbol.getTypeSymbol() );
setPointerOperators( paramSymbol, absDecl.getPointerOperators(), absDecl.getArrayModifiers() );
if( isParameter)
symbol.addParameter( paramSymbol );
else
symbol.setReturnType( paramSymbol );
if( newReferences != null )
references.addAll( newReferences );
if( absDecl instanceof ASTParameterDeclaration )
{
ASTParameterDeclaration parm = (ASTParameterDeclaration)absDecl;
parm.setSymbol( paramSymbol );
try
{
attachSymbolExtension( paramSymbol, parm );
}
catch (ExtensionException e)
{
throw new ASTSemanticException();
}
}
}
/**
* @param paramSymbol
* @param iterator
*/
protected void setPointerOperators(ISymbol symbol, Iterator pointerOpsIterator, Iterator arrayModsIterator) throws ASTSemanticException
{
while( pointerOpsIterator.hasNext() )
{
ASTPointerOperator pointerOperator = (ASTPointerOperator)pointerOpsIterator.next();
if( pointerOperator == ASTPointerOperator.REFERENCE )
symbol.addPtrOperator( new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference ));
else if( pointerOperator == ASTPointerOperator.POINTER )
symbol.addPtrOperator( new TypeInfo.PtrOp( TypeInfo.PtrOp.t_pointer ));
else if( pointerOperator == ASTPointerOperator.CONST_POINTER )
symbol.addPtrOperator( new TypeInfo.PtrOp( TypeInfo.PtrOp.t_pointer, true, false ));
else if( pointerOperator == ASTPointerOperator.VOLATILE_POINTER )
symbol.addPtrOperator( new TypeInfo.PtrOp( TypeInfo.PtrOp.t_pointer, false, true));
else
throw new ASTSemanticException();
}
while( arrayModsIterator.hasNext() )
{
arrayModsIterator.next();
symbol.addPtrOperator( new TypeInfo.PtrOp( TypeInfo.PtrOp.t_array ));
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createMethod(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, java.util.List, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.IASTTemplate, boolean, boolean, boolean, boolean, boolean, boolean, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility)
*/
public IASTMethod createMethod(
IASTScope scope,
ITokenDuple name,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
boolean isInline,
boolean isFriend,
boolean isStatic,
int startOffset,
int nameOffset,
int nameEndOffset,
IASTTemplate ownerTemplate,
boolean isConst,
boolean isVolatile,
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual,
ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments ) throws ASTSemanticException
{
return createMethod(scope, name, parameters, returnType, exception,
isInline, isFriend, isStatic, startOffset, nameOffset, nameEndOffset,
ownerTemplate, isConst, isVolatile, isVirtual, isExplicit, isPureVirtual,
visibility, constructorChain, null, isFunctionDefinition, hasFunctionTryBlock, hasVariableArguments );
}
public IASTMethod createMethod(
IASTScope scope,
ITokenDuple nameDuple,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
boolean isInline,
boolean isFriend,
boolean isStatic,
int startOffset,
int nameOffset,
int nameEndOffset,
IASTTemplate ownerTemplate,
boolean isConst,
boolean isVolatile,
boolean isVirtual,
boolean isExplicit,
boolean isPureVirtual,
ASTAccessVisibility visibility,
List constructorChain,
List references, boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments ) throws ASTSemanticException
{
boolean isConstructor = false;
boolean isDestructor = false;
IContainerSymbol ownerScope = scopeToSymbol( scope );
IParameterizedSymbol symbol = pst.newParameterizedSymbol( nameDuple.toString(), TypeInfo.t_function );
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
setMethodTypeInfoBits( symbol, isConst, isVolatile, isVirtual, isExplicit );
symbol.setHasVariableArgs( hasVariableArguments );
if(references == null)
references = new ArrayList();
if( returnType.getTypeSpecifier() != null )
setParameter( symbol, returnType, false, references );
setParameters( symbol, references, parameters.iterator() );
String parentName = ((IASTClassSpecifier)scope).getName();
// check constructor / destructor if no return type
if ( returnType.getTypeSpecifier() == null ){
if(parentName.indexOf(DOUBLE_COLON) != -1){
parentName = parentName.substring(parentName.lastIndexOf(DOUBLE_COLON) + DOUBLE_COLON.length());
}
if( parentName.equals(nameDuple.toString()) ){
isConstructor = true;
} else if(nameDuple.getFirstToken().getType() == IToken.tCOMPL && parentName.equals(nameDuple.getLastToken().getImage())){
isDestructor = true;
}
}
symbol.setIsForwardDeclaration(!isFunctionDefinition);
boolean previouslyDeclared = false;
IParameterizedSymbol functionDeclaration = null;
if( isFunctionDefinition || isFriend )
{
List functionParameters = new LinkedList();
// the lookup requires a list of type infos
// instead of a list of IASTParameterDeclaration
Iterator p = parameters.iterator();
while (p.hasNext()){
ASTParameterDeclaration param = (ASTParameterDeclaration)p.next();
functionParameters.add(param.getSymbol().getTypeInfo());
}
List functionReferences = new ArrayList();
if( isFriend )
{
functionDeclaration =
(IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, functionReferences, false, LookupType.FORFRIENDSHIP );
} else {
functionDeclaration =
(IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple.toString(), isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION );
}
previouslyDeclared = ( functionDeclaration != null );
if( isFriend )
{
if( functionDeclaration != null )
{
symbol.setTypeSymbol( functionDeclaration );
// friend declaration, has no real visibility, set private
visibility = ASTAccessVisibility.PRIVATE;
} else
{
//for a friend function declaration, if there is no prior declaration, the program is illformed
throw new ASTSemanticException();
}
} else if( functionDeclaration != null )
{
functionDeclaration.setTypeSymbol( symbol );
// set the definition visibility = declaration visibility
ASTMethodReference reference = (ASTMethodReference) functionReferences.iterator().next();
visibility = ((IASTMethod)reference.getReferencedElement()).getVisiblity();
}
}
try
{
if( isFriend )
{
((IDerivableContainerSymbol)ownerScope).addFriend( functionDeclaration );
} else if( !isConstructor )
ownerScope.addSymbol( symbol );
else
{
symbol.setType( TypeInfo.t_constructor );
((IDerivableContainerSymbol)ownerScope).addConstructor( symbol );
}
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
resolveLeftoverConstructorInitializerMembers( symbol, constructorChain );
ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock );
try
{
attachSymbolExtension( symbol, method );
}
catch (ExtensionException e1)
{
throw new ASTSemanticException();
}
return method;
}
/**
* @param symbol
* @param constructorChain
*/
protected void resolveLeftoverConstructorInitializerMembers(IParameterizedSymbol symbol, List constructorChain)
{
if( constructorChain != null )
{
Iterator initializers = constructorChain.iterator();
while( initializers.hasNext())
{
IASTConstructorMemberInitializer initializer = (IASTConstructorMemberInitializer)initializers.next();
if( !initializer.getName().equals( "") &&
initializer instanceof ASTConstructorMemberInitializer &&
((ASTConstructorMemberInitializer)initializer).requiresNameResolution() )
{
ASTConstructorMemberInitializer realInitializer = ((ASTConstructorMemberInitializer)initializer);
try
{
IDerivableContainerSymbol container = (IDerivableContainerSymbol) symbol.getContainingSymbol();
lookupQualifiedName(container, initializer.getName(), TypeInfo.t_any, null, realInitializer.getNameOffset(), realInitializer.getReferences(), false, LookupType.QUALIFIED);
}
catch( ASTSemanticException ase )
{
}
}
// TODO try and resolve parameter references now in the expression list
}
}
}
/**
* @param symbol
* @param isConst
* @param isVolatile
* @param isConstructor
* @param isDestructor
* @param isVirtual
* @param isExplicit
* @param isPureVirtual
*/
protected void setMethodTypeInfoBits(IParameterizedSymbol symbol, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit)
{
symbol.getTypeInfo().setBit( isConst, TypeInfo.isConst );
symbol.getTypeInfo().setBit( isVolatile, TypeInfo.isConst );
symbol.getTypeInfo().setBit( isVirtual, TypeInfo.isVirtual );
symbol.getTypeInfo().setBit( isExplicit, TypeInfo.isExplicit );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createVariable(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, boolean, org.eclipse.cdt.core.parser.ast.IASTInitializerClause, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, boolean, boolean, boolean, boolean, int, int)
*/
public IASTVariable createVariable(
IASTScope scope,
String name,
boolean isAuto,
IASTInitializerClause initializerClause,
IASTExpression bitfieldExpression,
IASTAbstractDeclaration abstractDeclaration,
boolean isMutable,
boolean isExtern,
boolean isRegister,
boolean isStatic,
int startingOffset,
int nameOffset, int nameEndOffset, IASTExpression constructorExpression) throws ASTSemanticException
{
List references = new ArrayList();
IContainerSymbol ownerScope = scopeToSymbol( scope );
// check if this is a scoped field, not a variable
StringTokenizer tokenizer = new StringTokenizer(name,DOUBLE_COLON);
int tokencount = tokenizer.countTokens();
if(tokencount > 1){
List tokens = new ArrayList();
String oneToken = "";
// This is NOT a function. This is a method definition
while (tokenizer.hasMoreTokens()){
oneToken = tokenizer.nextToken();
tokens.add(oneToken);
}
String fieldName = oneToken;
int numOfTokens = 1;
int offset = nameOffset;
IContainerSymbol parentScope = ownerScope;
Iterator i = tokens.iterator();
while (i.hasNext() && (numOfTokens++) < tokens.size()){
String token = (String) i.next();
IContainerSymbol parentSymbol = null;
try {
parentSymbol = (IContainerSymbol) parentScope.lookupNestedNameSpecifier( token );
if( parentSymbol != null )
addReference( references, createReference( parentSymbol, name, offset ));
} catch (ParserSymbolTableException e1) {
//do nothing
}
if(parentSymbol == null)
break;
else {
parentScope = parentSymbol;
offset += token.length()+ DOUBLE_COLON.length();
}
}
if((parentScope != null) &&
( (parentScope.getType() == TypeInfo.t_class)
|| (parentScope.getType() == TypeInfo.t_struct)
|| (parentScope.getType() == TypeInfo.t_union))
){
IASTScope fieldParentScope = (IASTScope)parentScope.getASTExtension().getPrimaryDeclaration();
return createField(fieldParentScope, fieldName,isAuto, initializerClause, bitfieldExpression, abstractDeclaration, isMutable, isExtern,
isRegister, isStatic, startingOffset, offset, nameEndOffset, constructorExpression, ASTAccessVisibility.PRIVATE, references);
}
}
ISymbol newSymbol = cloneSimpleTypeSymbol(name, abstractDeclaration, references);
setVariableTypeInfoBits(
isAuto,
abstractDeclaration,
isMutable,
isExtern,
isRegister,
isStatic,
newSymbol);
setPointerOperators( newSymbol, abstractDeclaration.getPointerOperators(), abstractDeclaration.getArrayModifiers() );
newSymbol.setIsForwardDeclaration(isStatic);
boolean previouslyDeclared = false;
if(!isStatic){
ISymbol variableDeclaration = (ISymbol) lookupQualifiedName(ownerScope, name, new ArrayList(), false, LookupType.UNQUALIFIED);
if( variableDeclaration != null )
{
variableDeclaration.setTypeSymbol( newSymbol );
previouslyDeclared = true;
}
}
try
{
ownerScope.addSymbol( newSymbol );
}
catch (ParserSymbolTableException e)
{
// TODO Auto-generated catch block
}
ASTVariable variable = new ASTVariable( newSymbol, abstractDeclaration, initializerClause, bitfieldExpression, startingOffset, nameOffset, nameEndOffset, references, constructorExpression, previouslyDeclared );
if( variable.getInitializerClause() != null )
{
variable.getInitializerClause().setOwnerVariableDeclaration(variable);
addDesignatorReferences( (ASTInitializerClause)variable.getInitializerClause() );
}
try
{
attachSymbolExtension(newSymbol, variable );
}
catch (ExtensionException e)
{
throw new ASTSemanticException();
}
return variable;
}
/**
* @param clause
*/
protected void addDesignatorReferences( ASTInitializerClause clause )
{
if( clause.getKind() == IASTInitializerClause.Kind.DESIGNATED_INITIALIZER_LIST ||
clause.getKind() == IASTInitializerClause.Kind.DESIGNATED_ASSIGNMENT_EXPRESSION )
{
ISymbol variableSymbol = ((ASTVariable)clause.getOwnerVariableDeclaration()).getSymbol();
ISymbol currentSymbol = variableSymbol.getTypeSymbol();
TypeInfo currentTypeInfo = new TypeInfo( currentSymbol.getTypeInfo() );
Iterator designators = clause.getDesignators();
while( designators.hasNext() )
{
IASTDesignator designator = (IASTDesignator)designators.next();
if( designator.getKind() == IASTDesignator.DesignatorKind.FIELD )
{
ISymbol lookup = null;
if( ! ( currentSymbol instanceof IContainerSymbol ) )
break;
try
{
lookup = ((IContainerSymbol)currentSymbol).lookup( designator.fieldName() );
}
catch (ParserSymbolTableException e){
break;
}
if( lookup == null || lookup.getContainingSymbol() != currentSymbol )
break;
try
{
clause.getReferences().add( createReference( lookup, designator.fieldName(), designator.fieldOffset() ));
}
catch (ASTSemanticException e1)
{
// error
}
// we have found the correct field
currentTypeInfo = new TypeInfo( lookup.getTypeInfo() );
if( lookup.getTypeInfo() == null )
break;
currentSymbol = lookup.getTypeSymbol();
}
else if( designator.getKind() == IASTDesignator.DesignatorKind.SUBSCRIPT )
currentTypeInfo.applyOperatorExpressions( SUBSCRIPT );
}
}
if( clause.getKind() == IASTInitializerClause.Kind.DESIGNATED_INITIALIZER_LIST ||
clause.getKind() == IASTInitializerClause.Kind.INITIALIZER_LIST )
{
Iterator subInitializers = clause.getInitializers();
while( subInitializers.hasNext() )
addDesignatorReferences( (ASTInitializerClause)subInitializers.next() );
}
}
protected void setVariableTypeInfoBits(
boolean isAuto,
IASTAbstractDeclaration abstractDeclaration,
boolean isMutable,
boolean isExtern,
boolean isRegister,
boolean isStatic,
ISymbol newSymbol)
{
newSymbol.getTypeInfo().setBit( isMutable, TypeInfo.isMutable );
newSymbol.getTypeInfo().setBit( isAuto, TypeInfo.isAuto );
newSymbol.getTypeInfo().setBit( isExtern, TypeInfo.isExtern );
newSymbol.getTypeInfo().setBit( isRegister, TypeInfo.isRegister );
newSymbol.getTypeInfo().setBit( isStatic, TypeInfo.isStatic );
newSymbol.getTypeInfo().setBit( abstractDeclaration.isConst(), TypeInfo.isConst );
}
protected ISymbol cloneSimpleTypeSymbol(
String name,
IASTAbstractDeclaration abstractDeclaration,
List references) throws ASTSemanticException
{
if( abstractDeclaration.getTypeSpecifier() == null )
throw new ASTSemanticException();
ISymbol newSymbol = null;
ISymbol symbolToBeCloned = null;
if( abstractDeclaration.getTypeSpecifier() instanceof ASTSimpleTypeSpecifier )
{
symbolToBeCloned = ((ASTSimpleTypeSpecifier)abstractDeclaration.getTypeSpecifier()).getSymbol();
references.addAll( ((ASTSimpleTypeSpecifier)abstractDeclaration.getTypeSpecifier()).getReferences() );
}
else if( abstractDeclaration.getTypeSpecifier() instanceof ASTClassSpecifier )
{
symbolToBeCloned = pst.newSymbol(name, TypeInfo.t_type);
symbolToBeCloned.setTypeSymbol(((ASTClassSpecifier)abstractDeclaration.getTypeSpecifier()).getSymbol());
}
else if( abstractDeclaration.getTypeSpecifier() instanceof ASTElaboratedTypeSpecifier )
{
ASTElaboratedTypeSpecifier elab = ((ASTElaboratedTypeSpecifier)abstractDeclaration.getTypeSpecifier());
symbolToBeCloned = pst.newSymbol(name, TypeInfo.t_type);
symbolToBeCloned.setTypeSymbol(elab.getSymbol());
references.add( createReference( elab.getSymbol(), elab.getName(), elab.getNameOffset()) );
}
newSymbol = (ISymbol) symbolToBeCloned.clone();
newSymbol.setName( name );
return newSymbol;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createField(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, boolean, org.eclipse.cdt.core.parser.ast.IASTInitializerClause, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, boolean, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility)
*/
public IASTField createField(
IASTScope scope,
String name,
boolean isAuto,
IASTInitializerClause initializerClause,
IASTExpression bitfieldExpression,
IASTAbstractDeclaration abstractDeclaration,
boolean isMutable,
boolean isExtern,
boolean isRegister,
boolean isStatic,
int startingOffset,
int nameOffset,
int nameEndOffset, IASTExpression constructorExpression, ASTAccessVisibility visibility) throws ASTSemanticException
{
return createField(scope, name,isAuto, initializerClause, bitfieldExpression, abstractDeclaration, isMutable, isExtern,
isRegister, isStatic, startingOffset, nameOffset, nameEndOffset, constructorExpression, visibility, null);
}
public IASTField createField(
IASTScope scope,
String name,
boolean isAuto,
IASTInitializerClause initializerClause,
IASTExpression bitfieldExpression,
IASTAbstractDeclaration abstractDeclaration,
boolean isMutable,
boolean isExtern,
boolean isRegister,
boolean isStatic,
int startingOffset,
int nameOffset,
int nameEndOffset,
IASTExpression constructorExpression,
ASTAccessVisibility visibility,
List references) throws ASTSemanticException
{
IContainerSymbol ownerScope = scopeToSymbol( scope );
if(references == null)
references = new ArrayList();
ISymbol newSymbol = cloneSimpleTypeSymbol(name, abstractDeclaration, references);
setVariableTypeInfoBits(
isAuto,
abstractDeclaration,
isMutable,
isExtern,
isRegister,
isStatic,
newSymbol);
setPointerOperators( newSymbol, abstractDeclaration.getPointerOperators(), abstractDeclaration.getArrayModifiers() );
newSymbol.setIsForwardDeclaration(isStatic);
boolean previouslyDeclared = false;
if(!isStatic){
List fieldReferences = new ArrayList();
ISymbol fieldDeclaration = lookupQualifiedName(ownerScope, name, fieldReferences, false, LookupType.FORDEFINITION);
if( fieldDeclaration != null )
{
previouslyDeclared = true;
fieldDeclaration.setTypeSymbol( newSymbol );
// set the definition visibility = declaration visibility
ASTReference reference = (ASTReference) fieldReferences.iterator().next();
visibility = ((IASTField)reference.getReferencedElement()).getVisiblity();
}
}
try
{
ownerScope.addSymbol( newSymbol );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
ASTField field = new ASTField( newSymbol, abstractDeclaration, initializerClause, bitfieldExpression, startingOffset, nameOffset, nameEndOffset, references, previouslyDeclared, constructorExpression, visibility );
try
{
attachSymbolExtension(newSymbol, field );
}
catch (ExtensionException e)
{
throw new ASTSemanticException();
}
return field;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTemplateDeclaration(org.eclipse.cdt.core.parser.ast.IASTScope, java.util.List, boolean, int)
*/
public IASTTemplateDeclaration createTemplateDeclaration(
IASTScope scope,
List templateParameters,
boolean exported,
int startingOffset)
{
// TODO Auto-generated method stub
return new ASTTemplateDeclaration();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTemplateParameter(org.eclipse.cdt.core.parser.ast.IASTTemplateParameter.ParamKind, java.lang.String, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration, java.util.List)
*/
public IASTTemplateParameter createTemplateParameter(
ParamKind kind,
String identifier,
String defaultValue,
IASTParameterDeclaration parameter,
List parms)
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTemplateInstantiation(org.eclipse.cdt.core.parser.ast.IASTScope, int)
*/
public IASTTemplateInstantiation createTemplateInstantiation(
IASTScope scope,
int startingOffset)
{
// TODO Auto-generated method stub
return new ASTTemplateInstantiation();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTemplateSpecialization(org.eclipse.cdt.core.parser.ast.IASTScope, int)
*/
public IASTTemplateSpecialization createTemplateSpecialization(
IASTScope scope,
int startingOffset)
{
// TODO Auto-generated method stub
return new ASTTemplateSpecialization();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTypedef(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, int, int)
*/
public IASTTypedefDeclaration createTypedef(
IASTScope scope,
String name,
IASTAbstractDeclaration mapping,
int startingOffset,
int nameOffset, int nameEndOffset) throws ASTSemanticException
{
IContainerSymbol containerSymbol = scopeToSymbol(scope);
ISymbol newSymbol = pst.newSymbol( name, TypeInfo.t_type);
newSymbol.getTypeInfo().setBit( true,TypeInfo.isTypedef );
List references = new ArrayList();
if( mapping.getTypeSpecifier() instanceof ASTSimpleTypeSpecifier )
{
references.addAll( ((ASTSimpleTypeSpecifier)mapping.getTypeSpecifier()).getReferences() );
}
try
{
containerSymbol.addSymbol( newSymbol );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
ASTTypedef d = new ASTTypedef( newSymbol, mapping, startingOffset, nameOffset, nameEndOffset, references );
try
{
attachSymbolExtension(newSymbol, d );
}
catch (ExtensionException e1)
{
throw new ASTSemanticException();
}
return d;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTypeSpecDeclaration(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier, org.eclipse.cdt.core.parser.ast.IASTTemplate, int, int)
*/
public IASTAbstractTypeSpecifierDeclaration createTypeSpecDeclaration(
IASTScope scope,
IASTTypeSpecifier typeSpecifier,
IASTTemplate template,
int startingOffset,
int endingOffset)
{
return new ASTAbstractTypeSpecifierDeclaration( scopeToSymbol(scope), typeSpecifier, template, startingOffset, endingOffset);
}
public IASTElaboratedTypeSpecifier createElaboratedTypeSpecifier(IASTScope scope, ASTClassKind kind, ITokenDuple name, int startingOffset, int endOffset, boolean isForewardDecl, boolean isFriend) throws ASTSemanticException
{
IContainerSymbol currentScopeSymbol = scopeToSymbol(scope);
TypeInfo.eType pstType = classKindToTypeInfo(kind);
List references = new ArrayList();
IToken lastToken = name.getLastToken();
if( name.length() != 1 ) // qualified name
{
ITokenDuple containerSymbolName =
name.getSubrange( 0, name.length() - 3 ); // -1 for index, -2 for last hop of qualified name
currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol,
containerSymbolName, references, true);
if( currentScopeSymbol == null )
throw new ASTSemanticException();
}
ISymbol checkSymbol = null;
try
{
if( isFriend ){
if( !(currentScopeSymbol instanceof IDerivableContainerSymbol) ){
throw new ASTSemanticException();
}
checkSymbol = ((IDerivableContainerSymbol)currentScopeSymbol).lookupForFriendship( lastToken.getImage() );
} else {
checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, lastToken.getImage());
}
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
if( isForewardDecl )
{
if( checkSymbol == null )
{
checkSymbol = pst.newDerivableContainerSymbol( lastToken.getImage(), pstType );
checkSymbol.setIsForwardDeclaration( true );
try
{
if( isFriend ){
((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol );
} else {
currentScopeSymbol.addSymbol( checkSymbol );
}
}
catch (ParserSymbolTableException e1)
{
throw new ASTSemanticException();
}
ASTElaboratedTypeSpecifier elab =
new ASTElaboratedTypeSpecifier( checkSymbol, kind, startingOffset, name.getFirstToken().getOffset(), name.getLastToken().getEndOffset(), endOffset, references, isForewardDecl );
try
{
attachSymbolExtension( checkSymbol, elab );
}
catch (ExtensionException e2)
{
throw new ASTSemanticException();
}
} else if( isFriend ){
try {
((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol );
} catch (ParserSymbolTableException e1) {
throw new ASTSemanticException();
}
}
}
if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTClassSpecifier ||
checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTEnumerationSpecifier
)
{
ASTElaboratedTypeSpecifier elab = new ASTElaboratedTypeSpecifier( checkSymbol, kind, startingOffset, name.getFirstToken().getOffset(), name.getLastToken().getEndOffset(), endOffset, references, isForewardDecl );
try
{
attachSymbolExtension( checkSymbol, elab );
}
catch (ExtensionException e2)
{
throw new ASTSemanticException();
}
return elab;
}
if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTElaboratedTypeSpecifier )
return (IASTElaboratedTypeSpecifier)checkSymbol.getASTExtension().getPrimaryDeclaration();
throw new ASTSemanticException();
}
protected ParserSymbolTable pst;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createNamespaceAlias(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, org.eclipse.cdt.core.parser.ITokenDuple, int, int, int)
*/
public IASTNamespaceAlias createNamespaceAlias(IASTScope scope, String identifier, ITokenDuple alias, int startingOffset, int nameOffset, int nameEndOffset, int endOffset) throws ASTSemanticException
{
IContainerSymbol startingSymbol = scopeToSymbol(scope);
List references = new ArrayList();
ISymbol namespaceSymbol = lookupQualifiedName( startingSymbol, alias, references, true );
if( namespaceSymbol.getType() != TypeInfo.t_namespace )
throw new ASTSemanticException();
ISymbol newSymbol = pst.newContainerSymbol( identifier, TypeInfo.t_namespace );
newSymbol.setTypeSymbol( namespaceSymbol );
try
{
startingSymbol.addSymbol( newSymbol );
}
catch (ParserSymbolTableException e)
{
throw new ASTSemanticException();
}
ASTNamespaceAlias astAlias = new ASTNamespaceAlias(
newSymbol, alias.toString(), (IASTNamespaceDefinition)namespaceSymbol.getASTExtension().getPrimaryDeclaration(),
startingOffset, nameOffset, nameEndOffset, endOffset, references );
try
{
attachSymbolExtension( newSymbol, astAlias );
}
catch (ExtensionException e1)
{
throw new ASTSemanticException();
}
return astAlias;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createNewCodeBlock(org.eclipse.cdt.core.parser.ast.IASTScope)
*/
public IASTCodeScope createNewCodeBlock(IASTScope scope) {
IContainerSymbol symbol = scopeToSymbol( scope );
IContainerSymbol newScope = pst.newContainerSymbol("", TypeInfo.t_block);
newScope.setContainingSymbol(symbol);
ASTCodeScope codeScope = new ASTCodeScope( newScope );
try
{
attachSymbolExtension( newScope, codeScope );
}
catch (ExtensionException e)
{
}
return codeScope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#queryIsTypeName(org.eclipse.cdt.core.parser.ITokenDuple)
*/
public boolean queryIsTypeName(IASTScope scope, ITokenDuple nameInQuestion) {
ISymbol lookupSymbol = null;
try {
lookupSymbol =
lookupQualifiedName(
scopeToSymbol(scope),
nameInQuestion,
new ArrayList(),
false);
} catch (ASTSemanticException e) {
// won't get thrown
}
if( lookupSymbol == null ) return false;
if( lookupSymbol.isType( TypeInfo.t_type, TypeInfo.t_enumeration ) ) return true;
return false;
}
public IASTParameterDeclaration createParameterDeclaration(boolean isConst, boolean isVolatile, IASTTypeSpecifier typeSpecifier, List pointerOperators, List arrayModifiers, List parameters, ASTPointerOperator pointerOp, String parameterName, IASTInitializerClause initializerClause, int startingOffset, int nameOffset, int nameEndOffset, int endingOffset)
{
return new ASTParameterDeclaration( null, isConst, isVolatile, typeSpecifier, pointerOperators, arrayModifiers, parameters, pointerOp, parameterName, initializerClause, startingOffset, endingOffset, nameOffset, nameEndOffset );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTypeId(org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type, org.eclipse.cdt.core.parser.ITokenDuple, java.util.List, java.util.List)
*/
public IASTTypeId createTypeId(IASTScope scope, Type kind, boolean isConst, boolean isVolatile, boolean isShort,
boolean isLong, boolean isSigned, boolean isUnsigned, boolean isTypename, ITokenDuple name, List pointerOps, List arrayMods) throws ASTSemanticException
{
ASTTypeId result =
new ASTTypeId( kind, name, pointerOps, arrayMods, "", //TODO
isConst, isVolatile, isUnsigned, isSigned, isShort, isLong, isTypename );
result.setTypeSymbol( createSymbolForTypeId( scope, result ) );
return result;
}
/**
* @param id
* @return
*/
public static TypeInfo.eType getTypeKind(IASTTypeId id)
{
IASTSimpleTypeSpecifier.Type type = id.getKind();
if( type == IASTSimpleTypeSpecifier.Type.BOOL )
return TypeInfo.t_bool;
else if( type == IASTSimpleTypeSpecifier.Type.CHAR )
return TypeInfo.t_char;
else if( type == IASTSimpleTypeSpecifier.Type.DOUBLE )
return TypeInfo.t_double;
else if( type == IASTSimpleTypeSpecifier.Type.FLOAT )
return TypeInfo.t_float;
else if( type == IASTSimpleTypeSpecifier.Type.INT )
return TypeInfo.t_int;
else if( type == IASTSimpleTypeSpecifier.Type.VOID )
return TypeInfo.t_void;
else if( id.isShort() || id.isLong() || id.isUnsigned() || id.isSigned() )
return TypeInfo.t_int;
else
return TypeInfo.t_type;
}
protected ISymbol createSymbolForTypeId( IASTScope scope, IASTTypeId id ) throws ASTSemanticException
{
if( id == null ) return null;
ASTTypeId typeId = (ASTTypeId)id;
ISymbol result = pst.newSymbol( "", CompleteParseASTFactory.getTypeKind(id));
result.getTypeInfo().setBit( id.isConst(), TypeInfo.isConst );
result.getTypeInfo().setBit( id.isVolatile(), TypeInfo.isVolatile );
result.getTypeInfo().setBit( id.isShort(), TypeInfo.isShort);
result.getTypeInfo().setBit( id.isLong(), TypeInfo.isLong);
result.getTypeInfo().setBit( id.isUnsigned(), TypeInfo.isUnsigned);
List refs = new ArrayList();
if( result.getType() == TypeInfo.t_type )
{
ISymbol typeSymbol = lookupQualifiedName( scopeToSymbol(scope), typeId.getTokenDuple(), refs, true );
if( typeSymbol.getType() == TypeInfo.t_type )
throw new ASTSemanticException();
result.setTypeSymbol( typeSymbol );
typeId.addReferences( refs );
}
setPointerOperators( result, id.getPointerOperators(), id.getArrayModifiers() );
return result;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#signalEndOfClassSpecifier(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier)
*/
public void signalEndOfClassSpecifier(IASTClassSpecifier astClassSpecifier)
{
if( astClassSpecifier == null ) return;
try
{
((IDerivableContainerSymbol)((ASTClassSpecifier)astClassSpecifier).getSymbol()).addCopyConstructor();
}
catch (ParserSymbolTableException e)
{
// do nothing, this is best effort
}
}
public IASTInitializerClause createInitializerClause(IASTScope scope, IASTInitializerClause.Kind kind, IASTExpression assignmentExpression, List initializerClauses, List designators)
{
return new ASTInitializerClause( kind, assignmentExpression, initializerClauses, designators );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#getCompletionContext(org.eclipse.cdt.core.parser.ast.IASTExpression.Kind, org.eclipse.cdt.core.parser.ast.IASTExpression)
*/
public IASTNode getCompletionContext(Kind kind, IASTExpression expression) {
IContainerSymbol context = null;
try {
context = getSearchScope( kind, expression, null );
} catch (ASTSemanticException e) {
return null;
}
if( context != null ){
ISymbolASTExtension extension = context.getASTExtension();
return ( extension != null ) ? extension.getPrimaryDeclaration() : null;
}
return null;
}
}