LLVM函數定義由「define」 關鍵字,一個可選的連接標識,一個可選的可見性模式,一個可選的DLL存儲類別,一個可選的調用約定,一個可選的 unnamed_addr 屬性,一個返回值類型,一個可選的返回值的參數屬性,一個函數名,一個(可能爲空的)實參列表(每個都帶有可選的參數屬性),可選的函數屬性,一個可選的section,一個可選的對齊屬性,一個可選垃圾回收期的名字,一個可選的前綴,一個左花括號,一個基本塊列表和一個右花括號。html
LLVM函數聲明由 「declare」 關鍵字,一個可選的連接標識,一個可選的可見性模式,一個可選的DLL存儲類型,一個可選的調用約定,一個可選的 unnamed_addr 屬性,一個返回值類型,一個可選的返回值類型的參數屬性,一個函數名,一個可能爲空的實參列表,一個可選對齊屬性,一個可選垃圾回收器名和一個可選的前綴。前端
一個函數定義包含一個基本塊的列表,能夠爲函數造成CFG(控制流圖形)。每個基本塊能夠(可選的)開始於一個label(給定這個基本快一個符號表入口),包含一個指令列表,而且結束與一個終止指令(例如分支或函數返回)。若是一個明確的label不被提供,一個快會被分配到一個隱式的編號label,使用的計數器與匿名臨時變量使用同一個計數器。例如,若是一個函數入口塊不具備一個顯示的label,他會被分配到一個label "%0",而後第一個在這個塊中的匿名臨時變量將會是「%1」。node
函數中的第一基本塊特殊在兩個方面: 她是在函數進入後立刻執行的,而且它是不容許有前置基本塊(即函數入口塊不能擁有任何分支)。由於這個塊沒有前置塊,因此也不能有任何 PHI nodes.python
LLVM容許函數指定一個明確的section。若是目標平臺支持它,它會放散函數到這個指定塊。web
一個顯示的對齊屬性可能會被指定到一個函數。若是沒有指定,或者對齊屬性被設置爲0,那麼這個函數的對齊屬性將會根據目標平臺的須要設定。若是一個顯式對齊屬性被指定,這個函數被迫至少想指定的那麼多對齊。全部對齊屬性必須爲2的次冪。數組
若是 unnamed_addr 屬性被指定了,函數的地址會被認爲是不重要的且兩個相同的函數之間能夠被合併。函數
語法:post
define [linkage] [visibility] [DLLStorageClass] [cconv] [ret attrs] <ResultType> @<FunctionName> ([argument list]) [fn Attrs] [section "name"] [align N] [gc] [prefix Constant] { ... }
別名做爲可別名對象(包括函數,全局變量,另外一個別名或全局值的bitcast)的「second name」。別名能夠擁有一個可選的連接標識,一個可選的可見性模式,一個可選的DLL存儲類別。優化
語法:this
@<Name> = [Visibility] [DLLStorageClass] alias [Linkage] <AliaseeTy> @<Aliasee>
連接標識必須是 private, linker_private, linker_private_weak, internal, linkonce, weak, linkonce_odr, weak_odr, external.中的其中一個。注意一些系統連接器可能會不正確地處理一個降級的弱符號做爲非弱別名。
具名元數據是一個元數據的集合。Metadata nodes (但非元數據字符串) 是惟一對於具名元數據有效的操做數。
語法:
; Some unnamed metadata nodes, which are referenced by the named metadata.
!0 = metadata !{metadata !"zero"}
!1 = metadata !{metadata !"one"}
!2 = metadata !{metadata !"two"}
; A named metadata.
!name = !{!0, !1, !2}
這個返回類型和每個函數的參數類型可能擁有一個參數屬性集。參數屬性是用於交流函數的返回值和參數的額外信息。參數類型被認爲是函數的一部分,但不是函數類型的一部分,因此用不一樣的參數屬性的函數能夠擁有同一個函數類型。
參數屬性是是如下的一些跟在類型後的簡單的關鍵字。若是須要多個參數屬性,他們須要被空白符分隔開。
例如:
declare i32 @printf(i8* noalias nocapture, ...)
declare i32 @atoi(i8 zeroext)
declare signext i8 @returns_signed_char()
注意,任何對於函數結果nounwind, readonly)屬性跟隨在實參列表後。
當前,僅有如下的參數屬性被定義:
inalloca
注意
這個特性是不穩定的且沒有徹底實現。
inalloca 實參屬性容許調用者帶有即將離開stack的實參地址。一個 inalloca 實參必須是一個使用 alloca 指令建立指向棧內存的指針的地址。這個分配的堆棧空間或實參分配必須也以inalloca關鍵字標識。只有過去的實參可使用inalloca屬性且這個實參保證在內存中傳遞。
一個實參分配可能被函數調用使用至少一次由於這個函數調用可能會釋放它。這個 inalloca 屬性不可能與其餘會影響實參存儲的屬性結合使用,像inreg, nest, sret, or byval。這個 inalloca 屬性也禁止LLVM隱式下降大型聚合返回值,這意味着前端做者必須經過 sret 下降他們。
當到達調用地點時,實參分配必須是仍然活的最新棧分配,或者結果是未定義的。在一個實參分配後和這個實參的調用地點前額外分配堆棧空間是可能的,但這必須清除llvm.stackrestore。
詳見 Design and Usage of the InAlloca Attribute