| /********************************************************************** |
| * Copyright (c) 2007,2010 IBM Corporation. |
| * 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.ptp.pldt.mpi.analysis.cdt.graphs.impl; |
| |
| import java.util.ArrayList; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.cdt.core.dom.ast.IASTExpression; |
| import org.eclipse.cdt.core.dom.ast.IASTName; |
| import org.eclipse.cdt.core.dom.ast.IASTNode; |
| import org.eclipse.cdt.core.dom.ast.IASTStatement; |
| import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.IBlock; |
| |
| /** |
| * |
| * @author Yuan Zhang |
| * |
| */ |
| public class Block implements IBlock { |
| protected List<IBlock> succs_; |
| protected List<IBlock> preds_; |
| protected IBlock topNext_ = null; |
| protected IBlock botNext_ = null; |
| protected List<IBlock> DOM_ = null; |
| protected List<IBlock> PDOM_ = null; |
| |
| protected static int counter = 0; |
| protected int id; |
| |
| /** "type" tells the type of the content in this block. |
| * A block with expr_type/stmt_type/label_type stores an |
| * expression/statement/labelname, respectively. A block |
| * with continue_join_type is an empty block in a loop |
| * joining regular flows and flows from continue statements. |
| * A block with exit_join_type is an empty block joining |
| * (1) two branches of an if statement (2) all leaving |
| * edges (through break or default statements) of a |
| * switch statement (3) the regular exit from a loop and |
| * irregular exits from break statements of this loop. |
| */ |
| protected int type; |
| public static final int expr_type = 1; |
| public static final int stmt_type = 2; |
| public static final int label_type = 3; |
| public static final int continue_join_type = 4; |
| public static final int exit_join_type = 5; |
| |
| protected IASTNode content_; |
| |
| /** The parent of a block storing a statement is the statement itself; |
| * The parent of a block with a predicate expression is the corresponding |
| * if/loop/switch statement; |
| * The parent of a block with a label is the label statement; |
| * The parent of a block with continue_join_type or exit_join_type |
| * is the corresponding if/loop/switch statement; |
| */ |
| protected IASTStatement parent_; |
| |
| protected Hashtable<String,Object> attrs_; |
| |
| int color; // white = 0, gray = 1, black = 2 |
| |
| public Block(){ |
| id = counter ++; |
| type = 0; |
| content_ = null; |
| parent_ = null; |
| blockInit(); |
| } |
| |
| public Block(IASTNode content, IASTStatement parent, int type){ |
| this(); |
| content_ = content; |
| parent_ = parent; |
| this.type = type; |
| blockInit(); |
| } |
| |
| /** Short-cut constructor for stmt_type block */ |
| public Block(IASTStatement stmt){ |
| this(stmt, stmt, stmt_type); |
| } |
| |
| /** Short-cut constructor for expr_type block */ |
| public Block(IASTExpression expr, IASTStatement parent){ |
| this(expr, parent, expr_type); |
| } |
| |
| /** Short-cut constructor for label_type block */ |
| public Block(IASTName label){ |
| this(label, null, label_type); |
| } |
| |
| protected void blockInit(){ |
| succs_ = new ArrayList<IBlock>(); |
| preds_ = new ArrayList<IBlock>(); |
| DOM_ = new ArrayList<IBlock>(); |
| PDOM_ = new ArrayList<IBlock>(); |
| attrs_ = new Hashtable<String,Object>(); |
| } |
| |
| public int getID(){ |
| return id; |
| } |
| |
| public IASTNode getContent(){ |
| return content_; |
| } |
| |
| public IASTStatement getParent(){ |
| return parent_; |
| } |
| public int getType() {return type;} |
| |
| public boolean search(IASTNode content, IASTStatement parent, int type){ |
| if(this.type != type) return false; |
| if(type == stmt_type){ |
| if(content == content_) return true; |
| else return false; |
| } |
| else if(type == label_type){ |
| if(content instanceof IASTName){ |
| IASTName name = (IASTName)content; |
| IASTName labelName = (IASTName)content_; |
| if(name.toString().equals(labelName.toString())) |
| return true; |
| else return false; |
| } |
| else return false; |
| } |
| else if(type == expr_type){ |
| if(content != null && content == content_) return true; |
| if(content == null && content_ == null && parent_ == parent) |
| return true; |
| else return false; |
| } |
| else if(type == continue_join_type || type == exit_join_type){ |
| if(content != null) return false; |
| if(parent == parent_) return true; |
| else return false; |
| } |
| else return false; |
| } |
| |
| public boolean search(IASTExpression expr, IASTStatement parent){ |
| return search(expr, parent, expr_type); |
| } |
| |
| public boolean search(IASTStatement stmt){ |
| return search(stmt, stmt, stmt_type); |
| } |
| |
| public boolean search(IASTName label){ |
| return search(label, null, label_type); |
| } |
| |
| public IBlock topNext() { |
| return topNext_; |
| } |
| public IBlock getTopNext() { |
| return topNext_; |
| } |
| public void setTopNext(IBlock b){ |
| topNext_ = b; |
| } |
| |
| public IBlock botNext() { |
| return botNext_; |
| } |
| public IBlock getBotNext() { |
| return botNext_; |
| } |
| public void setBotNext(IBlock b){ |
| botNext_ = b; |
| } |
| |
| public List<IBlock> getPreds() { |
| return preds_; |
| } |
| |
| public List<IBlock> getSuccs() { |
| return succs_; |
| } |
| |
| public List<IBlock> getDOM(){ |
| return DOM_; |
| } |
| |
| public void setDOM(List<IBlock> set){ |
| DOM_ = set; |
| } |
| |
| public List<IBlock> getPDOM(){ |
| return PDOM_; |
| } |
| |
| public void setPDOM(List<IBlock> set){ |
| PDOM_ = set; |
| } |
| |
| public void setAttr(String name, Object attr){ |
| attrs_.put(name, attr); |
| } |
| |
| public Object getAttr(String name){ |
| return attrs_.get(name); |
| } |
| |
| /** |
| * Print IBlock information, include id, content (type & raw signature), and successors |
| */ |
| public void print(){ |
| System.out.println(toString()); |
| } |
| public String toString(){ |
| StringBuffer buf = new StringBuffer(); |
| buf.append("Block " + id + ": "); //$NON-NLS-1$ //$NON-NLS-2$ |
| IASTNode content = getContent(); |
| if(content != null) { |
| String type=content.toString(); // a.b.c.Name@abcd |
| type = type.substring(type.lastIndexOf('.')+1); // Name@abcd |
| type=type.substring(0,type.indexOf('@')); |
| buf.append(" "+type+" "+content.getRawSignature()+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| else { |
| buf.append(" Empty block"); //$NON-NLS-1$ |
| buf.append("\n"); //$NON-NLS-1$ |
| } |
| buf.append(" flows to: "); //$NON-NLS-1$ |
| for(Iterator<IBlock> i = succs_.iterator(); i.hasNext();){ |
| buf.append(i.next().getID() + ", "); //$NON-NLS-1$ |
| } |
| buf.append(" \n"); //$NON-NLS-1$ |
| /* |
| System.out.print("Dominator: "); |
| for(Iterator i = DOM_.iterator(); i.hasNext();){ |
| Block dom = (Block)i.next(); |
| System.out.print(dom.getID() + ", "); |
| } |
| System.out.println(" "); |
| */ |
| return buf.toString(); |
| } |
| } |