PageRenderTime 24ms CodeModel.GetById 12ms app.highlight 5ms RepoModel.GetById 2ms app.codeStats 0ms

/src/wrappers/llvm/library/values/llvm_function.e

http://github.com/tybor/Liberty
Specman e | 250 lines | 132 code | 36 blank | 82 comment | 3 complexity | ed1ca8758b09133fb29b51e81728f06a MD5 | raw file
  1class LLVM_FUNCTION
  2	-- A function in LLVM 
  3
  4	-- The Function class represents a single procedure in LLVM. It is actually
  5	-- one of the more complex classes in the LLVM heirarchy because it must
  6	-- keep track of a large amount of data. The Function class keeps track of
  7	-- a list of BasicBlocks, a list of formal Arguments, and a SymbolTable.
  8
  9	-- The list of BasicBlocks is the most commonly used part of Function
 10	-- objects. The list imposes an implicit ordering of the blocks in the
 11	-- function, which indicate how the code will be layed out by the backend.
 12	-- Additionally, the first BasicBlock is the implicit entry node for the
 13	-- Function. It is not legal in LLVM to explicitly branch to this initial
 14	-- block. There are no implicit exit nodes, and in fact there may be
 15	-- multiple exit nodes from a single Function. If the BasicBlock list is
 16	-- empty, this indicates that the Function is actually a function
 17	-- declaration: the actual body of the function hasn't been linked in yet.
 18
 19	-- In addition to a list of BasicBlocks, the Function class also keeps
 20	-- track of the list of formal Arguments that the function receives. This
 21	-- container manages the lifetime of the Argument nodes, just like the
 22	-- BasicBlock list does for the BasicBlocks.
 23
 24	-- The SymbolTable is a very rarely used LLVM feature that is only used
 25	-- when you have to look up a value by name. Aside from that, the
 26	-- SymbolTable is used internally to make sure that there are not conflicts
 27	-- between the names of Instructions, BasicBlocks, or Arguments in the
 28	-- function body.
 29
 30	-- Note that Function is a GlobalValue and therefore also a Constant. The
 31	-- value of the function is its address (after linking) which is guaranteed
 32	-- to be constant.
 33
 34	-- Eiffel specific note: variadic functions - functions accepting a
 35	-- variable number of arguments - are not supported. 
 36
 37inherit 
 38	LLVM_GLOBAL_VALUE
 39	ITERABLE[LLVM_VALUE]
 40		-- to provide iteration over parameters
 41		rename 
 42			count as parameters_count,
 43			is_empty as is_parameterless
 44			new_iterator as new_parameter_iterator,
 45			do_all as do_all_parameters
 46			for_all as for_all_parameters
 47			exists as exists_parameter
 48		undefine is_equal, copy, out_in_tagged_out_memory, fill_tagged_out_memory
 49		end
 50
 51insert LLVM_VALUE_WRAPPER_FACTORY 
 52
 53create {ANY} make 
 54create {WRAPPER, WRAPPER_HANDLER} from_external_pointer
 55
 56feature {} -- Creation
 57	make (a_return_type: LLVM_TYPE; some_parameters: WRAPPER_COLLECTION[LLVM_TYPE])
 58    local some_wrappers: WRAPPER_COLLECTION[LLVM_TYPE]
 59	do
 60		from_external_pointer
 61		(llvmfunction_type
 62		(null_or(a_return_type),
 63		 null_or_array(some_parameters),
 64		 some_parameters.count.to_natural_32,
 65		0 -- i.e. False, non-variadic
 66		))
 67	end
 68
 69feature {ANY} -- Calling convention
 70	calling_convention: LLVMCALL_CONV_ENUM
 71		do
 72			Result.change_value(llvmget_function_call_conv(handle).to_integer_32)
 73		end
 74			
 75	set_calling_convention (a_calling_convention: LLVMCALL_CONV_ENUM)
 76		-- Set calling convention
 77	do
 78		llvmset_function_call_conv(handle, a_calling_convention.value.to_natural_32)	
 79	end	
 80feature {ANY} -- Iterating over blocks
 81
 82	-- `first', `last' from LLVM_FUNCTION and `next', `previous' from
 83	-- LLVM_BASIC_BLOCK allow to iterate over blocks. A proper ITERATOR shall
 84	-- be provided (TODO).
 85
 86	-- Note: a feature like "blocks: COLLECTION[LLVM_BASIC_BLOCK]" is not
 87	-- offered even if there are functions like "llvmcount_basic_blocks" and
 88	-- "llvmget_basic_blocks" because its content may be invalidated adding
 89	-- some blocks; there is not efficient way to monitor changes standing my
 90	-- insufficient current knowledge of LLVM. Paolo 2009-10-20.
 91
 92	first: LLVM_BASIC_BLOCK
 93		-- The first block
 94	local p: POINTER
 95	do
 96		p := llvmget_first_basic_block(handle)
 97		if p.is_not_null then 
 98			create Result.from_external_pointer(p)
 99		end
100	end
101	
102	last: LLVM_BASIC_BLOCK
103		-- The last block
104	local p: POINTER
105	do
106		p:=llvmget_last_basic_block(handle)
107		if p.is_not_null then
108			create Result.from_external_pointer(p)
109		end
110	end
111	
112	basic_blocks_count: NATURAL_32
113		do
114			Result := llvmcount_basic_blocks(handle)
115		end
116
117	-- TODO: basic_blocks: COLLECTION[LLVM_BASIC_BLOCK] may be not efficiently
118	-- implemented, so "void LLVMGetBasicBlocks(LLVMValueRef Fn,
119	-- LLVMBasicBlockRef *BasicBlocks);" is not wrapped. It would require that
120	-- the given array is stable, while it is mutable since instructions may be
121	-- added anytime. To implement this feature we shall directly access C++
122	-- API.
123
124	new_block_iterator: ITERATOR_OVER_BASIC_BLOCKS
125		-- A new iterator over blocks composing the function.
126	do
127		create Result.from_function(Current)
128	ensure Result/=Void
129	end
130	
131	entry_basic_block: LLVM_BASIC_BLOCK
132		-- Entry block of function
133	local p: POINTER
134	do
135		p := llvmget_entry_basic_block(handle)
136		if p.is_not_null then
137			create Result.from_external_pointer(p)
138		end
139	end
140
141feature {ANY} -- Parameters
142	parameters_count: INTEGER
143		-- The number of parameters. TODO: should be NATURAL
144		do
145			Result:=llvmcount_params(handle).to_integer_32
146		end
147
148	is_parameterless: BOOLEAN do Result:=(parameters_count=0) end
149
150	-- Note: "void LLVMGetParams(LLVMValueRef Fn,
151	-- LLVMValueRef *Params);" will not be wrapped because
152	-- the C interface doe not allow an efficient
153	-- implementation see the note about basic blocks.
154
155	is_valid_parameter_index (an_index: INTEGER): BOOLEAN
156		do
157			Result := an_index.in_range(0, parameters_count)
158		end
159
160	parameter (an_index: INTEGER): LLVM_VALUE
161		-- The parameter at `an_index'
162		-- TODO: `an_index' should be a NATURAL_32 as in C it's an unsigned. 
163		require is_valid_parameter_index(an_index)
164		local p: POINTER
165		do
166			p := llvmget_param(handle,an_index.to_natural_32)
167			check
168				p.is_not_null 
169			end
170			Result:=value_wrapper(p)
171		ensure Result/=Void
172		end
173	
174	new_parameter_iterator: ITERATOR_OVER_FUNCTION_PARAMETERS
175		-- A newly allocated iterator over Current function's parameters.
176		do
177			create Result.from_function(Current)
178		end
179
180-- LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn);
181-- LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn);
182-- LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg);
183-- LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg);
184-- void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA);
185-- void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA);
186-- void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
187
188feature {ANY} -- Deleting
189	delete
190		-- Delete Current function. 
191	do
192		llvmdelete_function(handle)
193		handle := default_pointer
194	ensure
195		unusable: is_deleted
196	end
197
198	is_deleted: BOOLEAN
199		-- Has Current function already been deleted?
200	do
201		Result:=handle.is_null
202	end
203feature {ANY} -- Miscellaneous
204	intrinsic_id: NATURAL_32
205		do
206			Result:=llvmget_intrinsic_id(handle)
207		end
208
209	gc: FIXED_STRING
210		-- wraps LLVMGetGC. TODO: provide a better name and description
211		do
212			create Result.from_external(llvmget_gc(handle))
213		ensure Result/=Void
214		end
215
216	set_gc (a_name: ABSTRACT_STRING)
217		-- wraps LLVMSetGC. TODO: provide better name and description
218	do
219		llvmset_gc(handle,a_name.to_external)
220	ensure set: a_name.is_equal(gc)
221	end
222
223	add_attribute (an_attribute: LLVMATTRIBUTE_ENUM)
224	do
225		llvmadd_function_attr(handle,an_attribute.value)
226	end
227
228	remove_attribute (an_attribute: LLVMATTRIBUTE_ENUM)
229	do
230		llvmremove_function_attr(handle,an_attribute.value)
231	end
232
233end -- class LLVM_FUNCTION
234
235-- Copyright (C) 2009-2017: Paolo Redaelli
236-- This file is part of LLVM wrappers for Liberty Eiffel.
237--
238-- This library is free software: you can redistribute it and/or modify
239-- it under the terms of the GNU Lesser General Public License as published by
240-- the Free Software Foundation, version 3 of the License.
241--
242-- Liberty Eiffel is distributed in the hope that it will be useful,
243-- but WITHOUT ANY WARRANTY; without even the implied warranty of
244-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
245-- GNU General Public License for more details.
246--
247-- You should have received a copy of the GNU General Public License
248-- along with Liberty Eiffel.  If not, see <http://www.gnu.org/licenses/>.
249--
250