diff options
author | Mike Kucera | 2008-04-07 15:52:01 +0000 |
---|---|---|
committer | Mike Kucera | 2008-04-07 15:52:01 +0000 |
commit | b20ba9eac9f7c1d5f653c60a1602dbe47c1df988 (patch) | |
tree | 257d8d0302ab04dfaa3c0f8683e7007dafd801d7 /lrparser/org.eclipse.cdt.core.lrparser/old | |
parent | 0df76bd7b0a35b9ce48808408099238a5a717e7b (diff) | |
download | org.eclipse.cdt-b20ba9eac9f7c1d5f653c60a1602dbe47c1df988.tar.gz org.eclipse.cdt-b20ba9eac9f7c1d5f653c60a1602dbe47c1df988.tar.xz org.eclipse.cdt-b20ba9eac9f7c1d5f653c60a1602dbe47c1df988.zip |
moved unused code into separate source folder
Diffstat (limited to 'lrparser/org.eclipse.cdt.core.lrparser/old')
31 files changed, 4732 insertions, 0 deletions
diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/C99ResolveParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/C99ResolveParserAction.java new file mode 100644 index 00000000000..e2e729b7458 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/C99ResolveParserAction.java @@ -0,0 +1,1559 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.action.deprecated; + +import static org.eclipse.cdt.core.parser.util.CollectionUtils.reverseIterable; +import static org.eclipse.cdt.internal.core.dom.lrparser.symboltable.CNamespace.*; + +import java.util.LinkedList; +import java.util.List; + +import lpg.lpgjavaruntime.IToken; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider; +import org.eclipse.cdt.core.dom.lrparser.action.ScopedStack; +import org.eclipse.cdt.core.parser.util.DebugUtil; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99ArrayType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99BasicType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Enumeration; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Enumerator; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Field; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Function; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99FunctionScope; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99FunctionType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Label; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Parameter; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99PointerType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99ProblemBinding; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Scope; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Structure; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Typedef; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.IC99Binding; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.IC99Scope; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.ITypeable; +import org.eclipse.cdt.internal.core.dom.lrparser.symboltable.C99SymbolTable; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +/** + * This class was an attempt at doing full binding resolution during the parse + * as opposed to doing it after the parse as is normally done with the DOM parser. + * + * + * TODO: token mapping so that this will work with UPC + * TODO: what about function definitions, don't they count as declarations? + * + * Try to resolve bindings without using the ASTStack, that way I can resolve bindings + * without generating an AST. In the future I can remove this as a subclass of C99ParserAction. + * + * TODO: if I'm calculating scopes then those scopes need to be linked to AST nodes + * + * TODO: some language constructs are not handled yet: typeIds (casts), field designators + * + * @author Mike Kucera + * + * @deprecated Binding resolution is too hard, replacing with simpler C99TypedefTrackerParserAction + */ +@SuppressWarnings("restriction") +@Deprecated public class C99ResolveParserAction { + + private static final boolean DEBUG = true; + private static final String NO_IDENT = ""; //$NON-NLS-1$ + + + // provides limited access to the token stream + private final IParserActionTokenProvider parser; + + // The symbolTable currently in use + private C99SymbolTable symbolTable = C99SymbolTable.EMPTY_TABLE; + + // A stack that keeps track of scopes in the symbol table, used to "close" scopes and to undo the opening of scopes + private final LinkedList<C99SymbolTable> symbolTableScopeStack = new LinkedList<C99SymbolTable>(); + + // A stack that keeps track of scopes that are set on bindings + private final LinkedList<IC99Scope> bindingScopeStack = new LinkedList<IC99Scope>(); + + // keeps track of nested declarations + private final LinkedList<DeclaratorFrame> declarationStack = new LinkedList<DeclaratorFrame>(); + + // keeps track of expression types + private final ScopedStack<IType> exprTypeStack = new ScopedStack<IType>(); + + + + + + private TypeQualifiers typeQualifiers; // TODO: can this go in the declaration stack? + + private static class TypeQualifiers { + boolean isConst, isRestrict, isVolatile; + } + + + // "For every action there is an equal and opposite reaction." - Newton's third law + private final LinkedList<IUndoAction> undoStack = new LinkedList<IUndoAction>(); + + + private interface IUndoAction { + void undo(); + } + + public void undo() { + undoStack.removeLast().undo(); + } + + public void undo(int steps) { + for(int i = 0; i < steps; i++) { + undo(); + } + } + + public IC99Scope getCurrentScope() { + return bindingScopeStack.getLast(); + } + + + public C99ResolveParserAction(IParserActionTokenProvider parser) { + this.parser = parser; + bindingScopeStack.add(new C99Scope()); // the global scope + System.out.println(); + } + + + private static IType rawType(IType type) { + while(type instanceof ITypedef) { + type = ((C99Typedef)type).getType(); + } + return type; + } + + /** + * Lexer feedback hack, used by the parser to identify typedefname tokens. + */ + public boolean isTypedef(String ident) { + boolean result = symbolTable.lookup(IDENTIFIER, ident) instanceof ITypedef; + return result; + } + + + /** + * Methods used by tests, package local access. + */ + C99SymbolTable getSymbolTable() { + return symbolTable; + } + + int undoStackSize() { + return undoStack.size(); + } + + LinkedList<DeclaratorFrame> getDeclarationStack() { + return declarationStack; + } + + + /** + * Called from the grammar file in places where a scope is created. + * + * Scopes are created by compound statements, however special care + * must also be taken with for loops because they may contain + * declarations. + * + * TODO: scope object now need to be handled explicitly + */ + public void openSymbolScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTableScopeStack.add(symbolTable); + bindingScopeStack.add(new C99Scope()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace("undo"); + + bindingScopeStack.removeLast(); + symbolTable = symbolTableScopeStack.removeLast(); + } + }); + } + + + public IC99Scope closeSymbolScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final C99SymbolTable undoTable = symbolTable; + symbolTable = symbolTableScopeStack.removeLast(); // close the scope + + final IC99Scope undoScope = bindingScopeStack.removeLast(); + if(!bindingScopeStack.isEmpty()) + undoScope.setParent(bindingScopeStack.getLast()); + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + undoScope.setParent(null); + bindingScopeStack.add(undoScope); + + symbolTableScopeStack.add(symbolTable); + symbolTable = undoTable; + } + }); + + return undoScope; + } + + + // TODO, this needs an undo action + public void openPointerScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.openPointerModifierScope(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + frame.closePointerModifierScope(); + } + }); + } + + + /** + * Called from the grammar before a declaration is about to be reduced. + */ + public void openDeclarationScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.add(new DeclaratorFrame()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.removeLast(); + } + }); + } + + + public void closeDeclarationScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame undoFrame = declarationStack.removeLast(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.add(undoFrame); + } + }); + } + + + public void consumeFunctionDefinition() { + if(DEBUG) DebugUtil.printMethodTrace(); + +// final IC99Scope undoScope = bindingScope; +// +// C99FunctionScope functionScope = new C99FunctionScope(); +// functionScope.setBodyScope(undoScope); +// undoScope.setParent(functionScope); +// bindingScope = bindingScopeStack.removeLast(); +// functionScope.setParent(bindingScope); + + + final IC99Scope undoScope = bindingScopeStack.removeLast(); + + C99FunctionScope functionScope = new C99FunctionScope(); + functionScope.setBodyScope(undoScope); + undoScope.setParent(functionScope); + functionScope.setParent(bindingScopeStack.getLast()); + + + final DeclaratorFrame frame = declarationStack.removeLast(); + + // the function binding needs to be available outside of the function's scope + String functionName = frame.getDeclaratorName().toString(); + C99Function functionBinding = (C99Function) symbolTable.lookup(IDENTIFIER, functionName); + functionBinding.setFunctionScope(functionScope); + + final C99SymbolTable undoTable = symbolTable; + final C99SymbolTable outerTable = symbolTableScopeStack.removeLast(); + symbolTable = outerTable.insert(IDENTIFIER, functionName, functionBinding); + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTableScopeStack.add(outerTable); + symbolTable = undoTable; + declarationStack.add(frame); + bindingScopeStack.add(undoScope); + } + }); + } + + + public void consumeAbstractDeclaratorFunctionDeclarator() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.setFunctionDeclarator(true); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + frame.setFunctionDeclarator(false); + } + }); + } + + + public void consumeDirectDeclaratorFunctionDeclarator() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.setFunctionDeclarator(true); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.setFunctionDeclarator(false); + } + }); + } + + + public void consumeDeclSpecToken() { + if(DEBUG) DebugUtil.printMethodTrace(); + + IToken token = parser.getRightIToken(); + final int kind = token.getKind(); + + // creates a DeclSpec if there isn't one already + DeclaratorFrame frame = declarationStack.getLast(); + final DeclSpec declSpec = frame.getDeclSpec(); + declSpec.add(kind); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declSpec.remove(kind); + } + }); + } + + + /** + * A labeled statement is creates an implicit declaration of the label identifier. + * + * TODO: a label has function scope, meaning the same label cannot be declared twice + * in a function regardless of block scope. + * TODO: labels can be implicitly declared, that is a goto can exist above the label + */ + public IBinding consumeStatementLabeled() { + if(DEBUG) DebugUtil.printMethodTrace(); + + IToken token = parser.getLeftIToken(); + String ident = token.toString(); + + IC99Binding labelBinding = new C99Label(ident); + // TODO: strictly speaking the same label cannot be declared twice, + // but we aren't checking that here + final C99SymbolTable oldTable = symbolTable; + symbolTable = symbolTable.insert(GOTO_LABEL, ident, labelBinding); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTable = oldTable; + } + }); + + return labelBinding; + } + + + public IBinding consumeStatementGoto() { + if(DEBUG) DebugUtil.printMethodTrace(); + + List<IToken> ruleTokens = parser.getRuleTokens(); + assert ruleTokens.size() == 3 : "a goto statement must always consist of 3 tokens"; //$NON-NLS-1$ + String ident = ruleTokens.get(1).toString(); + + final C99SymbolTable oldTable = symbolTable; + + IC99Binding labelBinding = symbolTable.lookup(GOTO_LABEL, ident); + if(labelBinding == null) { + labelBinding = new C99Label(ident); + symbolTable = symbolTable.insert(GOTO_LABEL, ident, labelBinding); + } + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + symbolTable = oldTable; + } + }); + + + return labelBinding; + } + + + public IBinding consumeDeclarationSpecifiersTypedefName() { + if(DEBUG) DebugUtil.printMethodTrace(); + + // find the typedef token + String typedefName = null; + for(IToken token : parser.getRuleTokens()) { + // the token kind will still be TK_identifier, but there can only be one + if(token.getKind() == C99Parsersym.TK_identifier) { + typedefName = token.toString(); + break; + } + } + assert typedefName != null : "a typedef token must have been parsed for this action to fire"; //$NON-NLS-1$ + + // we know that the binding is a typedef because the lexer feedback hack worked and got us here + ITypedef binding = (ITypedef) symbolTable.lookup(IDENTIFIER, typedefName); + // TODO: do I need to clone the typedef in case it is further modified like with const? + DeclaratorFrame frame = declarationStack.getLast(); + final DeclSpec declSpec = frame.getDeclSpec(); + declSpec.setType(binding); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + declSpec.setType(null); + } + }); + + return binding; + } + + + + public void consumeDirectDeclaratorIdentifier() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + DebugUtil.printMethodTrace(); + frame.setDeclaratorName(parser.getRightIToken()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + DebugUtil.printMethodTrace(); + frame.setDeclaratorName(null); + } + }); + } + + + + // TODO need to be careful, this is called in a lot of places in the grammar + public void consumeDeclaratorWithPointer() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + final LinkedList<C99PointerType> scope = frame.closePointerModifierScope(); + final int scopeSize = scope.size(); + + for(C99PointerType pt : reverseIterable(scope)) { + frame.addTypeModifier(pt); + } + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + for(int i = 0; i < scopeSize; i++) { + frame.removeLastTypeModifier(); + } + frame.openPointerModifierScope(scope); + } + }); + } + + + + public void consumeDirectDeclaratorBracketed() { + if(DEBUG) DebugUtil.printMethodTrace(); + + // Used to tell the difference between function prototype declarations and function pointer declarations + final DeclaratorFrame frame = declarationStack.getLast(); + frame.setDeclaratorBracketed(true); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.setDeclaratorBracketed(false); + } + }); + } + + + public IBinding consumeDeclaratorComplete() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + + IToken token = frame.getDeclaratorName(); + IType type = frame.getDeclaratorType(); + DeclSpec declSpec = frame.getDeclSpec(); + boolean isFunction = frame.isFunctionDeclarator(); + List<IBinding> nestedDeclarators = frame.getNestedDeclarations(); + + if(isFunction) + type = createFunctionType(type, nestedDeclarators); + + String ident = (token == null) ? null : token.toString(); + + // compute the binding + IC99Binding binding; + if(declSpec.isTypedef()) + binding = createTypedefBinding(ident, type); + else if(isFunction && !frame.isDeclaratorBracketed()) + binding = createFunctionBinding(ident, (IFunctionType)type, declSpec, nestedDeclarators); + else + binding = createVariableBinding(ident, type, declSpec); + + binding.setScope(bindingScopeStack.getLast()); + + // insert into symbol table + final C99SymbolTable oldTable = symbolTable; + if(ident != null) + symbolTable = symbolTable.insert(IDENTIFIER, ident, binding); + + declarationStack.removeLast(); + declarationStack.add(new DeclaratorFrame(frame.getDeclSpec())); // reset the declarator + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + exprTypeStack.pop(); + declarationStack.removeLast(); + declarationStack.add(frame); + symbolTable = oldTable; + } + }); + + return binding; + } + + /** + * Just gets rid of the type that was on the type stack. + */ + public void consumeInitDeclarator() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final IType type = exprTypeStack.pop(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + exprTypeStack.push(type); + } + }); + } + + + public IBinding consumeFunctionDefinitionHeader() { + if(DEBUG) DebugUtil.printMethodTrace(); + + DeclaratorFrame frame = declarationStack.getLast(); + DeclSpec declSpec = frame.getDeclSpec(); + String functionName = frame.getDeclaratorName().toString(); + + final C99SymbolTable oldTable = symbolTable; + + // there may have been a function prototype, hence there may already be a binding for the function + IC99Binding binding = symbolTable.lookup(IDENTIFIER, functionName); + if(binding == null) { + IType type = frame.getDeclaratorType(); + List<IBinding> nestedDeclarators = frame.getNestedDeclarations(); + + IFunctionType functionType = createFunctionType(type, nestedDeclarators); + binding = createFunctionBinding(functionName, functionType, declSpec, nestedDeclarators); + + // a scope has already been opened for the function body, use the outer scope + IC99Scope topScope = bindingScopeStack.removeLast(); + binding.setScope(bindingScopeStack.getLast()); + bindingScopeStack.add(topScope); + + symbolTable = symbolTable.insert(IDENTIFIER, functionName, binding); + } + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + symbolTable = oldTable; + } + }); + + return binding; + } + + + public IBinding consumeDeclaratorCompleteParameter() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + IToken token = frame.getDeclaratorName(); + IType type = frame.getDeclaratorType(); + DeclSpec declSpec = frame.getDeclSpec(); + boolean isFunction = frame.isFunctionDeclarator(); + + // its a function pointer + if(isFunction) + type = createFunctionType(type, frame.getNestedDeclarations()); + + String ident = (token == null) ? NO_IDENT : token.toString(); + + IC99Binding parameterBinding = createParameterBinding(ident, type, declSpec); + parameterBinding.setScope(bindingScopeStack.getLast()); + + // check to see if there is already a parameter binding + String functionName = declarationStack.getLast().getDeclaratorName().toString(); + C99Function function = (C99Function) symbolTable.lookup(IDENTIFIER, functionName); + + if(function != null) { + // there is already a function binding for this function, that means there + // is a function prototype and there is already a binding for this parameter + int position = declarationStack.getLast().getNestedDeclarations().size(); + IParameter[] parameters = function.getParameters(); + if(parameters != null && position < parameters.length) { + parameterBinding = (IC99Binding)parameters[position]; + } + } + + // even if the binding is reused it still might be under a different name + final C99SymbolTable oldTable = symbolTable; + if(ident != null) { + symbolTable = symbolTable.insert(IDENTIFIER, ident, parameterBinding); + } + + declarationStack.getLast().addNestedDeclaration(parameterBinding); + + // parameter declarations can only have one declarator, so don't reset + //declarationStack.add(new DeclaratorFrame()); // reset + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + //declarationStack.removeLast(); + declarationStack.getLast().removeLastNestedDeclaration(); + declarationStack.add(frame); + symbolTable = oldTable; + } + }); + + return parameterBinding; + } + + + /** + * This is a special case for the rule: + * parameter_declaration ::= declaration_specifiers + * + * In this case there is no declarator at all + * + * TODO: creating bindings that have no identifier seems really dumb, + * why does it need to be done? Why not just have a null binding or + * for that matter don't even have a name node + * + */ + public IBinding consumeParameterDeclarationWithoutDeclarator() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + DeclSpec declSpec = frame.getDeclSpec(); + C99Parameter param = createParameterBinding(null, declSpec.getType(), declSpec); + declarationStack.getLast().addNestedDeclaration(param); + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + declarationStack.getLast().removeLastNestedDeclaration(); + declarationStack.add(frame); + } + }); + + return param; + } + + + public IBinding consumeDeclaratorCompleteField() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + IToken token = frame.getDeclaratorName(); + IType type = frame.getDeclaratorType(); + + // its a function pointer + if(frame.isFunctionDeclarator()) + type = createFunctionType(type, frame.getNestedDeclarations()); + + IBinding binding = createFieldBinding(token.toString(), type, frame.getDeclSpec()); + + declarationStack.removeLast(); + declarationStack.getLast().addNestedDeclaration(binding); + declarationStack.add(new DeclaratorFrame(frame.getDeclSpec())); // reset the declarator + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + declarationStack.removeLast(); + declarationStack.getLast().removeLastNestedDeclaration(); + declarationStack.add(frame); + } + }); + + return binding; + } + + + /** + * An abstract declarator used as part of an expression, eg) a cast. + * Only need the type. + * + * TODO: this isn't enough, I need a binding for the abstract declarator + * what I really need is a consumeDeclaratorCompleteTypeId similar to above + */ + public void consumeTypeId() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + IType type = frame.getDeclaratorType(); + if(frame.isFunctionDeclarator()) // its a function pointer + type = createFunctionType(type, frame.getNestedDeclarations()); + + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + declarationStack.add(frame); + } + }); + } + + + public void consumeDirectDeclaratorArrayModifier() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.addTypeModifier(new C99ArrayType()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.removeLastTypeModifier(); + } + }); + } + + + public void consumeAbstractDeclaratorArrayModifier() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.addTypeModifier(new C99ArrayType()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.removeLastTypeModifier(); + } + }); + } + + + public void consumeDirectDeclaratorModifiedArrayModifier(boolean isStatic, boolean isVarSized, boolean hasTypeQualifierList) { + if(DEBUG) DebugUtil.printMethodTrace(); + + C99ArrayType arrayType = new C99ArrayType(); + arrayType.setStatic(isStatic); + arrayType.setVariableLength(isVarSized); + + if(hasTypeQualifierList) { + arrayType.setConst(typeQualifiers.isConst); + arrayType.setRestrict(typeQualifiers.isRestrict); + arrayType.setVolatile(typeQualifiers.isVolatile); + } + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.addTypeModifier(arrayType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.removeLastTypeModifier(); + } + }); + } + + + + public void consumePointer() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.addPointerModifier(new C99PointerType()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.removeLastPointerModifier(); + } + }); + } + + + public void consumePointerTypeQualifierList() { + if(DEBUG) DebugUtil.printMethodTrace(); + + C99PointerType pointerType = new C99PointerType(); + pointerType.setConst(typeQualifiers.isConst); + pointerType.setRestrict(typeQualifiers.isRestrict); + pointerType.setVolatile(typeQualifiers.isVolatile); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.addPointerModifier(pointerType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.removeLastPointerModifier(); + } + }); + } + + + public void consumeTypeQualifiers() { + if(DEBUG) DebugUtil.printMethodTrace(); + + typeQualifiers = new TypeQualifiers(); + + for(IToken token : parser.getRuleTokens()) { + switch(token.getKind()) { + case C99Parsersym.TK_const: + typeQualifiers.isConst = true; + break; + case C99Parsersym.TK_restrict: + typeQualifiers.isRestrict = true; + break; + case C99Parsersym.TK_volatile: + typeQualifiers.isVolatile = true; + break; + } + } + + // I don't think this is really necessary but I need an undo action anyway + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + typeQualifiers = null; + } + }); + } + + + + /** + * Works for structs, unions and enums. + * If the struct tag is not in the symbol table then it is treated + * as a declaration. + */ + public IBinding consumeTypeSpecifierElaborated(int kind) { + if(DEBUG) DebugUtil.printMethodTrace(); + + String tag = parser.getRightIToken().toString(); + + IC99Binding structBinding = symbolTable.lookup(STRUCT_TAG, tag); + + final C99SymbolTable undoTable; + + final boolean isDeclaration = (structBinding == null); + + if(isDeclaration) { // declaration of an incomplete type + if(kind == IASTElaboratedTypeSpecifier.k_enum) + structBinding = new C99Enumeration(); + else + structBinding = new C99Structure(kind); + + undoTable = symbolTable; + symbolTable = symbolTable.insert(STRUCT_TAG, tag, structBinding); + } + else { + undoTable = null; // final variable must be initialized + } + + final DeclSpec declSpec = declarationStack.getLast().getDeclSpec(); + declSpec.setType((IType)structBinding); // upcast + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + declSpec.setType(null); + + if(isDeclaration) { + assert undoTable != null; + symbolTable = undoTable; + } + } + }); + + return structBinding; + } + + + /** + * @param key A field in IASTCompositeTypeSpecifier. + */ + public IBinding consumeTypeSpecifierComposite(final boolean hasName, int key) { + if(DEBUG) DebugUtil.printMethodTrace(); + + // If the symbol table isn't updated then its still ok to undo + // because setting symbolTable to oldTable will effectively be a no-op. + final C99SymbolTable oldTable = symbolTable; + + C99Structure struct; + if(hasName) { + String ident = parser.getRuleTokens().get(1).toString(); + struct = (C99Structure) symbolTable.lookup(STRUCT_TAG, ident); // structure may have already been declared + if(struct == null) { + struct = new C99Structure(ident, key); + symbolTable = symbolTable.insert(STRUCT_TAG, ident, struct); + } + } + else { + struct = new C99Structure(key); + } + + final DeclaratorFrame frame = declarationStack.getLast(); + for(IBinding binding : frame.getNestedDeclarations()) { + // the parser may allow invalid declarations like typedefs inside of structures, ignore those + if(binding instanceof C99Field) { + C99Field field = (C99Field)binding; + struct.addField(field); + field.setCompositeTypeOwner(struct); + } + } + + frame.getDeclSpec().setType(struct); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.getDeclSpec().setType(null); + symbolTable = oldTable; + } + }); + + return struct; + } + + + public IBinding consumeTypeSpecifierEnumeration(final boolean hasName) { + if(DEBUG) DebugUtil.printMethodTrace(); + + C99Enumeration enumeration = new C99Enumeration(); + + final C99SymbolTable oldTable = symbolTable; + if(hasName) { + String ident = parser.getRuleTokens().get(1).toString(); + enumeration.setName(ident); + symbolTable = symbolTable.insert(STRUCT_TAG, ident, enumeration); + } + + final DeclaratorFrame frame = declarationStack.getLast(); + for(IBinding binding : frame.getNestedDeclarations()) { + C99Enumerator enumerator = (C99Enumerator)binding; + enumeration.addEnumerator(enumerator); + enumerator.setType(enumeration); + } + + frame.getDeclSpec().setType(enumeration); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + frame.getDeclSpec().setType(null); + if(hasName) + symbolTable = oldTable; + } + }); + + return enumeration; + } + + + + public IBinding consumeEnumerator(boolean hasInitializer) { + if(DEBUG) DebugUtil.printMethodTrace(); + + IToken token = parser.getLeftIToken(); + String ident = token.toString(); + C99Enumerator enumerator = new C99Enumerator(ident); + + final C99SymbolTable oldTable = symbolTable; + symbolTable = symbolTable.insert(IDENTIFIER, ident, enumerator); + + // enumerators are not declarations in the standard sense, so a scope won't be opened for them + declarationStack.getLast().addNestedDeclaration(enumerator); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + declarationStack.getLast().removeLastNestedDeclaration(); + symbolTable = oldTable; + } + }); + + return enumerator; + } + + + + public IField consumeDesignatorBaseField() { + if(DEBUG) DebugUtil.printMethodTrace(); + + + IType baseType = getInitializerType(); + String fieldName = parser.getRightIToken().toString(); + + C99Field fieldBinding = computeFieldBinding(baseType, fieldName, false); + IType type = fieldBinding == null ? C99ProblemBinding.badType() : fieldBinding.getType(); + + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + } + }); + + return fieldBinding; + } + + + + private IType getInitializerType() { + List<IType> outerScope = exprTypeStack.outerScope(); + return outerScope.get(outerScope.size()-1); + } + + + public void consumeDesignatorBaseArray() { + if(DEBUG) DebugUtil.printMethodTrace(); + + IType baseType = getInitializerType(); + + IType type = C99ProblemBinding.badType(); + if(baseType instanceof C99ArrayType) { + type = ((C99ArrayType)baseType).getType(); + } + + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + } + }); + } + + public void consumeInitializerStartPositional() { + if(DEBUG) DebugUtil.printMethodTrace(); + DebugUtil.printMethodTrace(); + + IType type = getInitializerType(); + type = rawType(type); + + IType positionType; + if(type instanceof C99Structure) { + int position = exprTypeStack.topScope().size(); + C99Field field = (C99Field)((C99Structure)type).getFields()[position]; + positionType = field.getType(); + } + else if(type instanceof IArrayType) { + positionType = ((C99ArrayType)type).getType(); + } + else { + positionType = C99ProblemBinding.badType(); + } + + exprTypeStack.push(positionType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + } + }); + } + + + private static C99FunctionType createFunctionType(IType returnType, List<IBinding> parameterDeclarations) { + C99FunctionType functionType = new C99FunctionType(); + functionType.setReturnType(returnType); + for(IBinding b : parameterDeclarations) { + C99Variable parameter = (C99Variable) b; + functionType.addParameterType(parameter.getType()); + } + return functionType; + } + + + + // helper functions for creating binding objects + + private static C99Function createFunctionBinding(String ident, IFunctionType type, DeclSpec declSpec) { + C99Function func = new C99Function(ident == null ? NO_IDENT : ident, type); + declSpec.modifyBinding(func); + return func; + } + + private static C99Function createFunctionBinding(String ident, IFunctionType type, DeclSpec declSpec, List<IBinding> params) { + C99Function func = createFunctionBinding(ident, type, declSpec); + for(IBinding b : params) { + func.addParameter((IParameter)b); + } + return func; + } + + private static C99Field createFieldBinding(String ident, IType type, DeclSpec declSpec) { + C99Field var = new C99Field(ident == null ? NO_IDENT : ident); + var.setType(type); + declSpec.modifyBinding(var); + return var; + } + + private static C99Parameter createParameterBinding(String ident, IType type, DeclSpec declSpec) { + C99Parameter param = new C99Parameter(ident == null ? NO_IDENT : ident); + param.setType(type); + declSpec.modifyBinding(param); + return param; + } + + private static C99Variable createVariableBinding(String ident, IType type, DeclSpec declSpec) { + C99Variable var = new C99Variable(ident == null ? NO_IDENT : ident); + var.setType(type); + declSpec.modifyBinding(var); + return var; + } + + private static C99Typedef createTypedefBinding(String ident, IType type) { + return new C99Typedef(type, ident == null ? NO_IDENT : ident); + } + + + + public void openTypeScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + exprTypeStack.openScope(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.closeScope(); + } + }); + } + + + + public void consumeExpressionConstant(int kind) { + if(DEBUG) DebugUtil.printMethodTrace(); + + //super.consumeExpressionConstant(kind); + // TODO: this is incomplete, what about double constants, int constants with long suffix etc + String constant = parser.getRightIToken().toString(); + + IType type = null; + switch(kind) { + case IASTLiteralExpression.lk_char_constant: + if(constant.startsWith("L")) {//unsigned short int + C99BasicType charType = new C99BasicType(IBasicType.t_int); + charType.setShort(true); + charType.setUnsigned(true); + type = charType; + } + else + type = new C99BasicType(IBasicType.t_char); + break; + + case IASTLiteralExpression.lk_float_constant: + C99BasicType floatType; + if(constant.contains("f") || constant.contains("F")) + floatType = new C99BasicType(IBasicType.t_float); + else + floatType = new C99BasicType(IBasicType.t_double); + + if(constant.contains("l") || constant.contains("L")) + floatType.setLong(true); + + type = floatType; + break; + + case IASTLiteralExpression.lk_integer_constant: + C99BasicType intType = new C99BasicType(IBasicType.t_int); + if(constant.contains("l") || constant.contains("L")) + intType.setLong(true); + + if(constant.contains("ll") || constant.contains("LL")) { + intType.setLongLong(true); + intType.setLong(false); + } + if(constant.contains("u") || constant.contains("U")) + intType.setUnsigned(true); + + type = intType; + break; + + case IASTLiteralExpression.lk_string_literal: + type = new C99PointerType(new C99BasicType(IBasicType.t_char)); + break; + + default: + assert false : "can't get here"; //$NON-NLS-1$ + } + + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + } + }); + } + + + public IBinding consumeExpressionID() { + if(DEBUG) DebugUtil.printMethodTrace(); + + IToken token = parser.getRightIToken(); + String ident = token.toString(); + IBinding binding = symbolTable.lookup(IDENTIFIER, ident); + + IType type = C99ProblemBinding.badType(); + if(binding instanceof ITypeable) + type = ((ITypeable)binding).getType(); + + exprTypeStack.push(type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + } + }); + + return binding; + } + + + public IField consumeExpressionFieldReference(boolean isPointerDereference) { + if(DEBUG) DebugUtil.printMethodTrace(); + + String memberName = parser.getRightIToken().toString(); + final IType identType = exprTypeStack.pop(); + + C99Field field = computeFieldBinding(identType, memberName, isPointerDereference); + IType resultType = field == null ? C99ProblemBinding.badType() : field.getType(); + + exprTypeStack.push(resultType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + exprTypeStack.push(identType); + } + }); + + return field; + } + + /** + * Computes the type of a field member access in an expression. + * eg) x.a; computes the type of a + */ + private C99Field computeFieldBinding(IType identType, String memberName, boolean isPointerDereference) { + try { + IType type = identType; + if(isPointerDereference) { + if(type instanceof IPointerType) + type = ((ITypeContainer)type).getType(); // do the dereference + else + return null; + } + + type = rawType(type); + if(type instanceof ICompositeType) { + ICompositeType struct = (ICompositeType) type; + return (C99Field) struct.findField(memberName); + } + } catch(DOMException _) {} + + return null; + } + + + // TODO In C a function name can be used without parenthesis, the result is the address of + // the function (which is an int I think). This means an identifier that happens to be + // a function name should probably evaluate to an int, and then if it subsequently gets parsed + // as a function call we can look up its function type from the symbol table. + public void consumeExpressionFunctionCall(final boolean hasArgs) { + if(DEBUG) DebugUtil.printMethodTrace(); + + final List<IType> scope = hasArgs ? exprTypeStack.closeScope() : null; + final IType identifierType = exprTypeStack.pop(); + + IType resultType = C99ProblemBinding.badType(); + + if(identifierType instanceof IFunctionType) { + // TODO: check the parameter types + IFunctionType functionType = (IFunctionType)identifierType; + try { + resultType = functionType.getReturnType(); + } catch (DOMException e) { } // do nothing, the problem binding is fine + } + + exprTypeStack.push(resultType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + exprTypeStack.push(identifierType); + if(hasArgs) + exprTypeStack.openScope(scope); + } + }); + } + + + public void consumeExpressionArraySubscript() { + if(DEBUG) DebugUtil.printMethodTrace(); + + // Not doing type checking so it doesn't matter that this is integral type + final IType subscriptType = exprTypeStack.pop(); + final IType exprType = exprTypeStack.pop(); + + IType resultType = C99ProblemBinding.badType(); + if(exprType instanceof IArrayType) { + IArrayType arrType = (IArrayType) exprType; + try { + resultType = arrType.getType(); // strip off the array type + } catch (DOMException e) { } + } + + exprTypeStack.push(resultType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + exprTypeStack.push(exprType); + exprTypeStack.push(subscriptType); + } + }); + } + + + public void consumeExpressionUnaryOperator(int operator) { + if(DEBUG) DebugUtil.printMethodTrace(); + + // TODO: this is lazy, need to check the actual rules for types and operators + final IType expressionType = exprTypeStack.pop(); + + IType resultType = new C99BasicType(IBasicType.t_int); + exprTypeStack.push(resultType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + exprTypeStack.push(expressionType); + } + }); + } + + + public void consumeExpressionUnarySizeofTypeName() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final IType typeNameType = exprTypeStack.pop(); + + IType resultType = new C99BasicType(IBasicType.t_int); + exprTypeStack.push(resultType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + exprTypeStack.push(typeNameType); + } + }); + } + + + public void consumeExpressionCast() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final IType exprType = exprTypeStack.pop(); + + // pop then push is no-op + //IType castType = exprTypeStack.pop(); + //exprTypeStack.push(castType); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.push(exprType); + } + }); + } + + + public void consumeExpressionTypeIdInitializer() { + if(DEBUG) DebugUtil.printMethodTrace(); + + // Throw away the types of the initializer list + final List<IType> scope = exprTypeStack.closeScope(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.openScope(scope); + } + }); + } + + public void consumeExpressionInitializer() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final IType type = exprTypeStack.pop(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + exprTypeStack.push(type); + } + }); + } + + + public void consumeExpressionBinaryOperator(int op) { + if(DEBUG) DebugUtil.printMethodTrace(); + + final IType op2type = exprTypeStack.pop(); + final IType op1type = exprTypeStack.pop(); + + switch(op) { + case IASTBinaryExpression.op_assign: + case IASTBinaryExpression.op_multiplyAssign: + case IASTBinaryExpression.op_divideAssign: + case IASTBinaryExpression.op_moduloAssign: + case IASTBinaryExpression.op_plusAssign: + case IASTBinaryExpression.op_minusAssign: + case IASTBinaryExpression.op_shiftLeftAssign: + case IASTBinaryExpression.op_shiftRightAssign: + case IASTBinaryExpression.op_binaryAndAssign: + case IASTBinaryExpression.op_binaryXorAssign: + case IASTBinaryExpression.op_binaryOrAssign: + exprTypeStack.push(op1type); + break; + + default: + IType resultType = new C99BasicType(IBasicType.t_int); + exprTypeStack.push(resultType); + } + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + exprTypeStack.pop(); + exprTypeStack.push(op1type); + exprTypeStack.push(op2type); + } + }); + } + + public void consumeExpressionConditional() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final IType expr2Type = exprTypeStack.pop(); + final IType expr1Type = exprTypeStack.pop(); + final IType condType = exprTypeStack.pop(); + exprTypeStack.push(expr1Type); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + exprTypeStack.pop(); + exprTypeStack.push(condType); + exprTypeStack.push(expr1Type); + exprTypeStack.push(expr2Type); + } + }); + } + +// // TODO: expression lists are changing +// public void consumeExpressionList(boolean baseCase) { +// // This is a hack, the type of an expression +// // list will be the first expression in the list. +// if(!baseCase) { +// exprTypeStack.pop(); +// } +// } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/C99TypedefTrackerParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/C99TypedefTrackerParserAction.java new file mode 100644 index 00000000000..7667e1d80df --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/C99TypedefTrackerParserAction.java @@ -0,0 +1,355 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.action.deprecated; + +import java.util.LinkedList; + +import lpg.lpgjavaruntime.IToken; + +import org.eclipse.cdt.core.dom.lrparser.IParserActionTokenProvider; +import org.eclipse.cdt.core.parser.util.DebugUtil; +import org.eclipse.cdt.internal.core.dom.lrparser.symboltable.TypedefSymbolTable; +/** + * A simple set of trial and undo actions that just keep track + * of typedef names. This information is then fed back to the parser + * in order to disambiguate certain parser grammar rules. + * + * The command design pattern is used to implement undo actions. + * + * @author Mike Kucera + */ +public class C99TypedefTrackerParserAction { + + private static final boolean DEBUG = true; + + + // provides limited access to the token stream + private final IParserActionTokenProvider parser; + + // The symbolTable currently in use + private TypedefSymbolTable symbolTable = TypedefSymbolTable.EMPTY_TABLE; + + // A stack that keeps track of scopes in the symbol table, used to "close" scopes and to undo the opening of scopes + private final LinkedList<TypedefSymbolTable> symbolTableScopeStack = new LinkedList<TypedefSymbolTable>(); + + // keeps track of nested declarations + private final LinkedList<DeclaratorFrame> declarationStack = new LinkedList<DeclaratorFrame>(); + + + // "For every action there is an equal and opposite reaction." - Newton's third law + private final LinkedList<IUndoAction> undoStack = new LinkedList<IUndoAction>(); + + + /** + * A command object that provides undo functionality. + */ + private interface IUndoAction { + void undo(); + } + + + /** + * Undoes the last fired action. + */ + public void undo() { + undoStack.removeLast().undo(); + } + + + public C99TypedefTrackerParserAction(IParserActionTokenProvider parser) { + this.parser = parser; + } + + + /** + * Lexer feedback hack, used by the parser to identify typedefname tokens. + */ + public boolean isTypedef(String ident) { + return symbolTable.contains(ident); + } + + + /** + * Methods used by tests, package local access. + */ + TypedefSymbolTable getSymbolTable() { + return symbolTable; + } + + int undoStackSize() { + return undoStack.size(); + } + + LinkedList<DeclaratorFrame> getDeclarationStack() { + return declarationStack; + } + + + /** + * Called from the grammar file in places where a scope is created. + * + * Scopes are created by compound statements, however special care + * must also be taken with for loops because they may contain + * declarations. + * + * TODO: scope object now need to be handled explicitly + */ + public void openSymbolScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTableScopeStack.add(symbolTable); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTable = symbolTableScopeStack.removeLast(); + } + }); + } + + + public void closeSymbolScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final TypedefSymbolTable undoTable = symbolTable; + symbolTable = symbolTableScopeStack.removeLast(); // close the scope + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTableScopeStack.add(symbolTable); + symbolTable = undoTable; + } + }); + } + + + + /** + * Called from the grammar before a declaration is about to be reduced. + */ + public void openDeclarationScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.add(new DeclaratorFrame()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.removeLast(); + } + }); + } + + + public void closeDeclarationScope() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame undoFrame = declarationStack.removeLast(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.add(undoFrame); + } + }); + } + + + public void consumeFunctionDefinition() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + + final TypedefSymbolTable undoTable = symbolTable; + symbolTable = symbolTableScopeStack.removeLast(); + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + symbolTableScopeStack.add(symbolTable); + symbolTable = undoTable; + + declarationStack.add(frame); + } + }); + } + + + + + public void consumeDeclSpecToken() { + if(DEBUG) DebugUtil.printMethodTrace(); + + IToken token = parser.getRightIToken(); + final int kind = token.getKind(); + + // creates a DeclSpec if there isn't one already + DeclaratorFrame frame = declarationStack.getLast(); + final DeclSpec declSpec = frame.getDeclSpec(); + declSpec.add(kind); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declSpec.remove(kind); + } + }); + } + + + + public void consumeDirectDeclaratorIdentifier() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + frame.setDeclaratorName(parser.getRightIToken()); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + frame.setDeclaratorName(null); + } + }); + } + + + public void consumeDeclaratorComplete() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.getLast(); + + IToken token = frame.getDeclaratorName(); + DeclSpec declSpec = frame.getDeclSpec(); + + String ident = (token == null) ? null : token.toString(); + //System.out.println("declarator complete: " + ident); + + final TypedefSymbolTable oldTable = symbolTable; + if(declSpec.isTypedef()) { + //System.out.println("adding typedef: " + ident); + symbolTable = symbolTable.add(ident); + } + + declarationStack.removeLast(); + declarationStack.add(new DeclaratorFrame(frame.getDeclSpec())); // reset the declarator + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.removeLast(); + declarationStack.add(frame); + symbolTable = oldTable; + } + }); + } + + + + + public void consumeDeclaratorCompleteParameter() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + + //declarationStack.getLast().addNestedDeclaration(parameterBinding); + + // parameter declarations can only have one declarator, so don't reset + //declarationStack.add(new DeclaratorFrame()); // reset + + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + //declarationStack.removeLast(); + //declarationStack.getLast().removeLastNestedDeclaration(); + declarationStack.add(frame); + } + }); + } + + + /** + * This is a special case for the rule: + * parameter_declaration ::= declaration_specifiers + * + * In this case there is no declarator at all + * + * TODO: creating bindings that have no identifier seems really dumb, + * why does it need to be done? Why not just have a null binding or + * for that matter don't even have a name node + * + */ + public void consumeParameterDeclarationWithoutDeclarator() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.add(frame); + } + }); + } + + + public void consumeDeclaratorCompleteField() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + + declarationStack.add(new DeclaratorFrame(frame.getDeclSpec())); // reset the declarator + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.removeLast(); + + declarationStack.add(frame); + } + }); + } + + + /** + * An abstract declarator used as part of an expression, eg) a cast. + * Only need the type. + * + * TODO: this isn't enough, I need a binding for the abstract declarator + * what I really need is a consumeDeclaratorCompleteTypeId similar to above + */ + public void consumeTypeId() { + if(DEBUG) DebugUtil.printMethodTrace(); + + final DeclaratorFrame frame = declarationStack.removeLast(); + + undoStack.add(new IUndoAction() { + public void undo() { + if(DEBUG) DebugUtil.printMethodTrace(); + + declarationStack.add(frame); + } + }); + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/DeclSpec.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/DeclSpec.java new file mode 100644 index 00000000000..e6eeaa5c6dc --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/DeclSpec.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.action.deprecated; + +import static org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym.*; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.c.ICBasicType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99BasicType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Function; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99QualifierType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable; + +/** + * Keeps track of declaration specifiers during the parse. + * Used to compute types and determine if a declarator is a typedef. + * + * @author Mike Kucera + */ +class DeclSpec { + + // maps token kinds to the number of occurrences of that kind + private Map<Integer,Integer> tokenKindMap = new HashMap<Integer,Integer>(); + + private IType type = null; + + + public void add(int kind) { + tokenKindMap.put(kind, count(kind) + 1); + } + + public void remove(final int kind) { + Integer count = tokenKindMap.get(kind); + if(count == null) + return; + + if(count <= 1) + tokenKindMap.remove(kind); + else + tokenKindMap.put(kind, count - 1); + } + + public boolean contains(int kind) { + return tokenKindMap.containsKey(kind); + } + + + public boolean isTypedef() { + return contains(C99Parsersym.TK_typedef); + } + + /** + * Need to keep track of how many times a particular + * declaration specifier appears in order to support + * long long. + */ + public int count(int kind) { + Integer count = tokenKindMap.get(kind); + return count == null ? 0 : count; + } + + /** + * Set if the type should be a structure. + */ + public void setType(IType type) { + this.type = type; + } + + + + public IType getType() { + if(type != null) + return type; + if(tokenKindMap.isEmpty()) // there are no type tokens, so it must be implicit int + return new C99BasicType(ICBasicType.t_int); + + C99BasicType basicType = new C99BasicType(); + + for(int kind : tokenKindMap.keySet()) { + switch(kind) { + case TK_void: + basicType.setType(ICBasicType.t_void); + break; + case TK_char: + basicType.setType(ICBasicType.t_char); + break; + case TK_int: + basicType.setType(ICBasicType.t_int); + break; + case TK_float: + basicType.setType(ICBasicType.t_float); + break; + case TK_double: + basicType.setType(ICBasicType.t_double); + break; + case TK_long: + boolean isLongLong = count(TK_long) > 1; + basicType.setLongLong(isLongLong); + basicType.setLong(!isLongLong); + break; + case TK_signed: + basicType.setSigned(true); + break; + case TK_unsigned: + basicType.setUnsigned(true); + break; + case TK_short: + basicType.setShort(true); + break; + case TK__Bool: + basicType.setType(ICBasicType.t_Bool); + break; + case TK__Complex: + basicType.setComplex(true); + break; + case TK__Imaginary: + basicType.setImaginary(true); + break; + } + } + + boolean isConst = contains(TK_const); + boolean isRestrict = contains(TK_restrict); + boolean isVolatile = contains(TK_volatile); + + if(isConst || isRestrict || isVolatile) + return new C99QualifierType(basicType, isConst, isVolatile, isRestrict); + else + return basicType; + } + + + public void modifyBinding(C99Variable var) { + if(!var.isAuto()) + var.setAuto(contains(TK_auto)); + if(!var.isExtern()) + var.setExtern(contains(TK_extern)); + if(!var.isRegister()) + var.setRegister(contains(TK_register)); + if(!var.isStatic()) + var.setStatic(contains(TK_static)); + } + + public void modifyBinding(C99Function function) { + if(!function.isAuto()) + function.setAuto(contains(TK_auto)); + if(!function.isExtern()) + function.setExtern(contains(TK_extern)); + if(!function.isInline()) + function.setInline(contains(TK_inline)); + if(!function.isRegister()) + function.setRegister(contains(TK_register)); + if(!function.isStatic()) + function.setStatic(contains(TK_static)); + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/DeclaratorFrame.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/DeclaratorFrame.java new file mode 100644 index 00000000000..9adc96c9b5f --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/action/deprecated/DeclaratorFrame.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.action.deprecated; + +import java.util.LinkedList; +import java.util.List; + +import lpg.lpgjavaruntime.IToken; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99PointerType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; + +/** + * Represents a frame on the declaration stack used by the resolver actions. + * + * TODO: document this class better + * + * @author Mike Kucera + */ +@SuppressWarnings("restriction") +public class DeclaratorFrame { + private DeclSpec declSpec; + //IBinding declarator; + private IToken declaratorName; + private boolean isDeclaratorBracketed; + private boolean isFunctionDeclarator = false; + + // temporary storage for pointer modifiers + private LinkedList<LinkedList<C99PointerType>> pointerModifiers = new LinkedList<LinkedList<C99PointerType>>(); + + // stores pointer and array modifiers that are applied to the declarator + private LinkedList<ITypeContainer> typeModifiers = new LinkedList<ITypeContainer>(); + + private LinkedList<IBinding> nestedDeclarations = new LinkedList<IBinding>(); + + + public DeclaratorFrame() { + } + + public DeclaratorFrame(DeclSpec declSpec) { + this.declSpec = declSpec; + } + + + public DeclSpec getDeclSpec() { + if(declSpec == null) + declSpec = new DeclSpec(); + + return declSpec; + } + + public IType getDeclaratorType() { + // the declSpec may be null, so use getDeclSpec() + IType baseType = getDeclSpec().getType(); + + if(typeModifiers.isEmpty()) + return baseType; + + IType type = typeModifiers.get(0); + + // link the types together + for(int i = 1; i < typeModifiers.size(); i++) { + ITypeContainer t1 = typeModifiers.get(i-1); + ITypeContainer t2 = typeModifiers.get(i); + t1.setType(t2); + } + + ITypeContainer last = typeModifiers.get(typeModifiers.size()-1); + last.setType(baseType); + return type; + } + + public IToken getDeclaratorName() { + return declaratorName; + } + public void setDeclaratorName(IToken declaratorName) { + this.declaratorName = declaratorName; + } + public boolean isDeclaratorBracketed() { + return isDeclaratorBracketed; + } + public void setDeclaratorBracketed(boolean isDeclaratorBracketed) { + this.isDeclaratorBracketed = isDeclaratorBracketed; + } + public boolean isFunctionDeclarator() { + return isFunctionDeclarator; + } + public void setFunctionDeclarator(boolean isFunctionDeclarator) { + this.isFunctionDeclarator = isFunctionDeclarator; + } + + public List<IBinding> getNestedDeclarations() { + return nestedDeclarations; + } + + public void addNestedDeclaration(IBinding binding) { + nestedDeclarations.add(binding); + } + + public void removeLastNestedDeclaration() { + nestedDeclarations.removeLast(); + } + + public void addTypeModifier(ITypeContainer x) { + typeModifiers.add(x); + } + + public void removeLastTypeModifier() { + typeModifiers.removeLast(); + } + + public void addPointerModifier(C99PointerType x) { + pointerModifiers.getLast().add(x); + } + + public void removeLastPointerModifier() { + pointerModifiers.getLast().removeLast(); + } + + public void openPointerModifierScope() { + pointerModifiers.add(new LinkedList<C99PointerType>()); + } + + public void openPointerModifierScope(LinkedList<C99PointerType> scope) { + pointerModifiers.add(scope); + } + + public LinkedList<C99PointerType> closePointerModifierScope() { + return pointerModifiers.removeLast(); + } +} + diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99ArrayType.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99ArrayType.java new file mode 100644 index 00000000000..398de9359ae --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99ArrayType.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.c.ICArrayType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; + +public class C99ArrayType implements ICArrayType, ITypeContainer { + + private boolean isConst; + private boolean isRestrict; + private boolean isStatic; + private boolean isVolatile; + private boolean isVariableLength; + + private IType type; + + + public C99ArrayType() { + } + + public C99ArrayType(IType type) { + this.type = type; + } + + public boolean isConst() { + return isConst; + } + + public void setConst(boolean isConst) { + this.isConst = isConst; + } + + public boolean isRestrict() { + return isRestrict; + } + + public void setRestrict(boolean isRestrict) { + this.isRestrict = isRestrict; + } + + public boolean isStatic() { + return isStatic; + } + + public void setStatic(boolean isStatic) { + this.isStatic = isStatic; + } + + public boolean isVolatile() { + return isVolatile; + } + + public void setVolatile(boolean isVolatile) { + this.isVolatile = isVolatile; + } + + public boolean isVariableLength() { + return isVariableLength; + } + + public void setVariableLength(boolean isVariableLength) { + this.isVariableLength = isVariableLength; + } + + public IASTExpression getArraySizeExpression() throws DOMException { + return null; + } + + public IType getType() { + return type; + } + + public void setType(IType type) { + this.type = type; + } + + public boolean isSameType(IType t) { + if(t == this) + return true; + if(t instanceof ITypedef) + return t.isSameType(this); + if(t instanceof ICArrayType) { + ICArrayType at = (ICArrayType)t; + try { + if(at.isConst() == isConst && + at.isRestrict() == isRestrict && + at.isStatic() == isStatic && + at.isVolatile() == isVolatile && + at.isVariableLength() == isVariableLength) { + return at.isSameType(type); + } + } catch(DOMException _) { } + } + return false; + } + + + public C99ArrayType clone() { + C99ArrayType clone = null; + try { + clone = (C99ArrayType) super.clone(); + clone.type = (IType) type.clone(); + } catch (CloneNotSupportedException e) { + assert false; // not going to happen + } + return clone; + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99BasicType.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99BasicType.java new file mode 100644 index 00000000000..32d391ba56a --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99BasicType.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.c.ICBasicType; + +public class C99BasicType implements ICBasicType { + + /* Type flags given in IBasicType */ + private int type; + + private boolean isLong; + private boolean isShort; + private boolean isSigned; + private boolean isUnsigned; + private boolean isComplex; + private boolean isImaginary; + private boolean isLongLong; + + + public C99BasicType() { + } + + public C99BasicType(int type) { + this.type = type; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public boolean isLong() { + return isLong; + } + + public void setLong(boolean isLong) { + this.isLong = isLong; + } + + public boolean isShort() { + return isShort; + } + + public void setShort(boolean isShort) { + this.isShort = isShort; + } + + public boolean isSigned() { + return isSigned; + } + + public void setSigned(boolean isSigned) { + this.isSigned = isSigned; + } + + public boolean isUnsigned() { + return isUnsigned; + } + + public void setUnsigned(boolean isUnsigned) { + this.isUnsigned = isUnsigned; + } + + public boolean isComplex() { + return isComplex; + } + + public void setComplex(boolean isComplex) { + this.isComplex = isComplex; + } + + public boolean isImaginary() { + return isImaginary; + } + + public void setImaginary(boolean isImaginary) { + this.isImaginary = isImaginary; + } + + public boolean isLongLong() { + return isLongLong; + } + + public void setLongLong(boolean isLongLong) { + this.isLongLong = isLongLong; + } + + public IASTExpression getValue() { + return null; + } + + public boolean isSameType(IType t) { + if(t == this) + return true; + if(!(t instanceof C99BasicType)) + return false; + + C99BasicType bt = (C99BasicType) t; + return bt.type == this.type && + bt.isLong == this.isLong && + bt.isShort == this.isShort && + bt.isSigned == this.isSigned && + bt.isUnsigned == this.isUnsigned && + bt.isComplex == this.isComplex && + bt.isImaginary == this.isImaginary && + bt.isLongLong == this.isLongLong; + } + + public C99BasicType clone() { + try { + return (C99BasicType) super.clone(); + } catch (CloneNotSupportedException e) { + assert false; + return null; + } + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99CompositeTypeScope.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99CompositeTypeScope.java new file mode 100644 index 00000000000..d7c30ac260c --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99CompositeTypeScope.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope; + +public class C99CompositeTypeScope extends C99Scope implements ICCompositeTypeScope { + + + private ICompositeType struct; + + + public C99CompositeTypeScope(ICompositeType struct) { + this.struct = struct; + } + + public ICompositeType getCompositeType() { + return struct; + } + + public IBinding getBinding(char[] name) throws DOMException { + throw new UnsupportedOperationException(); + } + + + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java new file mode 100644 index 00000000000..0edb9bd1da8 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Enumeration extends PlatformObject implements IC99Binding, IEnumeration, ITypeable { + + private List<IEnumerator> enumerators = new ArrayList<IEnumerator>(); + private String name; + + private IScope scope; + + + public C99Enumeration() { + } + + public C99Enumeration(String name) { + this.name = name; + } + + public void addEnumerator(IEnumerator e) { + enumerators.add(e); + } + + public IEnumerator[] getEnumerators() { + return enumerators.toArray(new IEnumerator[enumerators.size()]); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public char[] getNameCharArray() { + return name.toCharArray(); + } + + + public IType getType() { + return this; + } + + public boolean isSameType(IType type) { + if( type == this ) + return true; + if( type instanceof ITypedef) + return type.isSameType( this ); + + return false; + } + + public C99Enumeration clone() { + try { + C99Enumeration clone = (C99Enumeration) super.clone(); + clone.enumerators = new ArrayList<IEnumerator>(); + for(IEnumerator e : enumerators) { + // TODO this is wrong, + // IEnumerator is not Cloneable so we are not returning a deep copy here + clone.addEnumerator(e); + } + return clone; + } catch (CloneNotSupportedException e1) { + assert false; + return null; + } + + } + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public IScope getScope() { + return scope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } + + + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumerator.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumerator.java new file mode 100644 index 00000000000..f5c6fa23727 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumerator.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Enumerator extends PlatformObject implements IC99Binding, IEnumerator, ITypeable { + + private String name; + private IType type; + private IScope scope; + + + public C99Enumerator() { + } + + public C99Enumerator(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public IType getType() { + return type; + } + + public void setType(IType type) { + this.type = type; + } + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public char[] getNameCharArray() { + return name.toCharArray(); + } + + public IScope getScope() { + return scope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Field.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Field.java new file mode 100644 index 00000000000..9404cc15053 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Field.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IScope; + +public class C99Field extends C99Variable implements IC99Binding, IField, ITypeable { + + private ICompositeType compositeTypeOwner; + + + public C99Field() { + } + + public C99Field(String name) { + super(name); + } + + public ICompositeType getCompositeTypeOwner() { + return compositeTypeOwner; + } + + public void setCompositeTypeOwner(ICompositeType compositeTypeOwner) { + this.compositeTypeOwner = compositeTypeOwner; + } + + public IScope getScope() { + try { + return compositeTypeOwner.getCompositeScope(); + } catch (DOMException e) { + return null; // should never happen + } + } + + +}
\ No newline at end of file diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Function.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Function.java new file mode 100644 index 00000000000..9e15f32cbf1 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Function.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Function extends PlatformObject implements IC99Binding, IFunction, ITypeable { + + private String name; + private IFunctionType type; + private List<IParameter> parameters = new ArrayList<IParameter>(); + + private boolean isAuto; + private boolean isExtern; + private boolean isInline; + private boolean isRegister; + private boolean isStatic; + private boolean isVarArgs; + + // the scope that the function is in (must be the global scope, no?) + private IScope scope; + + // the scope that represents the body of the function + private IScope bodyScope; + + + public C99Function() { + } + + public C99Function(String name) { + this.name = name; + } + + public C99Function(String name, IFunctionType type) { + this(name); + this.type = type; + } + + + public IParameter[] getParameters() { + return parameters.toArray(new IParameter[parameters.size()]); + } + + public void addParameter(IParameter parameter) { + parameters.add(parameter); + } + + public IFunctionType getType() { + return type; + } + + public void setType(IFunctionType type) { + this.type = type; + } + + public boolean isAuto() { + return isAuto; + } + + public void setAuto(boolean isAuto) { + this.isAuto = isAuto; + } + + public boolean isExtern() { + return isExtern; + } + + public void setExtern(boolean isExtern) { + this.isExtern = isExtern; + } + + public boolean isInline() { + return isInline; + } + + public void setInline(boolean isInline) { + this.isInline = isInline; + } + + public boolean isRegister() { + return isRegister; + } + + public void setRegister(boolean isRegister) { + this.isRegister = isRegister; + } + + public boolean isStatic() { + return isStatic; + } + + public void setStatic(boolean isStatic) { + this.isStatic = isStatic; + } + + public boolean takesVarArgs() { + return isVarArgs; + } + + public void setTakesVarArgs(boolean isVarArgs) { + this.isVarArgs = isVarArgs; + } + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public char[] getNameCharArray() { + return name.toCharArray(); + } + + public IScope getScope() { + return scope; + } + + public IScope getFunctionScope() { + return bodyScope; + } + + public void setFunctionScope(IScope bodyScope) { + this.bodyScope = bodyScope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99FunctionScope.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99FunctionScope.java new file mode 100644 index 00000000000..c4a11f2e9f7 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99FunctionScope.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; + +public class C99FunctionScope extends C99Scope implements ICFunctionScope { + + + /** + * Scope that represents the compound statement of the body of this scope. + * Does not include the parameters which are part of this function scope. + */ + private IScope bodyScope; + + + public IBinding getBinding(char[] name) throws DOMException { + // TODO Auto-generated method stub + return null; + } + + public void setBodyScope(IScope bodyScope) { + this.bodyScope = bodyScope; + } + + public IScope getBodyScope() throws DOMException { + return bodyScope; + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99FunctionType.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99FunctionType.java new file mode 100644 index 00000000000..51a7cf2e7aa --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99FunctionType.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IType; + +public class C99FunctionType implements IFunctionType { + + private IType returnType; + private List<IType> parameterTypes = new ArrayList<IType>(); + + public IType[] getParameterTypes() { + return parameterTypes.toArray(new IType[parameterTypes.size()]); + } + + public void addParameterType(IType parameterType) { + parameterTypes.add(parameterType); + } + + public IType getReturnType() { + return returnType; + } + + public void setReturnType(IType returnType) { + this.returnType = returnType; + } + + public boolean isSameType(IType type) { + // TODO Auto-generated method stub + return false; + } + + public C99FunctionType clone() { + try { + C99FunctionType clone = (C99FunctionType) super.clone(); + clone.setReturnType((IType)returnType.clone()); + clone.parameterTypes = new ArrayList<IType>(); + for(IType parameterType : parameterTypes) { + clone.addParameterType((IType)parameterType.clone()); + } + return clone; + } catch (CloneNotSupportedException e) { + assert false; + return null; + } + + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Label.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Label.java new file mode 100644 index 00000000000..964e9bd820f --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Label.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; +import org.eclipse.cdt.core.dom.ast.ILabel; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Label extends PlatformObject implements IC99Binding, ILabel { + + private String name; + private IScope scope; + + public C99Label() { + } + + public C99Label(String name) { + this.name = name; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public char[] getNameCharArray() { + return name.toCharArray(); + } + + + + public IASTLabelStatement getLabelStatement() { + return null; + } + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public IScope getScope() { + return scope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Parameter.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Parameter.java new file mode 100644 index 00000000000..31e8aa81a2c --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Parameter.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.IParameter; + +public class C99Parameter extends C99Variable implements IParameter, ITypeable { + + public C99Parameter() { + } + + public C99Parameter(String name) { + super(name); + } + + public static C99Parameter valueOf(C99Variable var) { + C99Parameter param = new C99Parameter(var.getName()); + param.setType(var.getType()); + param.setAuto(var.isAuto()); + param.setExtern(var.isExtern()); + param.setRegister(var.isRegister()); + param.setStatic(var.isStatic()); + return param; + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99PointerType.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99PointerType.java new file mode 100644 index 00000000000..3bd44ae4f25 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99PointerType.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.c.ICPointerType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; + + +public class C99PointerType implements ITypeContainer, ICPointerType { + + + private IType type; + private boolean isConst; + private boolean isRestrict; + private boolean isVolatile; + + public C99PointerType() { + } + + + public C99PointerType(IType type) { + this.type = type; + } + + public IType getType() { + return type; + } + + public void setType(IType type) { + this.type = type; + } + + public boolean isConst() { + return isConst; + } + + public void setConst(boolean isConst) { + this.isConst = isConst; + } + + public boolean isRestrict() { + return isRestrict; + } + + public void setRestrict(boolean isRestrict) { + this.isRestrict = isRestrict; + } + + public boolean isVolatile() { + return isVolatile; + } + + public void setVolatile(boolean isVolatile) { + this.isVolatile = isVolatile; + } + + + public boolean isSameType(IType t) { + if(t == this) + return true; + + if (t instanceof ICPointerType) { + try { + ICPointerType pointerType = (ICPointerType) t; + if(pointerType.isConst() == isConst && + pointerType.isRestrict() == isRestrict && + pointerType.isVolatile() == isVolatile) { + return type.isSameType(pointerType.getType()); + } + } catch(DOMException _) { } + } + return false; + } + + + + public C99PointerType clone() { + try { + C99PointerType clone = (C99PointerType) super.clone(); + clone.type = (IType) type.clone(); + return clone; + } catch (CloneNotSupportedException e) { + assert false; + return null; + } + + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99ProblemBinding.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99ProblemBinding.java new file mode 100644 index 00000000000..97e822af261 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99ProblemBinding.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; + +public class C99ProblemBinding extends ProblemBinding implements IProblemBinding { + + + public C99ProblemBinding(int messageId) { + super(null, messageId, null); + } + + public C99ProblemBinding(int messageId, String arg) { + super(null, messageId, arg.toCharArray()); + } + + public static C99ProblemBinding badType() { + return new C99ProblemBinding(IProblemBinding.SEMANTIC_INVALID_TYPE); + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99QualifierType.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99QualifierType.java new file mode 100644 index 00000000000..97fd0fe92c8 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99QualifierType.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.c.ICQualifierType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; + +public class C99QualifierType implements ICQualifierType, ITypeContainer { + + private boolean isRestrict; + private boolean isConst; + private boolean isVolatile; + + private IType type; + + + public C99QualifierType() { + } + + public C99QualifierType(IType type) { + this.type = type; + } + + public C99QualifierType(IType type, boolean isConst, boolean isVolatile, boolean isRestrict) { + this.isConst = isConst; + this.isRestrict = isRestrict; + this.isVolatile = isVolatile; + this.type = type; + } + + public boolean isRestrict() { + return isRestrict; + } + + public void setRestrict(boolean isRestrict) { + this.isRestrict = isRestrict; + } + + public boolean isConst() { + return isConst; + } + + public void setConst(boolean isConst) { + this.isConst = isConst; + } + + public boolean isVolatile() { + return isVolatile; + } + + public void setVolatile(boolean isVolatile) { + this.isVolatile = isVolatile; + } + + public IType getType() { + return type; + } + + public void setType(IType type) { + this.type = type; + } + + public boolean isSameType(IType t) { + if(t == this) + return true; + + if (t instanceof ICQualifierType) { + try { + ICQualifierType pointerType = (ICQualifierType) t; + if(pointerType.isConst() == isConst && + pointerType.isRestrict() == isRestrict && + pointerType.isVolatile() == isVolatile) { + return type.isSameType(pointerType.getType()); + } + } catch(DOMException _) { } + } + return false; + } + + + public C99QualifierType clone() { + try { + C99QualifierType clone = (C99QualifierType) super.clone(); + clone.type = (IType) type.clone(); + return clone; + } catch (CloneNotSupportedException e) { + assert false; + return null; + } + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java new file mode 100644 index 00000000000..da0c949d71d --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.index.IIndexFileSet; +import org.eclipse.cdt.internal.core.dom.lrparser.symboltable.C99SymbolTable; +import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; + +/** + * @author Mike Kucera + * + */ +public class C99Scope implements IC99Scope, IASTInternalScope { + + + + private IScope parent; + private IASTNode physicalNode; + private IName scopeName; + + + + + + public IScope getParent() { + return parent; + } + + public void setParent(IScope parent) { + this.parent = parent; + } + + public IASTNode getPhysicalNode() { + return physicalNode; + } + + public void setPhysicalNode(IASTNode physicalNode) { + this.physicalNode = physicalNode; + } + + public IName getScopeName() { + return scopeName; + } + + public void setScopeName(IName scopeName) { + this.scopeName = scopeName; + } + + + public IBinding[] find(String name) { + throw new UnsupportedOperationException(); + } + + public IBinding getBinding(IASTName name, boolean resolve) { + throw new UnsupportedOperationException(); + } + + public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { + throw new UnsupportedOperationException(); + } + + + + + public void addBinding(IBinding binding) { + throw new UnsupportedOperationException(); + } + + public void addName(IASTName name) { + throw new UnsupportedOperationException(); + } + + public void flushCache() { + + } + + public boolean isFullyCached() { + return true; + } + + public void removeBinding(IBinding binding) { + + } + + public void setFullyCached(boolean b) { + + } + + public IBinding getBinding(IASTName name, boolean resolve, + IIndexFileSet acceptLocalBindings) throws DOMException { + // TODO Auto-generated method stub + return null; + } + + public IBinding[] getBindings(IASTName name, boolean resolve, + boolean prefixLookup, IIndexFileSet acceptLocalBindings) + throws DOMException { + // TODO Auto-generated method stub + return null; + } + + + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Structure.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Structure.java new file mode 100644 index 00000000000..e5d883647d0 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Structure.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Structure extends PlatformObject implements IC99Binding, ICompositeType, ITypeable { + + + private Map<String,IField> fields = new LinkedHashMap<String,IField>(); + private IField[] fieldArray = null; + + /** either t_union or t_structure defined in IASTCompositeTypeSpecifier */ + private int key; + private String name; + + private IScope scope; + + public C99Structure() { + } + + public C99Structure(String name) { + this.name = name; + } + + public C99Structure(int key) { + this.key = key; + } + + public C99Structure(String name, int key) { + this.name = name; + this.key = key; + } + + public void addField(IField field) { + fields.put(field.getName(), field); + fieldArray = null; + } + + public IField findField(String name) { + return fields.get(name); + } + + public IScope getCompositeScope() { +// C99Scope scope = new C99CompositeTypeScope(this); +// scope.setScopeName(nameNode); +// return scope; + return null; + } + + public IField[] getFields() { + if(fieldArray == null) + fieldArray = fields.values().toArray(new IField[fields.size()]); + return fieldArray; + } + + public void setKey(int key) { + this.key = key; + } + + public int getKey() { + return key; + } + + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public char[] getNameCharArray() { + if(name == null) + return new char[0]; + + return name.toCharArray(); + } + + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public IType getType() { + return this; + } + + public boolean isSameType(IType type) { + if(type == this) + return true; + if( type instanceof ITypedef) + return type.isSameType( this ); + return false; + } + + //private Map<String,IField> fields = new LinkedHashMap<String,IField>(); + //private IField[] fieldArray = null; + + + //private IScope scope; + + public C99Structure clone() { + try { + C99Structure clone = (C99Structure) super.clone(); + //clone.scope = (IScope) scope.clone(); TODO + clone.fieldArray = null; + clone.fields = new LinkedHashMap<String,IField>(); + for(IField field : fields.values()) + clone.addField(field); // TODO not a deep clone + return clone; + } catch (CloneNotSupportedException e) { + assert false; + return null; + } + } + + public IScope getScope() { + return scope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Typedef.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Typedef.java new file mode 100644 index 00000000000..967d027b60c --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Typedef.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Typedef extends PlatformObject implements IC99Binding, ITypedef, ITypeContainer, ITypeable { + + private IType type; + private String name; + + private IScope scope; + + + public C99Typedef() { + } + + public C99Typedef(IType type) { + this.type = type; + } + + public C99Typedef(IType type, String name) { + this.type = type; + this.name = name; + } + + + public IType getType() { + return type; + } + + public void setType(IType type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public char[] getNameCharArray() { + return name.toCharArray(); + } + + + public boolean isSameType(IType t) { + if(t == this) + return true; + + try { + if(t instanceof ITypedef) + return type.isSameType(((ITypedef)t).getType()); + else + return type.isSameType(t); + } catch(DOMException _) { + return false; + } + } + + public C99Typedef clone() { + try { + C99Typedef clone = (C99Typedef) super.clone(); + clone.type = (IType) type.clone(); + return clone; + } catch (CloneNotSupportedException e) { + assert false; + return null; + } + } + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public IScope getScope() { + return scope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Variable.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Variable.java new file mode 100644 index 00000000000..3ce77ab6785 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Variable.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.core.runtime.PlatformObject; + +public class C99Variable extends PlatformObject implements IC99Binding, IVariable, ITypeable { + + + private boolean isAuto; + private boolean isExtern; + private boolean isRegister; + private boolean isStatic; + + private String name; + private IType type; + + private IScope scope; + + public C99Variable() { + + } + + public C99Variable(String name) { + this.name = name; + } + + + public void setType(IType type) { + this.type = type; + } + + public IType getType() { + return type; + } + + + public void setAuto(boolean auto) { + this.isAuto = auto; + } + + public boolean isAuto() { + return isAuto; + } + + + public void setExtern(boolean extern) { + this.isExtern = extern; + } + + public boolean isExtern() { + return isExtern; + } + + + public void setRegister(boolean isRegister) { + this.isRegister = isRegister; + } + + public boolean isRegister() { + return isRegister; + } + + + public void setStatic(boolean isStatic) { + this.isStatic = isStatic; + } + + public boolean isStatic() { + return isStatic; + } + + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public char[] getNameCharArray() { + return name.toCharArray(); + } + + public ILinkage getLinkage() { + return Linkage.C_LINKAGE; + } + + public IScope getScope() { + return scope; + } + + public void setScope(IScope scope) { + this.scope = scope; + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/IC99Binding.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/IC99Binding.java new file mode 100644 index 00000000000..a928b923ce4 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/IC99Binding.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; + +public interface IC99Binding extends IBinding { + + void setScope(IScope scope); +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/IC99Scope.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/IC99Scope.java new file mode 100644 index 00000000000..629bd3c416c --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/IC99Scope.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICScope; + + +/** + * TODO maybe rename to IC99InternalScope or something else. + * + * @author Mike Kucera + */ +public interface IC99Scope extends ICScope { + + void setParent(IScope parent); + + void setPhysicalNode(IASTNode node); + + void setScopeName(IName name); +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/ITypeable.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/ITypeable.java new file mode 100644 index 00000000000..ca9129e39d9 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/ITypeable.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings; + +import org.eclipse.cdt.core.dom.ast.IType; + +public interface ITypeable { + IType getType(); +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/C99SymbolTable.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/C99SymbolTable.java new file mode 100644 index 00000000000..53e954384d7 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/C99SymbolTable.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.symboltable; + + +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.IC99Binding; + +/** + * A facade for a FunctionalMap to make it behave like + * a symbol table for C99. + * + * In particular we need to be able to lookup identifiers based both + * on the String representation of the identifier and its "namespace". + * + * @author Mike Kucera + */ +public class C99SymbolTable { + + /** + * Adapter objects are used as the keys. The trick here is to implement + * compareTo() in such a way that identifiers are separated by their namespace. + */ + private static class Key implements Comparable<Key> { + private final String ident; + private final CNamespace namespace; + + public Key(CNamespace namespace, String ident) { + if(namespace == null || ident == null) + throw new NullPointerException(); + + this.ident = ident; + this.namespace = namespace; + } + + public int compareTo(Key x) { + // this separates namespaces in the symbol table + int c = namespace.compareTo(x.namespace); + // only if the namespace is the same do we check the identifier + return (c == 0) ? ident.compareTo(x.ident) : c; + } + + @Override public String toString() { + return ident + "::" + namespace;//$NON-NLS-1$ + } + } + + /** + * Start with EMPTY_TABLE and build up a symbol table using insert(). + */ + public static final C99SymbolTable EMPTY_TABLE = new C99SymbolTable(); + + + // the map we are providing a facade for + private final FunctionalMap<Key,IC99Binding> map; + + + /** + * Constructors are private, start with EMPTY_TABLE + * and build it up using insert(). + */ + private C99SymbolTable() { + map = FunctionalMap.emptyMap(); + } + + private C99SymbolTable(FunctionalMap<Key,IC99Binding> newRoot) { + map = newRoot; + } + + /** + * Returns a new symbol table that contains the given mapping. + * @throws NullPointerException if the namespace or key is null. + */ + public C99SymbolTable insert(CNamespace ns, String key, IC99Binding binding) { + return new C99SymbolTable(map.insert(new Key(ns, key), binding)); + } + + /** + * Looks up the binding given its namespace and identifier. + * @return null If there is no binding corresponding to the key. + * @throws NullPointerException if the namespace or key is null. + */ + public IC99Binding lookup(CNamespace ns, String key) { + return map.lookup(new Key(ns, key)); + } + + public int size() { + return map.size(); + } + + public boolean isEmpty() { + return map.size() == 0; + } + + @Override public String toString() { + return map.toString(); + } + +// void printStructure() { +// map.printStructure(); +// } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/CImperativeSymbolTable.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/CImperativeSymbolTable.java new file mode 100644 index 00000000000..5f06190c641 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/CImperativeSymbolTable.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.symboltable; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ast.IBinding; + + +/** + * Used to compute binding resolution during the parse. + * + * Imperative style symbol table with destructive update. + * + * Consists of two data structures, a hash table for fast lookup + * of bindings given their names, and a stack used to keep track + * of scopes. + * + * + * @author Mike Kucera + */ +public class CImperativeSymbolTable { + + private static final int TABLE_SIZE = 256; + + private Bucket[] table = new Bucket[TABLE_SIZE]; + + private LinkedList<SymbolScope> scopeStack = new LinkedList<SymbolScope>(); + + + + /** + * Represents a scope in the C language. + */ + private static class SymbolScope { + + /** + * List of buckets that have been modified in the current scope. + * When the scope is closed these buckets are popped, returning the + * symbol table to the state it was in before the scope was opened. + */ + List<Integer> modifiedBuckets = new ArrayList<Integer>(); + } + + + /** + * A bucket object used to hold elements in the hash table. + */ + private static class Bucket { + String key; + CNamespace namespace; + IBinding binding; + Bucket next; + + Bucket(Bucket next, CNamespace namespace, String key, IBinding binding) { + this.key = key; + this.namespace = namespace; + this.binding = binding; + this.next = next; + } + } + + + public CImperativeSymbolTable() { + openScope(); // open the global scope + // TODO populate the global scope with built-ins + } + + + /** + * Hashes a key into an index in the hash table. + */ + private int index(String key) { + return Math.abs(key.hashCode() % TABLE_SIZE); + } + + + /** + * Adds a binding to the symbol table in the current scope. + * + * @param mask A bit mask used to identify the namespace of the identifier. + */ + public void put(CNamespace namespace, String ident, IBinding b) { + int index = index(ident); + table[index] = new Bucket(table[index], namespace, ident, b); + + SymbolScope scope = scopeStack.getLast(); + scope.modifiedBuckets.add(index); + } + + + /** + * Returns the binding associated with the given identifier, or + * null if there is none. + * + * @param mask A bit mask used to identify the namespace of the identifier. + */ + public IBinding get(CNamespace namespace, String ident) { + Bucket b = table[index(ident)]; + while(b != null) { + if(namespace == b.namespace && ident.equals(b.key)) + return b.binding; + b = b.next; + } + return null; + } + + + /** + * Opens a new inner scope for identifiers. + * + * If an identifier is added that already exists in an outer scope + * then it will be shadowed. + */ + public void openScope() { + scopeStack.add(new SymbolScope()); + } + + + /** + * Remove all the symbols defined in the scope that is being closed. + * + * @param scope An IScope object that will be used to represent this scope. + * @throws SymbolTableException If the global scope has already been closed or if bindingScope is null. + */ + public void closeScope() { + SymbolScope poppedScope = scopeStack.removeLast(); // pop the scopeStack + + // pop each bucket that was modified in the scope + for(int index : poppedScope.modifiedBuckets) + table[index] = table[index].next; + } + + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder buff = new StringBuilder('['); + for(Bucket b : table) { + while(b != null) { + buff.append('<').append(b.key).append(": ").append(b.binding).append(">, "); + b = b.next; + } + } + return buff.append(']').toString(); + } +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/CNamespace.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/CNamespace.java new file mode 100644 index 00000000000..321a81ccde3 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/CNamespace.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.symboltable; + +/** + * The C language has 4 namespaces for identifiers. + * This enum represents three of them, the "member" namespace + * is represented by IStructure.getFields(). + * + * The symbol table uses these to mark identifiers and keep + * the namespaces separate. + * + * @author Mike Kucera + */ +public enum CNamespace { + + GOTO_LABEL, // goto labels + STRUCT_TAG,// structs, unions, enums + IDENTIFIER; // all other identifiers + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/FunctionalMap.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/FunctionalMap.java new file mode 100644 index 00000000000..ca73f93bd86 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/FunctionalMap.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.symboltable; + + +/** + * An immutable map, like you would find in a functional programming language. + * + * Inserting a new pair into the map leaves the original map untouched, + * instead a new map that contains the pair is returned. Therefore + * an assignment is needed to "modify" the map (just like with Strings). + * + * <code> + * myMap = myMap.insert(key,value); + * </code> + * + * There is no remove() method because it is not needed. In order to + * "delete" a pair from the map simply save a reference to an old version + * of the map and restore the map from that old reference. This makes + * "undo" operations trivial to implement. + * + * <code> + * FunctionalMap oldMap = myMap; // save a reference + * myMap = myMap.insert(key,value); // insert the pair into the map + * myMap = oldMap; // delete the pair from the map + * </code> + * + * This map is implemented as a red-black tree data structure, + * and is based on the implementation found at: + * http://www.eecs.usma.edu/webs/people/okasaki/jfp99.ps + * + * @author Mike Kucera + */ +public class FunctionalMap<K extends Comparable<K>, V> { + + private static final boolean + RED = true, + BLACK = false; + + + private static class Node<K, V> { + final K key; + final V val; + Node<K,V> left; + Node<K,V> right; + boolean color; + + public Node(K key, V val, boolean color, Node<K,V> left, Node<K,V> right) { + this.key = key; + this.val = val; + this.left = left; + this.right = right; + this.color = color; + } + + @SuppressWarnings("nls") + @Override + public String toString() { + return "Node(" + key + "," + val + "," + (color ? "R" : "B") + ")"; + } + } + + + private Node<K,V> root = null; + + + private FunctionalMap() { + // private constructor, use static factory method to instantiate + } + + // factory method makes it cleaner to instantiate objects + public static <K extends Comparable<K>,V> FunctionalMap<K,V> emptyMap() { + return new FunctionalMap<K,V>(); + } + + + /** + * Returns a new map that contains the key-value pair. + * @throws NullPointerException if key is null + */ + public FunctionalMap<K,V> insert(K key, V val) { + if(key == null) + throw new NullPointerException(); + + FunctionalMap<K,V> newMap = new FunctionalMap<K,V>(); + newMap.root = insert(this.root, key, val); + newMap.root.color = BLACK; // force the root to be black + + assert checkInvariants(newMap.root); + + return newMap; + } + + + private Node<K,V> insert(Node<K,V> n, K key, V val) { + if(n == null) + return new Node<K,V>(key, val, RED, null, null); // new nodes are always red + + int c = key.compareTo(n.key); + if(c < 0) + return balance(n.key, n.val, n.color, insert(n.left, key, val), n.right); + else if(c > 0) + return balance(n.key, n.val, n.color, n.left, insert(n.right, key, val)); + else // equal, create a new node that overwrites the old value + return new Node<K,V>(key, val, n.color, n.left, n.right); + } + + + private Node<K,V> balance(K key, V val, boolean color, Node<K,V> left, Node<K,V> right) { + if(color == RED) + return new Node<K,V>(key, val, color, left, right); + + final Node<K,V> newLeft, newRight; + + // now for the madness... + + if(left != null && left.color == RED) { + if(left.left != null && left.left.color == RED) { + newLeft = new Node<K,V>(left.left.key, left.left.val, BLACK, left.left.left, left.left.right); + newRight = new Node<K,V>(key, val, BLACK, left.right, right); + return new Node<K,V>(left.key, left.val, RED, newLeft, newRight); + } + if(left.right != null && left.right.color == RED) { + newLeft = new Node<K,V>(left.key, left.val, BLACK, left.left, left.right.left); + newRight = new Node<K,V>(key, val, BLACK, left.right.right, right); + return new Node<K,V>(left.right.key, left.right.val, RED, newLeft, newRight); + } + } + if(right != null && right.color == RED) { + if(right.left != null && right.left.color == RED) { + newLeft = new Node<K,V>(key, val, BLACK, left, right.left.left); + newRight = new Node<K,V>(right.key, right.val, BLACK, right.left.right, right.right); + return new Node<K,V>(right.left.key, right.left.val, RED, newLeft, newRight); + } + if(right.right != null && right.right.color == RED) { + newLeft = new Node<K,V>(key, val, BLACK, left, right.left); + newRight = new Node<K,V>(right.right.key, right.right.val, BLACK, right.right.left, right.right.right); + return new Node<K,V>(right.key, right.val, RED, newLeft, newRight); + } + } + + return new Node<K,V>(key, val, BLACK, left, right); + } + + + /** + * Returns the value if it is in the map, null otherwise. + * @throws NullPointerException if key is null + */ + public V lookup(K key) { + if(key == null) + throw new NullPointerException(); + + // no need for recursion here + Node<K,V> n = root; + while(n != null) { + int x = key.compareTo(n.key); // throws NPE if key is null + if(x == 0) + return n.val; + n = (x < 0) ? n.left : n.right; + } + return null; + } + + + /** + * Returns true if there exists a mapping with the given key + * in this map. + * @throws NullPointerException if key is null + */ + public boolean containsKey(K key) { + if(key == null) + throw new NullPointerException(); + + // lookup uses an iterative algorithm + Node<K,V> n = root; + while(n != null) { + int x = key.compareTo(n.key); // throws NPE if key is null + if(x == 0) + return true; + n = (x < 0) ? n.left : n.right; + } + return false; + } + + + public boolean isEmpty() { + return root == null; + } + + @Override public String toString() { + StringBuilder sb = new StringBuilder('['); + inorderPrint(root, sb); + sb.append(']'); + return sb.toString(); + } + + private static <K,V> void inorderPrint(Node<K,V> n, StringBuilder sb) { + if(n == null) + return; + + inorderPrint(n.left, sb); + if(sb.length() > 1) + sb.append(", ");//$NON-NLS-1$ + sb.append(n.toString()); + inorderPrint(n.right, sb); + } + + + void printStructure() { + if(root == null) + System.out.println("empty map"); //$NON-NLS-1$ + else + printStructure(root, 0); + } + + private static <K,V> void printStructure(Node<K,V> node, int level) { + for(int i = 0; i < level; i++) + System.out.print("--");//$NON-NLS-1$ + + if(node == null) { + System.out.println("null");//$NON-NLS-1$ + } + else if(node.right == null && node.left == null) { + System.out.println(node); + } + else { + System.out.println(node); + printStructure(node.right, level + 1); + printStructure(node.left, level + 1); + } + } + + + private static <K,V> int depth(Node<K,V> node) { + if(node == null) + return 0; + return Math.max(depth(node.left), depth(node.right)) + 1; + } + + + /** + * Warning, this is a linear operation. + */ + public int size() { + return size(root); + } + + private static <K,V> int size(Node<K,V> node) { + if(node == null) + return 0; + return size(node.left) + size(node.right) + 1; + } + + + + /********************************************************************************************** + * Built-in testing + **********************************************************************************************/ + + + private boolean checkInvariants(Node<K,V> n) { + // the number of black nodes on every path through the tree is the same + assertBalanced(n); + return true; + } + + // not exactly sure if this is right + private int assertBalanced(Node<K,V> node) { + if(node == null) + return 1; // nulls are considered as black children + + // both children of every red node are black + if(node.color == RED) { + assert node.left == null || node.left.color == BLACK; + assert node.right == null || node.right.color == BLACK; + } + + int left = assertBalanced(node.left); + int right = assertBalanced(node.right); + + assert left == right; + + return left + (node.color == BLACK ? 1 : 0); + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/SymbolTableTests.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/SymbolTableTests.java new file mode 100644 index 00000000000..1222eeab09a --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/SymbolTableTests.java @@ -0,0 +1,214 @@ +package org.eclipse.cdt.internal.core.dom.lrparser.symboltable; + +//import junit.framework.TestCase; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Label; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Structure; +import org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings.C99Variable; + +@SuppressWarnings("deprecation") +public class SymbolTableTests {//extends TestCase { + // TODO write tests for imperative symbol table + + private final String[] KEYS = { "pantera", "soulfly", "inflames", "megadeth", "archenemy", "carcass" }; + + public void testPersistence() { + FunctionalMap<String,Integer> st0 = FunctionalMap.emptyMap(); + assertTrue(st0.isEmpty()); + + FunctionalMap<String,Integer> st1 = st0.insert(KEYS[0], 1); + + // empty symbol table does not change + assertTrue(st0.isEmpty()); + assertNull(st0.lookup(KEYS[1])); + + // a new symbol table was created + assertFalse(st1.isEmpty()); + assertEquals(new Integer(1), st1.lookup(KEYS[0])); + + FunctionalMap<String,Integer> st2 = st1.insert(KEYS[1], 2); + FunctionalMap<String,Integer> st3 = st2.insert(KEYS[2], 3); + FunctionalMap<String,Integer> st4 = st3.insert(KEYS[3], 4); + FunctionalMap<String,Integer> st5 = st4.insert(KEYS[4], 5); + + assertMap(st0, KEYS, new Integer[] {null, null, null, null, null, null} ); + assertMap(st1, KEYS, new Integer[] {1, null, null, null, null, null} ); + assertMap(st2, KEYS, new Integer[] {1, 2, null, null, null, null} ); + assertMap(st3, KEYS, new Integer[] {1, 2, 3, null, null, null} ); + assertMap(st4, KEYS, new Integer[] {1, 2, 3, 4, null, null} ); + assertMap(st5, KEYS, new Integer[] {1, 2, 3, 4, 5, null} ); + } + + + + private void assertEquals(Integer integer, Integer lookup) { + // TODO Auto-generated method stub + + } + + + + private void assertFalse(boolean empty) { + // TODO Auto-generated method stub + + } + + + + private void assertNull(Integer lookup) { + // TODO Auto-generated method stub + + } + + + + private void assertTrue(boolean empty) { + // TODO Auto-generated method stub + + } + + + + public void testOverride() { + FunctionalMap<String,Integer> map1 = FunctionalMap.emptyMap(); + for(int i = 0; i < KEYS.length; i++) { + map1 = map1.insert(KEYS[i], i); + } + + assertMap(map1, KEYS, new Integer[] {0, 1, 2, 3, 4, 5}); + + FunctionalMap<String,Integer> map2 = map1.insert(KEYS[5], 999); + FunctionalMap<String,Integer> map3 = map2.insert(KEYS[5], null); + + assertEquals(new Integer(5), map1.lookup(KEYS[5])); + assertEquals(new Integer(999), map2.lookup(KEYS[5])); + assertNull(map3.lookup(KEYS[5])); + } + + + private static void assertMap(FunctionalMap map, Comparable[] keys, Object[] vals) { + assert keys.length == vals.length; + + for(int i = 0; i < keys.length; i++) { + assertEquals( "the key '" + keys[i] + "' did not match", vals[i], map.lookup((keys[i]))); + if(vals[i] != null) { + assertTrue("key '" + keys[i] + "' not in map", map.containsKey(keys[i])); + } + } + } + + + private static void assertTrue(String string, boolean containsKey) { + // TODO Auto-generated method stub + + } + + + + private static void assertEquals(String string, Object object, Object lookup) { + // TODO Auto-generated method stub + + } + + + + public void testFunctionalSymbolTable1() { + C99SymbolTable st = C99SymbolTable.EMPTY_TABLE; + + for(String key : KEYS) { + st = st.insert(CNamespace.IDENTIFIER, key, new C99Variable(key)); + } + for(String key : KEYS) { + st = st.insert(CNamespace.GOTO_LABEL, key, new C99Label(key)); + } + for(String key : KEYS) { + st = st.insert(CNamespace.STRUCT_TAG, key, new C99Structure(key)); + } + + assertFunctionalSymbolTableContainsAllThePairs(st); + } + + public void testFunctionalSymbolTable2() { + C99SymbolTable st = C99SymbolTable.EMPTY_TABLE; + + // same test as above but this time we insert the keys in a different order + for(String key : KEYS) { + st = st.insert(CNamespace.IDENTIFIER, key, new C99Variable(key)); + st = st.insert(CNamespace.GOTO_LABEL, key, new C99Label(key)); + st = st.insert(CNamespace.STRUCT_TAG, key, new C99Structure(key)); + } + + assertFunctionalSymbolTableContainsAllThePairs(st); + } + + private void assertFunctionalSymbolTableContainsAllThePairs(C99SymbolTable st) { + assertEquals(KEYS.length * 3, st.size()); + for(String key : KEYS) { + IBinding b = st.lookup(CNamespace.IDENTIFIER, key); + assertNotNull(b); + C99Variable x = (C99Variable)b; + assertEquals(key, x.getName()); + } + for(String key : KEYS) { + IBinding b = st.lookup(CNamespace.GOTO_LABEL, key); + assertNotNull(b); + C99Label x = (C99Label)b; + assertEquals(key, x.getName()); + } + for(String key : KEYS) { + IBinding b = st.lookup(CNamespace.STRUCT_TAG, key); + assertNotNull(b); + C99Structure x = (C99Structure)b; + assertEquals(key, x.getName()); + } + } + + + private void assertEquals(String key, String name) { + // TODO Auto-generated method stub + + } + + + + private void assertNotNull(IBinding b) { + // TODO Auto-generated method stub + + } + + + + public void testProperFail() { + FunctionalMap<Integer,Integer> map = FunctionalMap.emptyMap(); + try { + map.insert(null, 99); + fail(); + } catch (NullPointerException _) {} + + try { + map.containsKey(null); + fail(); + } catch (NullPointerException _) {} + + try { + map.lookup(null); + fail(); + } catch (NullPointerException _) {} + + C99SymbolTable table = C99SymbolTable.EMPTY_TABLE; + try { + table.insert(null, null, new C99Variable("blah")); //$NON-NLS-1$ + fail(); + } catch (NullPointerException _) {} + + } + + + + private void fail() { + // TODO Auto-generated method stub + + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/TypedefSymbolTable.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/TypedefSymbolTable.java new file mode 100644 index 00000000000..49fca096e37 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/symboltable/TypedefSymbolTable.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2006, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.lrparser.symboltable; + + + +/** + * A facade for a FunctionalMap that is used just to track typedef + * declarations. + * + * This class acts like a set. No information needs to be associated + * with a typedef declaration, all we need to know is if the identifier + * has been declared as a typedef. + * + * @author Mike Kucera + */ +public class TypedefSymbolTable { + + /** + * Start with EMPTY_TABLE and build up a symbol table using add(). + */ + public static final TypedefSymbolTable EMPTY_TABLE = new TypedefSymbolTable(); + + + // the map we are providing a facade for + private final FunctionalMap<String,Object> map; + + + /** + * Constructors are private, start with EMPTY_TABLE + * and build it up using insert(). + */ + private TypedefSymbolTable() { + map = FunctionalMap.emptyMap(); + } + + private TypedefSymbolTable(FunctionalMap<String,Object> newRoot) { + map = newRoot; + } + + + public TypedefSymbolTable add(String typedefIdent) { + return new TypedefSymbolTable(map.insert(typedefIdent, null)); + } + + + public boolean contains(String typedef) { + return map.containsKey(typedef); + } + + public int size() { + return map.size(); + } + + public boolean isEmpty() { + return map.size() == 0; + } + + @Override public String toString() { + return map.toString(); + } + + +} |