Kludge the CXX11 checks for cmake 2.6.4
[dyninst.git] / instructionAPI / h / BinaryFunction.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #if !defined(BINARYFUNCTION_H)
32 #define BINARYFUNCTION_H
33
34 #include "Expression.h"
35 #include "Register.h"
36 #include "Result.h"
37 #include <sstream>
38
39 #if defined(_MSC_VER)
40 #pragma warning(disable:4251)
41 #endif
42
43 namespace Dyninst
44 {
45   namespace InstructionAPI
46   {
47     using std::vector;
48
49     /// A %BinaryFunction object represents a function that can combine two %Expressions and produce another %ValueComputation.
50     ///
51     /// For the purposes of representing a single operand of an instruction, the %BinaryFunctions of interest are addition and multiplication of
52     /// integer values; this allows a %Expression to represent all addressing modes on the architectures currently
53     /// supported by the %Instruction API.
54     class INSTRUCTION_EXPORT BinaryFunction : public Expression
55     {
56     public:
57       class INSTRUCTION_EXPORT funcT
58       {
59       public:
60         funcT(std::string name) : m_name(name) 
61         {
62         }
63         virtual ~funcT()
64         {
65         }
66         
67         virtual Result operator()(const Result& arg1, const Result& arg2) const = 0;
68         std::string format() const 
69         {
70           return m_name;
71         }
72         typedef boost::shared_ptr<funcT> Ptr;
73         
74       private:
75         std::string m_name;
76       };
77       
78       
79       class INSTRUCTION_EXPORT addResult : public funcT
80       {
81       public:
82         addResult() : funcT("+") 
83         {
84         }
85         virtual ~addResult()
86         {
87         }
88         Result operator()(const Result& arg1, const Result& arg2) const
89         {
90           return arg1 + arg2;
91         }
92       };
93       class INSTRUCTION_EXPORT multResult : public funcT
94       {
95       public:
96         multResult() : funcT("*")
97         {
98         }
99         virtual ~multResult()
100         {
101         }
102         Result operator()(const Result& arg1, const Result& arg2) const
103         {
104           return arg1 * arg2;
105         }
106       };
107             
108       /// \param arg1 first input to function
109       /// \param arg2 second input to function
110       /// \param result_type type of the function's result
111       /// \param func implementation of the function
112       ///
113       /// The constructor for a %BinaryFunction may take a reference-counted pointer or a plain C++ pointer to each of the
114       /// child Expressions that represent its arguments.  Since the reference-counted implementation requires explicit construction,
115       /// we provide overloads for all four combinations of plain and reference-counted pointers.  Note that regardless of which constructor
116       /// is used, the pointers \c arg1 and \c arg2 become owned by the %BinaryFunction being constructed, and should not be deleted.
117       /// They will be cleaned up when the %BinaryFunction object is destroyed.
118       ///
119       /// The \c func parameter is a binary functor on two Results.  It should be derived from \c %funcT.  \c addResult and
120       /// \c multResult, which respectively add and multiply two %Results, are provided as part of the InstructionAPI, 
121       /// as they are necessary for representing address calculations.  Other \c %funcTs may be implemented by the user if desired.
122       /// %funcTs have names associated with them for output and debugging purposes.  The addition and multiplication functors
123       /// provided with the %Instruction API are named "+" and "*", respectively.
124       BinaryFunction(Expression::Ptr arg1, Expression::Ptr arg2, Result_Type result_type,
125                      funcT::Ptr func) : 
126       Expression(result_type), m_arg1(arg1), m_arg2(arg2), m_funcPtr(func)
127       {
128       }
129               
130       virtual ~BinaryFunction() 
131       {
132       }
133
134       /// The %BinaryFunction version of \c eval allows the \c eval mechanism to handle complex addressing modes.  Like all of the %ValueComputation
135       /// implementations, a %BinaryFunction's \c eval will return the result of evaluating the expression it represents
136       /// if possible, or an empty %Result otherwise.
137       /// A %BinaryFunction may have arguments that can be evaluated, or arguments that cannot.
138       /// Additionally, it may have a real function pointer, or it may have a null function pointer.
139       /// If the arguments can be evaluated and the function pointer is real, a result other than an empty %Result is guaranteed to be
140       /// returned.  This result is cached after its initial calculation; the caching mechanism also allows
141       /// outside information to override the results of the %BinaryFunction's internal computation.
142       /// If the cached result exists, it is guaranteed to be returned even if the arguments or the function
143       /// are not evaluable.
144       virtual const Result& eval() const;
145     
146       /// The children of a %BinaryFunction are its two arguments.
147       /// \param children Appends the children of this %BinaryFunction to \c children.
148       virtual void getChildren(vector<InstructionAST::Ptr>& children) const
149       {
150         children.push_back(m_arg1);
151         children.push_back(m_arg2);
152         return;
153       }
154       virtual void getChildren(vector<Expression::Ptr>& children) const
155       {
156           children.push_back(m_arg1);
157           children.push_back(m_arg2);
158           return;
159       }
160       
161       /// The use set of a %BinaryFunction is the union of the use sets of its children.
162       /// \param uses Appends the use set of this %BinaryFunction to \c uses.
163       virtual void getUses(set<InstructionAST::Ptr>& uses)
164       {
165         m_arg1->getUses(uses);
166         m_arg2->getUses(uses);
167         return;
168       }
169       /// \c isUsed returns true if \c findMe is an argument of this %BinaryFunction,
170       /// or if it is in the use set of either argument.
171       virtual bool isUsed(InstructionAST::Ptr findMe) const
172       {
173         return m_arg1->isUsed(findMe) || m_arg2->isUsed(findMe) 
174                 || (*m_arg1 == *findMe) || (*m_arg2 == *findMe) || (*findMe == *this);
175       }
176       virtual std::string format(formatStyle how) const
177       {
178         std::stringstream retVal;
179         if(how == memoryAccessStyle)
180         {
181             retVal << m_arg2->format() << "(" << m_arg1->format() << ")";
182         }
183         else
184         {
185             retVal << m_arg1->format() << " " << m_funcPtr->format() << " " << m_arg2->format();
186         }
187         return retVal.str();
188       }
189       virtual bool bind(Expression* expr, const Result& value);
190       virtual void apply(Visitor* v);
191       bool isAdd() const;
192       bool isMultiply() const;
193     protected:
194       virtual bool isStrictEqual(const InstructionAST& rhs) const
195       {
196         const BinaryFunction& other(dynamic_cast<const BinaryFunction&>(rhs));
197         if(*(other.m_arg1) == *m_arg1 &&
198                     (*other.m_arg2) == *m_arg2) return true;
199         if(*(other.m_arg1) == *m_arg2 &&
200              (*other.m_arg2) == *m_arg1) return true;
201         return false;
202       }
203   
204     private:
205       Expression::Ptr m_arg1;
206       Expression::Ptr m_arg2;
207       funcT::Ptr m_funcPtr;
208       
209     };
210   };
211 };
212
213
214 #endif // !defined(BINARYFUNCTION_H)