001    // This file is part of the program FRYSK.
002    //
003    // Copyright 2007, 2008, Red Hat Inc.
004    //
005    // FRYSK is free software; you can redistribute it and/or modify it
006    // under the terms of the GNU General Public License as published by
007    // the Free Software Foundation; version 2 of the License.
008    //
009    // FRYSK is distributed in the hope that it will be useful, but
010    // WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012    // General Public License for more details.
013    // 
014    // You should have received a copy of the GNU General Public License
015    // along with FRYSK; if not, write to the Free Software Foundation,
016    // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
017    // 
018    // In addition, as a special exception, Red Hat, Inc. gives You the
019    // additional right to link the code of FRYSK with code not covered
020    // under the GNU General Public License ("Non-GPL Code") and to
021    // distribute linked combinations including the two, subject to the
022    // limitations in this paragraph. Non-GPL Code permitted under this
023    // exception must only link to the code of FRYSK through those well
024    // defined interfaces identified in the file named EXCEPTION found in
025    // the source code files (the "Approved Interfaces"). The files of
026    // Non-GPL Code may instantiate templates or use macros or inline
027    // functions from the Approved Interfaces without causing the
028    // resulting work to be covered by the GNU General Public
029    // License. Only Red Hat, Inc. may make changes or additions to the
030    // list of Approved Interfaces. You must obey the GNU General Public
031    // License in all respects for all of the FRYSK code and other code
032    // used in conjunction with FRYSK except the Non-GPL Code covered by
033    // this exception. If you modify this file, you may extend this
034    // exception to your version of the file, but you are not obligated to
035    // do so. If you do not wish to provide this exception without
036    // modification, you must delete this exception statement from your
037    // version and license this file solely under the GPL without
038    // exception.
039    
040    package frysk.scopes;
041    
042    import java.io.PrintWriter;
043    
044    import lib.dwfl.DwException;
045    import lib.dwfl.DwarfDie;
046    import frysk.debuginfo.DebugInfoFrame;
047    import frysk.debuginfo.LocationExpression;
048    import frysk.debuginfo.PieceLocation;
049    import frysk.debuginfo.TypeFactory;
050    import frysk.debuginfo.ValueUnavailableException;
051    import frysk.debuginfo.VariableOptimizedOutException;
052    import frysk.isa.ISA;
053    import frysk.rsl.Log;
054    import frysk.rsl.LogFactory;
055    import frysk.value.Format;
056    import frysk.value.ObjectDeclaration;
057    import frysk.value.Type;
058    import frysk.value.Value;
059    
060    /**
061     * This class contains the static information corresponding to a
062     * language variable.  Given a Frame it is possible to get a Value
063     * corresponding to this Variable
064     */
065    
066    public class Variable implements ObjectDeclaration {
067        
068        private static Log fine = LogFactory.fine(Variable.class);
069        private static Log finest = LogFactory.finest(Variable.class);
070        
071        private Type type;
072        private final DwarfDie variableDie;
073        private final String name;
074        private final LocationExpression locationExpression;
075        private SourceLocation sourceLocation;
076        
077        public Variable(DwarfDie variableDie) {
078            this.type = null;
079            this.variableDie = variableDie;
080            this.name = variableDie.getName();
081            locationExpression = new LocationExpression(variableDie);
082            sourceLocation = SourceLocationFactory.getSourceLocation(variableDie);
083        }
084        
085        public DwarfDie getVariableDie() {
086            return variableDie;
087        }
088        /**
089         * Return the variable's name.
090         */
091        public String getName() {
092            return name;
093        }
094    
095        public Type getType(ISA isa) {
096            fine.log(this, "Entering getType, ISA: ", isa);
097            
098            if(this.type == null){
099                TypeFactory typeFactory = new TypeFactory(isa);
100                this.type = typeFactory.getType(variableDie);
101            }
102            
103            finest.log(this, "Leaving getType, type: ", type);
104            return type;
105        }
106         
107        public long getLineNumber() {
108            return this.sourceLocation.getLine();
109        }
110      
111        public int getColumnNumber() {
112            return this.variableDie.getDeclColumn();
113        }
114      
115        public void toPrint(PrintWriter printWriter, DebugInfoFrame frame) {
116            if (this.getType(frame.getTask().getISA()) == null) {
117                // FIXME: This should just send the request to the Value's
118                // toPrint method and not try to figure out of the Type
119                // information was delt with.
120                printWriter.print("<<unhandled type>>");
121                return;
122            }
123            StringBuilder stringBuilder = new StringBuilder();
124            type.toPrint(stringBuilder, 0);
125            printWriter.print(stringBuilder);
126            printWriter.print(" ");
127            printWriter.print(this.getName());
128    
129        }
130      
131        public void printValue(PrintWriter printWriter, DebugInfoFrame frame){
132            try {
133                Value value = getValue(frame);
134                value.toPrint(printWriter, frame.getTask().getMemory(),
135                              Format.NATURAL, 0);
136            } catch (ValueUnavailableException e) {
137                printWriter.print("< value unavailable at pc=0x"+ Long.toHexString(frame.getAdjustedAddress())+">");
138            } catch (VariableOptimizedOutException e) {
139                printWriter.print("< optimized out >");
140            } catch (RuntimeException e) {
141                printWriter.print("< ERROR >");
142            }
143        }
144        
145        public void printLineCol(PrintWriter printWriter) {
146            printWriter.print("line#");
147            try {
148                printWriter.print(this.getLineNumber());
149            } catch (DwException e) {
150                printWriter.print("< error >");
151            }
152          
153            //      printWriter.print(" col#");
154            //      try {
155            //        printWriter.print(this.getColumnNumber());
156            //      } catch (DwException e) {
157            //        printWriter.print("< error >");
158            //      }
159        }
160    
161        public Value getValue(DebugInfoFrame frame) {
162            ISA isa = frame.getTask().getISA();
163            PieceLocation pieceLocation
164                = new PieceLocation(locationExpression.decode(frame, this.getType(isa)
165                                                              .getSize()));
166            Value value = new Value(this.getType(isa), pieceLocation);
167            return value;
168        }
169        
170        public SourceLocation getSourceLocation() {
171            return this.sourceLocation;
172        }
173    }