README.adoc (22868B)
1 2 LJClang -- A LuaJIT-based interface to libclang 3 =============================================== 4 Philipp Kutin 5 :max-width: 56em 6 7 Introduction 8 ------------ 9 10 :LuaJIT: http://luajit.org/ 11 :libclang: http://clang.llvm.org/doxygen/group__CINDEX.html 12 :luaclang-parser: https://github.com/mkottman/luaclang-parser 13 14 LJClang is an interface to {libclang}[libclang] for {LuaJIT}[LuaJIT], modeled 15 after and mostly API-compatible with {luaclang-parser}[luaclang-parser] by 16 Michal Kottman. 17 18 Requirements 19 ------------ 20 21 :LJDownload: http://luajit.org/download.html 22 23 * {LJDownload}[LuaJIT 2.0] (latest Git HEAD of the master branch recommended) 24 * LLVM/Clang -- read the http://clang.llvm.org/get_started.html[getting 25 started] guide to find out how to obtain Clang from source. `libclang` is 26 built and installed along with the Clang compiler. 27 28 Building and usage 29 ------------------ 30 31 :Clang-Win32: http://www.ishani.org/web/articles/code/clang-win32/ 32 33 Most of LJClang is written in Lua (extensively using LuaJIT's FFI), but due 34 to currently existing limitations, a support C library has to be built. 35 36 In the provided `Makefile`, adjust the libclang include path, and issue `make` 37 to build `libljclang_support.so`. 38 39 NOTE: LJClang has been tested on Ubuntu Linux and Windows (using 40 {Clang-Win32}[Clang-Win32]), but only minor modifications to the build process 41 should be necessary to get it working with other OSes or configurations. 42 43 From here on, LJClang can be used with LuaJIT by issuing a `require` for 44 `"ljclang"`. One likely wants to use LJClang from its development directory 45 without installing it to a system-wide path. Because it expects to find 46 `libljclang_support.so` and several supporting Lua files, one approach is to 47 wrap client programs into scripts starting LuaJIT with an environment 48 containing appropriate `LD_LIBRARY_PATH` and `LUA_PATH` entries. For example, 49 given the following function in `.bashrc`, 50 51 ---------- 52 # "LuaJIT with added path of the script directory" 53 ljwp () 54 { 55 local scriptdir=$(cd `dirname $1`; pwd) 56 LUA_PATH=";;$scriptdir/?.lua" LD_LIBRARY_PATH="$scriptdir" luajit "$@" 57 } 58 ---------- 59 60 and assuming that LJClang resides in `~/dl/ljclang`, the `extractdecls.lua` 61 program described below could be run from anywhere like this: 62 63 ---------- 64 $~/some/other/dir: ljwp ~/dl/ljclang/extractdecls.lua [args...] 65 ---------- 66 67 Overview 68 -------- 69 70 LJClang provides a cursor-based, callback-driven API to the abstract syntax 71 tree (AST) of C/C++ source files. These are the main classes: 72 73 * `Index` -- represents a set of translation units that could be linked together 74 * `TranslationUnit` -- a source file together with everything included by it 75 either directly or transitively 76 * `Cursor` -- an element in the AST in a translation unit such as a `typedef` 77 declaration or a statement 78 * `Type` -- the type of an element (for example, that of a variable, structure 79 member, or a function's input argument or return value) 80 81 To make something interesting happen, you usually create a single `Index` 82 object, parse into it one or many translation units, and define a callback 83 function to be invoked on each visit of a `Cursor` by libclang. 84 85 Example program 86 --------------- 87 88 :CXCursorKind: http://clang.llvm.org/doxygen/group__CINDEX.html#gaaccc432245b4cd9f2d470913f9ef0013 89 90 The `extractdecls.lua` script accompanied by LJClang can be used to extract 91 various kinds of C declarations from (usually) headers and print them in 92 various forms usable as FFI C declarations or descriptive tables with LuaJIT. 93 94 ---------- 95 Usage: ./extractdecls.lua [our_options...] <file.h> [clang_options...] 96 -p <filterPattern> 97 -x <excludePattern1> [-x <excludePattern2>] ... 98 -s <stripPattern> 99 -1 <string to print before everything> 100 -2 <string to print after everything> 101 -C: print lines like 102 static const int membname = 123; (enums/macros only) 103 -R: reverse mapping, only if one-to-one. Print lines like 104 [123] = "membname"; (enums/macros only) 105 -f <formatFunc>: user-provided body for formatting function (enums/macros only) 106 Accepts args `k', `v'; `f' is string.format. Must return a formatted line. 107 Example: "return f('%s = %s%s,', k, k:find('KEY_') and '65536+' or '', v)" 108 Incompatible with -C or -R. 109 -Q: be quiet 110 -w: extract what? Can be 111 EnumConstantDecl (default), TypedefDecl, FunctionDecl, MacroDefinition 112 ---------- 113 114 In fact, the file `ljclang_cursor_kind.lua` is generated by this program and is 115 used by LJClang to map values of the enumeration {CXCursorKind}[`enum 116 CXCursorKind`] to their names. The `bootstrap` target in the `Makefile` 117 extracts the relevant information using these options: 118 119 ---------- 120 -R -p '^CXCursor_' -x '_First' -x '_Last' -x '_GCCAsmStmt' -x '_MacroInstantiation' -s '^CXCursor_' \ 121 -1 'return { name={' -2 '}, }' -Q 122 ---------- 123 124 Thus, the `typedef` declarations are filtered to begin with ``++CXCursor_++'' 125 and all ``secondary'' names aliasing the one considered the main one are 126 rejected. (For example, `CXCursor_AsmStmt` and `CXCursor_GCCAsmStmt` have the 127 same value.) Finally, the prefix is stripped (`-s`) to yield lines like 128 129 ---------- 130 [215] = "AsmStmt"; 131 ---------- 132 133 Reference 134 --------- 135 136 :clang_createIndex: http://clang.llvm.org/doxygen/group__CINDEX.html#func-members 137 :CXChildVisitResult: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__TRAVERSAL.html#ga99a9058656e696b622fbefaf5207d715 138 :clang_parseTranslationUnit: http://clang.llvm.org/doxygen/group__CINDEX__TRANSLATION__UNIT.html#ga2baf83f8c3299788234c8bce55e4472e 139 :clang_createTranslationUnit: http://clang.llvm.org/doxygen/group__CINDEX__TRANSLATION__UNIT.html#gaa2e74f6e28c438692fd4f5e3d3abda97 140 141 The module returned by `require("ljclang")` contains the following: 142 143 `createIndex([excludePch : boolean [, showDiagnostics : boolean]])` -> `Index`:: 144 145 Binding for {clang_createIndex}[clang_createIndex]. Will create an `Index` into 146 which you can parse ++TranslationUnit++s. Both input arguments are optional and 147 default to *false*. 148 + 149 NOTE: Loading pre-compiled translation units in not implemented. 150 151 [[ChildVisitResult]] 152 `ChildVisitResult`:: 153 154 An object containing a mapping of names to values permissible as values 155 {CXChildVisitResult}[returned] from cursor visitor callbacks: `Break`, 156 `Continue`, `Recurse`. 157 158 [[regCursorVisitor]] 159 `regCursorVisitor(visitorfunc)` -> `vf_handle`:: 160 161 Registers a child visitor callback function `visitorfunc` with LJClang, 162 returning a handle which can be passed to `Cursor:children()`. The callback 163 function receives two input arguments, `(cursor, parent)` -- with the cursors 164 of the currently visited entity as well as its parent, and must return a value 165 from the `ChildVisitResult` enumeration to indicate whether or how libclang 166 should carry on AST visiting. 167 + 168 169 CAUTION: The `cursor` passed to the visitor callback is only valid during one 170 particular callback invocation. If it is to be used after the function has 171 returned, it *must* be copied using the `Cursor` constructor mentioned below. 172 173 `Cursor([cur : Cursor])` -> `Cursor`:: 174 175 A constructor to create a permanent cursor from that received by the visitor 176 callback. 177 178 179 `Index` 180 ------- 181 182 :TUFlags: http://clang.llvm.org/doxygen/group__CINDEX__TRANSLATION__UNIT.html#enum-members 183 184 `Index:parse(sourceFile : string, args : table [, opts : table])` -> `TranslationUnit`:: 185 186 Binding for {clang_parseTranslationUnit}[clang_parseTranslationUnit]. This will 187 parse a given source file `sourceFile` with the command line arguments `args`, 188 which would be given to the compiler for compilation, containing e.g. include 189 paths or defines. 190 If `sourceFile` is the empty string, the source file is expected to be named in 191 `args`. 192 + 193 The last optional argument `opts` is expected to be a sequence containing 194 {TUFlags}[`CXTranslationUnit_*`] enum names without the `"CXTranslationUnit_"` 195 prefix, for example `{ "DetailedPreprocessingRecord" }`. 196 + 197 NOTE: Both `args` and `opts` (if given) must not contain an element at index 0. 198 199 ////////// 200 `Index:load(astFile : string)` -> `TranslationUnit`:: 201 202 Binding for 203 {clang_createTranslationUnit}[clang_createTranslationUnit]. This will load 204 the translation unit from an AST file which was constructed using `clang 205 -emit-ast`. Useful when repeatedly processing large sets of files (like 206 frameworks). 207 ////////// 208 209 `TranslationUnit` 210 ----------------- 211 212 :clang_getTranslationUnitCursor: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__MANIP.html#gaec6e69127920785e74e4a517423f4391 213 :clang_getFile: http://clang.llvm.org/doxygen/group__CINDEX__FILES.html#gaa0554e2ea48ecd217a29314d3cbd2085 214 :clang_getDiagnostic: http://clang.llvm.org/doxygen/group__CINDEX__DIAG.html#ga3f54a79e820c2ac9388611e98029afe5 215 :code_completion_API: http://clang.llvm.org/doxygen/group__CINDEX__CODE__COMPLET.html 216 :clang_visitChildren: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__TRAVERSAL.html#ga5d0a813d937e1a7dcc35f206ad1f7a91 217 218 `TranslationUnit:cursor()` -> `Cursor`:: 219 220 Binding for 221 {clang_getTranslationUnitCursor}[clang_getTranslationUnitCursor]. Returns 222 the `Cursor` representing a given translation unit, which provides access 223 to information about e.g. functions and types defined in a given file. 224 225 ////////// 226 `TranslationUnit:file(fileName : string)` -> `string, number`:: 227 ////////// 228 `TranslationUnit:file(fileName : string)` -> `string`:: 229 230 Binding for {clang_getFile}[clang_getFile]. Returns the absolute file path 231 of `fileName`. 232 + 233 NOTE: The last modification date is currently not returned as in 234 luaclang-parser. 235 ////////// 236 and a `time_t` last modification time 237 ////////// 238 239 `TranslationUnit:diagnostics()` -> `{ Diagnostic* }`:: 240 241 Binding for {clang_getDiagnostic}[clang_getDiagnostic]. Returns a table 242 array of `Diagnostic`, which represent warnings and errors. Each diagnostic 243 is a table indexable by these keys: `text` -- the diagnostic message, and 244 `category` -- a diagnostic category (also a string). 245 246 ////////// 247 `TranslationUnit:codeCompleteAt(file : string, line : number, column : number)` -> `{ Completion* }, { Diagnostics* }`:: 248 249 Binding for {code_completion_API}[code completion API]. Returns the 250 available code completion options at a given location using prior 251 content. Each `Completion` is a table consisting of several chunks, each of 252 which has a text and a {chunk kind}[chunk kind] without the 253 `CXCompletionChunk_` prefix. If there are any annotations, the 254 `annotations` key is a table of strings: 255 256 completion = { 257 priority = number, priority of given completion 258 chunks = { 259 kind = string, chunk kind 260 text = string, chunk text 261 }, 262 [annotations = { string* }] 263 } 264 ////////// 265 266 `Cursor` 267 -------- 268 269 :clang_getCursorSemanticParent: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__MANIP.html#gabc327b200d46781cf30cb84d4af3c877 270 :clang_getCursorLexicalParent: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__MANIP.html#gace7a423874d72b3fdc71d6b0f31830dd 271 :clang_getCursorSpelling: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__XREF.html#gaad1c9b2a1c5ef96cebdbc62f1671c763 272 :clang_getCursorDisplayName: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__XREF.html#gac3eba3224d109a956f9ef96fd4fe5c83 273 :cursor_kind: http://clang.llvm.org/doxygen/group__CINDEX.html#gaaccc432245b4cd9f2d470913f9ef0013 274 :clang_Cursor_getArgument: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga673c5529d33eedd0b78aca5ac6fc1d7c 275 :clang_getCursorResultType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga6995a2d6352e7136868574b299005a63 276 :clang_getCursorExtent: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__SOURCE.html#ga79f6544534ab73c78a8494c4c0bc2840 277 :clang_getCursorReferenced: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__XREF.html#gabf059155921552e19fc2abed5b4ff73a 278 :clang_getCursorDefinition: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__XREF.html#gafcfbec461e561bf13f1e8540bbbd655b 279 :clang_getSpellingLocation: http://clang.llvm.org/doxygen/group__CINDEX__LOCATIONS.html#ga01f1a342f7807ea742aedd2c61c46fa0 280 :clang_getPresumedLocation: http://clang.llvm.org/doxygen/group__CINDEX__LOCATIONS.html#ga03508d9c944feeb3877515a1b08d36f9 281 282 :clang_getEnumConstantDeclValue: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga6b8585818420e7512feb4c9d209b4f4d 283 :clang_getEnumConstantUnsignedDeclValue: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#gaf7cbd4f2d371dd93e8bc997c951a1aef 284 :clang_getTypedefDeclUnderlyingType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga8de899fc18dc859b6fe3b97309f4fd52 285 286 :clang_Cursor_getTranslationUnit: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__MANIP.html#ga529f1504710a41ce358d4e8c3161848d 287 :clang_isCursorDefinition: http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__XREF.html#ga6ad05634a73e693217088eaa693f0010 288 289 You can compare whether two ++Cursor++s represent the same element using the 290 standard `==` Lua operator. Comparisons with any other type yield *false*. 291 292 `Cursor:children()` -> `{ Cursor* }`:: 293 `Cursor:children(vf_handle)` -> `boolean`:: 294 295 Binding over {clang_visitChildren}[clang_visitChildren]. This is the main 296 function for AST traversal. The first form collects the direct descendants of 297 the given cursor in a table, returning an empty one if none are found. The 298 second, preferred form accepts a handle of a visitor function previously 299 registered with <<regCursorVisitor,`regCursorVisitor()`>> instead. Here, the 300 returned value indicates whether the traversal was aborted prematurely due to 301 the callback returning +<<ChildVisitResult,ChildVisitResult>>.Break+. 302 + 303 NOTE: Currently, the recommended procedure is to encapsulate the logic of one 304 particular ``analysis'' into one visitor callback, which may run different 305 portions of code e.g. conditional on the cursor's kind. (Instead of calling 306 `Cursor:children(visitor_function_handle)` with a different visitor function 307 while another invocation of it is active.) 308 309 ////////// 310 Traverses the direct descendants of a given 311 cursor and collects them in a table. If no child cursors are found, returns 312 an empty table. 313 ////////// 314 315 `Cursor:parent()` -> `Cursor`:: 316 317 Binding for 318 {clang_getCursorSemanticParent}[clang_getCursorSemanticParent]. Returns a 319 cursor to the semantic parent of a given element. For example, for a method 320 cursor, returns its class. For a global declaration, returns the 321 translation unit cursor. 322 323 `Cursor:lexicalParent()` -> `Cursor`:: 324 325 Binding for 326 {clang_getCursorLexicalParent}[clang_getCursorLexicalParent]. Returns a 327 cursor to the lexical parent of a given element. 328 329 `Cursor:name()` -> `string`:: 330 331 Binding over {clang_getCursorSpelling}[clang_getCursorSpelling]. Returns 332 the name of the entity referenced by cursor. `Cursor` also has `__tostring` 333 set to this method. 334 335 `Cursor:displayName()` -> `string`:: 336 337 Binding over 338 {clang_getCursorDisplayName}[clang_getCursorDisplayName]. Returns the 339 display name of the entity, which for example is a function signature. 340 341 `Cursor:kind()` -> `string`:: 342 343 Returns the {cursor_kind}[cursor kind] without the `CXCursor_` prefix, 344 e.g. `"FunctionDecl"`. 345 346 `Cursor:haskind(kind : string)` -> `boolean`:: 347 348 Checks whether the cursor has kind given by `kind`, which must be a string 349 of {CXCursorKind}[`enum CXCursorKind`] names without the `CXCursor_` 350 prefix. For instance, `if (cur:haskind("TypedefDecl")) then --[[ do 351 something ]] end` . 352 353 ////////// 354 kindnum 355 ////////// 356 357 `Cursor:arguments()` -> `{ Cursor* }`:: 358 359 Binding of {clang_Cursor_getArgument}[clang_Cursor_getArgument]. Returns a 360 table array of ++Cursor++s representing arguments of a function or a 361 method. Returns an empty table if a cursor is not a method or function. 362 363 `Cursor:translationUnit()` -> `TranslationUnit`:: 364 365 Binding for 366 {clang_Cursor_getTranslationUnit}[clang_Cursor_getTranslationUnit]. Returns 367 the translation unit that a cursor originated from. 368 369 `Cursor:resultType()` -> `Type`:: 370 371 Binding for {clang_getCursorResultType}[clang_getCursorResultType]. For a 372 function or a method cursor, returns the return type of the function. 373 374 `Cursor:typedefType()` -> `Type`:: 375 376 If the cursor references a typedef declaration, returns its 377 {clang_getTypedefDeclUnderlyingType}[underlying type]. 378 379 ////////// 380 XXX: Make error instead? 381 Otherwise, returns *nil*. 382 ////////// 383 384 `Cursor:type()` -> `Type`:: 385 386 Returns the `Type` of a given element or *nil* if not available. 387 388 `Cursor:location([linesfirst : boolean])` -> `string, number, number, number, number [, number, number]`:: 389 390 Binding for {clang_getCursorExtent}[clang_getCursorExtent] and 391 {clang_getSpellingLocation}[clang_getSpellingLocation]. Returns the _file 392 name_, _starting line_, _starting column_, _ending line_ and _ending 393 column_ of the given cursor. If the optional argument `linesfirst` is true, 394 the numbers are ordered like _starting line_, _ending line_, _starting 395 column_, _ending column_, _starting offset_, _ending offset_ instead. If 396 `linesfirst` has the string value `'offset'`, only _starting offset_, 397 _ending offset_ are returned. 398 399 `Cursor:presumedLocation([linesfirst : boolean])` -> `string, number, number, number, number 400 401 Binding for {clang_getCursorExtent}[clang_getCursorExtent] and 402 {clang_getPresumedLocation}[clang_getPresumedLocation]. 403 404 ////////// 405 XXX: Better provide an API around CXSourceRange. 406 This can be used to look up the text a cursor consists of. 407 ////////// 408 409 `Cursor:definition()` -> `Cursor`:: 410 411 Binding for {clang_getCursorDefinition}[clang_getCursorDefinition]. For a 412 reference or declaration, returns a cursor to the definition of the entity, 413 otherwise returns *nil*. 414 415 `Cursor:referenced()` -> `Cursor`:: 416 417 Binding for {clang_getCursorReferenced}[clang_getCursorReferenced]. For a 418 reference type, returns a cursor to the element it references, otherwise 419 returns *nil*. 420 421 `Cursor:access()` -> `string`:: 422 423 When cursor kind is `"AccessSpecifier"`, returns one of `"private"`, 424 `"protected"` and `"public"`. 425 426 `Cursor:isDefinition()` -> `boolean`:: 427 428 Binding for {clang_isCursorDefinition}[clang_isCursorDefinition]. Determine 429 whether the declaration pointed to by this cursor is also a definition of 430 that entity. 431 432 `Cursor:isVirtual()` -> `boolean`:: 433 434 For a C++ method, returns whether the method is virtual. 435 436 `Cursor:isStatic()` -> `boolean`:: 437 438 For a C++ method, returns whether the method is static. 439 440 `Cursor:enumValue([unsigned : boolean])` -> `enum cdata`:: 441 442 If the cursor represents an enumeration constant (`CXCursor_EnumConstantDecl`), 443 returns its numeric value as a {clang_getEnumConstantDeclValue}[signed] 64-bit 444 signed integer, or a 64-bit {clang_getEnumConstantUnsignedDeclValue}[unsigned] 445 integer if `unsigned` is true. 446 + 447 NOTE: In C99, an enumeration constant must be in the range of values 448 representable by an `int` (6.7.2.2#2). LJClang does not check for this 449 constraint. 450 451 `Cursor:enumval([unsigned : boolean])` -> `number`:: 452 453 Returns the cdata obtained from `enumValue()` as a Lua number, converted 454 using `tonumber()`. Again, no checking of any kind is carried out. 455 456 `Type` 457 ------ 458 459 :clang_getTypeKindSpelling: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga6bd7b366d998fc67f4178236398d0666 460 :clang_getCanonicalType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#gaa9815d77adc6823c58be0a0e32010f8c 461 :clang_getPointeeType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#gaafa3eb34932d8da1358d50ed949ff3ee 462 :clang_isPODType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga3e7fdbe3d246ed03298bd074c5b3703e 463 :clang_isConstQualifiedType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga8c3f8029254d5862bcd595d6c8778e5b 464 :clang_getTypeDeclaration: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga0aad74ea93a2f5dea58fd6fc0db8aad4 465 :clang_getArrayElementType: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga718591f4b07d9d4861557a3ed8b29713 466 :clang_getArraySize: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga91521260817054f153b5f1295056192d 467 468 :CXTypeKind: http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#gaad39de597b13a18882c21860f92b095a 469 470 471 You can compare whether two ++Type++s represent the same type using the standard 472 `==` Lua operator. Comparisons with any other type yield *false*. 473 474 `Type:name()` -> `string`:: 475 476 Binding of {clang_getTypeKindSpelling}[clang_getTypeKindSpelling]. Returns 477 one of {CXTypeKind}[`CXTypeKind`] as a string without the `CXType_` 478 prefix. `Type` also has `__tostring` set to this method. 479 480 `Type:canonical()` -> `Type`:: 481 482 Binding of {clang_getCanonicalType}[clang_getCanonicalType]. Returns 483 underlying type with all typedefs removed. 484 + 485 NOTE: Unlike luaclang-parser, LJClang does *not* dispatch to 486 `clang_getPointeeType()` for pointer types. 487 488 ////////// 489 XXX: What was the intention of that? Test out stuff... 490 ////////// 491 492 `Type:pointee()` -> `Type`:: 493 494 Binding of {clang_getPointeeType}[clang_getPointeeType]. For pointer type 495 returns the type of the pointee. 496 497 `Type:isPod()` -> `boolean`:: 498 499 Binding of {clang_isPODType}[clang_isPODType]. Returns true if the type is 500 a ``Plain Old Data'' type. 501 502 `Type:isConst()` -> `boolean`:: 503 `Type:isConstQualified()` -> `boolean`:: 504 505 Binding of 506 {clang_isConstQualifiedType}[clang_isConstQualifiedType]. Returns true if 507 the type has a `const` qualifier. 508 509 `Type:declaration()` -> `Cursor`:: 510 511 Binding of {clang_getTypeDeclaration}[clang_getTypeDeclaration]. Returns a 512 `Cursor` to the declaration of a given type, or *nil*. 513 514 `Type:arrayElementType()` -> `Type`:: 515 516 Binding of {clang_getArrayElementType}[clang_getArrayElementType]. 517 518 `Type:arraySize()` -> `Type`:: 519 520 Binding of {clang_getArraySize}[clang_getArraySize]. 521 522 523 524 License 525 ------- 526 527 Copyright (C) 2013 Philipp Kutin 528 529 (Portions of the documentation copied or adapted from luaclang-parser, Copyright 530 (C) 2012 Michal Kottman) 531 532 Permission is hereby granted, free of charge, to any person obtaining a copy 533 of this software and associated documentation files (the "Software"), to deal 534 in the Software without restriction, including without limitation the rights 535 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 536 copies of the Software, and to permit persons to whom the Software is 537 furnished to do so, subject to the following conditions: 538 539 The above copyright notice and this permission notice shall be included in 540 all copies or substantial portions of the Software. 541 542 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 543 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 544 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 545 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 546 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 547 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 548 THE SOFTWARE. 549