| /********************************************************************** |
| * 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; |
| |
| } |
| } |