/******************************************************************************* * Copyright (c) 2005, 2010 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 Rational Software - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.core.runtime.PlatformObject; /** * Binding for a global or a local variable, serves as base class for fields. */ public class CVariable extends PlatformObject implements IInternalVariable, ICInternalBinding { private IASTName[] declarations = null; private IType type = null; public CVariable(IASTName name) { declarations = new IASTName[] { name }; } public IASTNode getPhysicalNode() { return declarations[0]; } public void addDeclaration(IASTName name) { if (name != null && name.isActive()) { declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name); } } /* * (non-Javadoc) * * @see org.eclipse.cdt.core.dom.ast.IVariable#getType() */ public IType getType() { if (type == null && declarations[0].getParent() instanceof IASTDeclarator) type = CVisitor.createType((IASTDeclarator) declarations[0].getParent()); return type; } /* * (non-Javadoc) * * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() */ public String getName() { return declarations[0].toString(); } public char[] getNameCharArray() { return declarations[0].toCharArray(); } /* * (non-Javadoc) * * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() */ public IScope getScope() { IASTDeclarator declarator = (IASTDeclarator) declarations[0].getParent(); return CVisitor.getContainingScope(declarator.getParent()); } public boolean isStatic() { return hasStorageClass(IASTDeclSpecifier.sc_static); } public boolean hasStorageClass(int storage) { if (declarations == null) return false; for (int i = 0; i < declarations.length && declarations[i] != null; i++) { final IASTName name = declarations[i]; IASTNode parent = name.getParent(); while (!(parent instanceof IASTDeclaration)) parent = parent.getParent(); if (parent instanceof IASTSimpleDeclaration) { IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier(); if (declSpec.getStorageClass() == storage) { return true; } } } return false; } /* * (non-Javadoc) * * @see org.eclipse.cdt.core.dom.ast.IVariable#isExtern() */ public boolean isExtern() { return hasStorageClass(IASTDeclSpecifier.sc_extern); } /* * (non-Javadoc) * * @see org.eclipse.cdt.core.dom.ast.IVariable#isAuto() */ public boolean isAuto() { return hasStorageClass(IASTDeclSpecifier.sc_auto); } /* * (non-Javadoc) * * @see org.eclipse.cdt.core.dom.ast.IVariable#isRegister() */ public boolean isRegister() { return hasStorageClass(IASTDeclSpecifier.sc_register); } public ILinkage getLinkage() { return Linkage.C_LINKAGE; } public IASTNode[] getDeclarations() { return declarations; } public IASTNode getDefinition() { return getPhysicalNode(); } public IBinding getOwner() { if (declarations == null || declarations.length == 0) return null; return CVisitor.findDeclarationOwner(declarations[0], true); } public IValue getInitialValue() { return getInitialValue(Value.MAX_RECURSION_DEPTH); } public IValue getInitialValue(int maxDepth) { if (declarations != null) { for (IASTName decl : declarations) { if (decl == null) break; final IValue val = getInitialValue(decl, maxDepth); if (val != null) return val; } } return null; } private IValue getInitialValue(IASTName name, int maxDepth) { IASTDeclarator dtor = findDeclarator(name); if (dtor != null) { IASTInitializer init = dtor.getInitializer(); if (init instanceof IASTEqualsInitializer) { final IASTInitializerClause initClause = ((IASTEqualsInitializer) init) .getInitializerClause(); if (initClause instanceof IASTExpression) { return Value.create((IASTExpression) initClause, maxDepth); } } if (init != null) return Value.UNKNOWN; } return null; } private IASTDeclarator findDeclarator(IASTName name) { IASTNode node = name.getParent(); if (!(node instanceof IASTDeclarator)) return null; return ASTQueries.findOutermostDeclarator((IASTDeclarator) node); } }