clangc 1.0.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/ext/clangc/_clangc_functions.c +303 -0
  3. data/ext/clangc/_clangc_functions.h +51 -0
  4. data/ext/clangc/clangc.c +376 -0
  5. data/ext/clangc/class_CodeCompleteResults.c +186 -0
  6. data/ext/clangc/class_CodeCompleteResults.h +51 -0
  7. data/ext/clangc/class_CompletionResult.c +98 -0
  8. data/ext/clangc/class_CompletionResult.h +36 -0
  9. data/ext/clangc/class_CompletionString.c +231 -0
  10. data/ext/clangc/class_CompletionString.h +57 -0
  11. data/ext/clangc/class_Cursor.c +1677 -0
  12. data/ext/clangc/class_Cursor.h +259 -0
  13. data/ext/clangc/class_CursorSet.c +109 -0
  14. data/ext/clangc/class_CursorSet.h +39 -0
  15. data/ext/clangc/class_Diagnostic.c +322 -0
  16. data/ext/clangc/class_Diagnostic.h +66 -0
  17. data/ext/clangc/class_File.c +145 -0
  18. data/ext/clangc/class_File.h +45 -0
  19. data/ext/clangc/class_Index.c +461 -0
  20. data/ext/clangc/class_Index.h +58 -0
  21. data/ext/clangc/class_Module.c +181 -0
  22. data/ext/clangc/class_Module.h +51 -0
  23. data/ext/clangc/class_OverriddenCursor.c +51 -0
  24. data/ext/clangc/class_OverriddenCursor.h +31 -0
  25. data/ext/clangc/class_SourceLocation.c +197 -0
  26. data/ext/clangc/class_SourceLocation.h +45 -0
  27. data/ext/clangc/class_SourceRange.c +123 -0
  28. data/ext/clangc/class_SourceRange.h +42 -0
  29. data/ext/clangc/class_TranslationUnit.c +457 -0
  30. data/ext/clangc/class_TranslationUnit.h +63 -0
  31. data/ext/clangc/class_Type.c +564 -0
  32. data/ext/clangc/class_Type.h +108 -0
  33. data/ext/clangc/constants.c +660 -0
  34. data/ext/clangc/constants.h +21 -0
  35. data/ext/clangc/extconf.rb +34 -0
  36. data/ext/clangc/macros.h +230 -0
  37. data/lib/clangc.rb +397 -0
  38. metadata +95 -0
@@ -0,0 +1,63 @@
1
+ /*
2
+ * ruby-clangc ruby bindings for the C interface of Clang
3
+ * Copyright (C) 2015-2016 Cedric Le Moigne cedlemo <cedlemo@gmx.com>
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ #ifndef TRANSLATIONUNIT_H
19
+ #define TRANSLATIONUNIT_H
20
+ #include <ruby/ruby.h>
21
+ #include "clang-c/Index.h"
22
+ typedef struct TranslationUnit_t
23
+ {
24
+ CXTranslationUnit data;
25
+ VALUE parent;
26
+ } TranslationUnit_t;
27
+
28
+ VALUE
29
+ c_TranslationUnit_struct_alloc(VALUE);
30
+
31
+ VALUE
32
+ c_TranslationUnit_get_diagnostics_num(VALUE);
33
+
34
+ VALUE
35
+ c_TranslationUnit_get_default_save_options(VALUE);
36
+
37
+ VALUE
38
+ c_TranslationUnit_get_spelling(VALUE);
39
+
40
+ VALUE
41
+ c_TranslationUnit_get_default_reparse_options(VALUE);
42
+
43
+ VALUE
44
+ c_TranslationUnit_get_diagnostic(VALUE, VALUE);
45
+
46
+ VALUE
47
+ c_TranslationUnit_get_file(VALUE, VALUE);
48
+
49
+ VALUE
50
+ c_TranslationUnit_get_cursor(VALUE);
51
+
52
+ VALUE
53
+ c_TranslationUnit_get_module(VALUE, VALUE);
54
+
55
+ VALUE
56
+ c_TranslationUnit_code_complete_at(VALUE, VALUE, VALUE, VALUE, VALUE);
57
+
58
+ VALUE
59
+ c_TranslationUnit_reparse(VALUE, VALUE);
60
+
61
+ VALUE
62
+ c_TranslationUnit_get_skipped_ranges(VALUE, VALUE);
63
+ #endif // TRANSLATIONUNIT_H
@@ -0,0 +1,564 @@
1
+ /*
2
+ * ruby-clangc ruby bindings for the C interface of Clang
3
+ * Copyright (C) 2015-2016 Cedric Le Moigne cedlemo <cedlemo@gmx.com>
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ /*Type ruby class*/
19
+ #include "class_Type.h"
20
+ #include "class_Cursor.h"
21
+ #include "macros.h"
22
+
23
+ static void c_Type_struct_free(Type_t *s)
24
+ {
25
+ if (s)
26
+ {
27
+
28
+ ruby_xfree(s);
29
+ }
30
+ }
31
+
32
+ static void c_Type_mark(void *s)
33
+ {
34
+ if (s)
35
+ {
36
+ Type_t *t = (Type_t *) s;
37
+ rb_gc_mark(t->parent);
38
+ }
39
+ }
40
+ VALUE
41
+ c_Type_struct_alloc(VALUE klass)
42
+ {
43
+
44
+ return Data_Wrap_Struct(
45
+ klass, NULL, c_Type_struct_free, ruby_xmalloc(sizeof(Type_t)));
46
+ }
47
+ /**
48
+ * call-seq:
49
+ * Clangc::Type#kind => Fixnum
50
+ *
51
+ * Get the kind of type. The returned value is a postive integer contained in
52
+ * Clangc::TypeKind.constants
53
+ */
54
+ VALUE
55
+ c_Type_get_kind(VALUE self)
56
+ {
57
+ Type_t *t;
58
+ Data_Get_Struct(self, Type_t, t);
59
+ return CUINT_2_NUM(t->data.kind);
60
+ }
61
+
62
+ /**
63
+ * call-seq:
64
+ * Clangc::Type#spelling => String
65
+ *
66
+ * Pretty-print the underlying type using the rules of the
67
+ * language of the translation unit from which it came.
68
+ *
69
+ * If the type is invalid, an empty string is returned.
70
+ */
71
+ VALUE
72
+ c_Type_get_spelling(VALUE self)
73
+ {
74
+ Type_t *t;
75
+ Data_Get_Struct(self, Type_t, t);
76
+ return CXSTR_2_RVAL(clang_getTypeSpelling(t->data));
77
+ }
78
+
79
+ /**
80
+ * call-seq:
81
+ * Clangc::Type#is_equal(Clangc::Type) => boolean
82
+ *
83
+ * Determine whether two Clangc::Type represent the same type.
84
+ *
85
+ * Returns true if the Clangc::Type represent the same type and
86
+ * false otherwise.
87
+ */
88
+ VALUE
89
+ c_Type_is_equal(VALUE self, VALUE type)
90
+ {
91
+ Type_t *t1;
92
+ Type_t *t2;
93
+ Data_Get_Struct(self, Type_t, t1);
94
+ CHECK_ARG_TYPE(type, Type);
95
+ Data_Get_Struct(type, Type_t, t2);
96
+ return NOT_0_2_RVAL(clang_equalTypes(t1->data, t2->data));
97
+ }
98
+
99
+ /**
100
+ * call-seq:
101
+ * Clangc::Type#canonical_type => Clangc::Type
102
+ *
103
+ * Return the canonical type for a Clangc::Type.
104
+ *
105
+ * Clang's type system explicitly models typedefs and all the ways
106
+ * a specific type can be represented. The canonical type is the underlying
107
+ * type with all the "sugar" removed. For example, if 'T' is a typedef
108
+ * for 'int', the canonical type for 'T' would be 'int'.
109
+ */
110
+ VALUE
111
+ c_Type_get_canonical_type(VALUE self)
112
+ {
113
+ Type_t *t;
114
+ Data_Get_Struct(self, Type_t, t);
115
+ Type_t *c;
116
+ VALUE canonical;
117
+ R_GET_CLASS_DATA("Clangc", Type, canonical, c);
118
+ c->data = clang_getCanonicalType(t->data);
119
+ c->parent = t->parent;
120
+ return canonical;
121
+ }
122
+
123
+ /**
124
+ * call-seq:
125
+ * Clangc::Type#pointee_type => Clangc::Type
126
+ *
127
+ * For pointer types, returns the type of the pointee.
128
+ */
129
+ VALUE
130
+ c_Type_get_pointee_type(VALUE self)
131
+ {
132
+ Type_t *t;
133
+ Data_Get_Struct(self, Type_t, t);
134
+ Type_t *p;
135
+ VALUE pointee;
136
+ R_GET_CLASS_DATA("Clangc", Type, pointee, p);
137
+ p->data = clang_getPointeeType(t->data);
138
+ p->parent = t->parent;
139
+ return pointee;
140
+ }
141
+
142
+ /**
143
+ * call-seq:
144
+ * Clangc::Type#is_const_qualified => true/false
145
+ *
146
+ * Determine whether a Clangc::Type instance has the "const" qualifier set,
147
+ * without looking through typedefs that may have added "const" at a
148
+ * different level.
149
+ */
150
+ VALUE
151
+ c_Type_is_const_qualified(VALUE self)
152
+ {
153
+ Type_t *t;
154
+ Data_Get_Struct(self, Type_t, t);
155
+ return NOT_0_2_RVAL(clang_isConstQualifiedType(t->data));
156
+ }
157
+
158
+ /**
159
+ * call-seq:
160
+ * Clangc::Type#is_volatile_qualified => true/false
161
+ *
162
+ * Determine whether a Clangc::Type instance has the "volatile" qualifier set,
163
+ * without looking through typedefs that may have added "const" at a
164
+ * different level.
165
+ */
166
+ VALUE
167
+ c_Type_is_volatile_qualified(VALUE self)
168
+ {
169
+ Type_t *t;
170
+ Data_Get_Struct(self, Type_t, t);
171
+ return NOT_0_2_RVAL(clang_isVolatileQualifiedType(t->data));
172
+ }
173
+
174
+ /**
175
+ * call-seq:
176
+ * Clangc::Type#is_restrict_qualified => true/false
177
+ *
178
+ * Determine whether a Clangc::Type instance has the "restrict" qualifier set,
179
+ * without looking through typedefs that may have added "const" at a
180
+ * different level.
181
+ */
182
+ VALUE
183
+ c_Type_is_restrict_qualified(VALUE self)
184
+ {
185
+ Type_t *t;
186
+ Data_Get_Struct(self, Type_t, t);
187
+ return NOT_0_2_RVAL(clang_isRestrictQualifiedType(t->data));
188
+ }
189
+
190
+ /**
191
+ * call-seq:
192
+ * Clangc::Type#result_type => Clangc::Type
193
+ *
194
+ * Retrieve the return type associated with a function type.
195
+ *
196
+ * If a non-function type is passed in (Clangc::Type#kind !=
197
+ * Clangc::TypeKind::FunctionNoProto for example),
198
+ * an invalid type is returned.
199
+ */
200
+ VALUE
201
+ c_Type_get_result_type(VALUE self)
202
+ {
203
+ Type_t *t;
204
+ Data_Get_Struct(self, Type_t, t);
205
+ Type_t *r;
206
+ VALUE result;
207
+ R_GET_CLASS_DATA("Clangc", Type, result, r);
208
+ r->data = clang_getResultType(t->data);
209
+ r->parent = t->parent;
210
+ return result;
211
+ }
212
+
213
+ /**
214
+ * call-seq:
215
+ * Clangc::Type#calling_conv => Clangc::CallingConv
216
+ *
217
+ * Retrieve the calling convention associated with a function type.
218
+ *
219
+ * If a non-function type is passed in, Clangc::CallingConv::Invalid is returned.
220
+ */
221
+ VALUE
222
+ c_Type_get_calling_conv(VALUE self)
223
+ {
224
+ Type_t *t;
225
+ Data_Get_Struct(self, Type_t, t);
226
+ return CUINT_2_NUM(clang_getFunctionTypeCallingConv(t->data));
227
+ }
228
+ /**
229
+ * call-seq:
230
+ * Clangc::Type#num_arg_types => Integer
231
+ *
232
+ * Retrieve the number of non-variadic parameters associated with a
233
+ * function type.
234
+ *
235
+ * If a non-function type is passed in, -1 is returned.
236
+ */
237
+ VALUE
238
+ c_Type_get_num_arg_types(VALUE self)
239
+ {
240
+ Type_t *t;
241
+ Data_Get_Struct(self, Type_t, t);
242
+ return CINT_2_NUM(clang_getNumArgTypes(t->data));
243
+ }
244
+
245
+ /**
246
+ * call-seq:
247
+ * Clangc::Type#arg_type(Integer) => Clangc::Type
248
+ *
249
+ * Retrieve the type of a parameter of a function type.
250
+ *
251
+ * If a non-function type is passed in or the function does not have enough
252
+ * parameters, an invalid type is returned.
253
+ * Better alternative is
254
+ * <code>Clangc::Type#arg_types => Array</code>
255
+ */
256
+ VALUE
257
+ c_Type_get_arg_type(VALUE self, VALUE index)
258
+ {
259
+ Type_t *t;
260
+ Data_Get_Struct(self, Type_t, t);
261
+ int max = clang_getNumArgTypes(t->data);
262
+ /*args number can be < 0 if self is not a function type
263
+ In this case I set max to zero and let this method returns
264
+ an invalid type. It the user responsabilitty to check
265
+ if the Clangc::Type#kind is a Functionproto or Functionnoproto
266
+ */
267
+ if (max < 0) max = 0;
268
+ unsigned int c_index = NUM2UINT(index);
269
+ CHECK_IN_RANGE(c_index, 0, max);
270
+ Type_t *a;
271
+ VALUE arg;
272
+ R_GET_CLASS_DATA("Clangc", Type, arg, a);
273
+ a->data = clang_getArgType(t->data, c_index);
274
+ a->parent = t->parent;
275
+ return arg;
276
+ }
277
+
278
+ /**
279
+ * call-seq:
280
+ * Clangc::Type#element_type => Clangc::Type
281
+ *
282
+ * Return the element type of an array, complex, or vector type.
283
+ *
284
+ * If a type is passed in that is not an array, complex, or vector type,
285
+ * an invalid type is returned.
286
+ */
287
+ VALUE
288
+ c_Type_get_element_type(VALUE self)
289
+ {
290
+ Type_t *t;
291
+ Data_Get_Struct(self, Type_t, t);
292
+ Type_t *e;
293
+ VALUE element;
294
+ R_GET_CLASS_DATA("Clangc", Type, element, e);
295
+ e->data = clang_getElementType(t->data);
296
+ e->parent = t->parent;
297
+ return element;
298
+ }
299
+
300
+ /**
301
+ * call-seq:
302
+ * Clangc::Type#num_elements => Num
303
+ *
304
+ * Return the number of elements of an array or vector type.
305
+ *
306
+ * If a type is passed in that is not an array or vector type,
307
+ * -1 is returned.
308
+ */
309
+ VALUE
310
+ c_Type_get_num_elements(VALUE self)
311
+ {
312
+ Type_t *t;
313
+ Data_Get_Struct(self, Type_t, t);
314
+ return CLLONG_2_NUM(clang_getNumElements(t->data));
315
+ }
316
+
317
+ /**
318
+ * call-seq:
319
+ * Clangc::Type#array_element_type => Clangc::Type
320
+ *
321
+ * Return the element type of an array type.
322
+ *
323
+ * If a non-array type is passed in, an invalid type is returned.
324
+ */
325
+ VALUE
326
+ c_Type_get_array_element_type(VALUE self)
327
+ {
328
+ Type_t *t;
329
+ Data_Get_Struct(self, Type_t, t);
330
+ Type_t *e;
331
+ VALUE element;
332
+ R_GET_CLASS_DATA("Clangc", Type, element, e);
333
+ e->data = clang_getArrayElementType(t->data);
334
+ e->parent = t->parent;
335
+ return element;
336
+ }
337
+
338
+ /**
339
+ * call-seq:
340
+ * Clangc::Type#array_size => Num
341
+ *
342
+ * Return the array size of a constant array.
343
+ *
344
+ * If a non-array type is passed in, -1 is returned.
345
+ */
346
+ VALUE
347
+ c_Type_get_array_size(VALUE self)
348
+ {
349
+ Type_t *t;
350
+ Data_Get_Struct(self, Type_t, t);
351
+ return CLLONG_2_NUM(clang_getArraySize(t->data));
352
+ }
353
+
354
+ /**
355
+ * call-seq:
356
+ * Clangc::Type#is_pod => true/false
357
+ *
358
+ * Return true if the Clangc::Type is a POD (plain old data) type, and false
359
+ * otherwise.
360
+ */
361
+ VALUE
362
+ c_Type_is_pod(VALUE self)
363
+ {
364
+ Type_t *t;
365
+ Data_Get_Struct(self, Type_t, t);
366
+ return NOT_0_2_RVAL(clang_isPODType(t->data));
367
+ }
368
+
369
+ /**
370
+ * call-seq:
371
+ * Clangc::Type#type_declaration => Clangc::Cursor
372
+ *
373
+ * Return the cursor for the declaration of the given type.
374
+ */
375
+ VALUE
376
+ c_Type_get_type_declaration(VALUE self)
377
+ {
378
+ Type_t *t;
379
+ Data_Get_Struct(self, Type_t, t);
380
+ Cursor_t *d;
381
+ VALUE declaration;
382
+ R_GET_CLASS_DATA("Clangc", Cursor, declaration, d);
383
+
384
+ /* Here we get the parent of the parent of self
385
+ * As self is a Clangc::Type, its parent is a Clangc::Cursor
386
+ * and its parent is a TranslationUnit.
387
+ * TL/DR The parent of the returned cursor is a TranslationUnit
388
+ * */
389
+ Cursor_t *c;
390
+ Data_Get_Struct(t->parent, Cursor_t, c);
391
+
392
+ d->data = clang_getTypeDeclaration(t->data);
393
+ d->parent = c->parent;
394
+ return declaration;
395
+ }
396
+
397
+ /**
398
+ * call-seq:
399
+ * Clangc::Type#is_function_type_variadic => true/false
400
+ *
401
+ * Return true if the Clangc::Type is a variadic function type, and false
402
+ * otherwise.
403
+ */
404
+ VALUE
405
+ c_Type_is_function_type_variadic(VALUE self)
406
+ {
407
+ Type_t *t;
408
+ Data_Get_Struct(self, Type_t, t);
409
+ return NOT_0_2_RVAL(clang_isFunctionTypeVariadic(t->data));
410
+ }
411
+
412
+ /**
413
+ * call-seq:
414
+ * Clangc::Type#align_of => Number
415
+ *
416
+ * Return the alignment of a type in bytes as per C++[expr.alignof]
417
+ * standard.
418
+ *
419
+ * If the type declaration is invalid, Clangc::TypeLayoutError::INVALID is
420
+ * returned.
421
+ * If the type declaration is an incomplete type,
422
+ * Clangc::TypeLayoutError::INCOMPLETE
423
+ * is returned.
424
+ * If the type declaration is a dependent type,
425
+ * Clangc::TypeLayoutError::DEPENDENT is
426
+ * returned.
427
+ * If the type declaration is not a constant size type,
428
+ * Clangc::TypeLayoutError::NOT_CONSTANT_SIZE is returned.
429
+ */
430
+ VALUE
431
+ c_Type_get_align_of(VALUE self)
432
+ {
433
+ Type_t *t;
434
+ Data_Get_Struct(self, Type_t, t);
435
+ return CLLONG_2_NUM(clang_Type_getAlignOf(t->data));
436
+ }
437
+
438
+ /**
439
+ * call-seq:
440
+ * Clangc::Type#size_of => Number
441
+ *
442
+ * Return the size of a type in bytes as per C++[expr.sizeof] standard.
443
+ *
444
+ * If the type declaration is invalid, Clangc::TypeLayoutError::INVALID is
445
+ * returned.
446
+ * If the type declaration is an incomplete type,
447
+ * Clangc::TypeLayoutError::INCOMPLETE
448
+ * is returned.
449
+ * If the type declaration is a dependent type,
450
+ * Clangc::TypeLayoutError::DEPENDENT is
451
+ * returned.
452
+ */
453
+ VALUE
454
+ c_Type_get_size_of(VALUE self)
455
+ {
456
+ Type_t *t;
457
+ Data_Get_Struct(self, Type_t, t);
458
+ return CLLONG_2_NUM(clang_Type_getSizeOf(t->data));
459
+ }
460
+
461
+ /**
462
+ * call-seq:
463
+ * Clangc::Type#class_type => Clangc::Type
464
+ *
465
+ * Return the class type of an member pointer type.
466
+ *
467
+ * If a non-member-pointer type is passed in, an invalid type is returned.
468
+ */
469
+ VALUE
470
+ c_Type_get_class_type(VALUE self)
471
+ {
472
+ Type_t *t;
473
+ Data_Get_Struct(self, Type_t, t);
474
+ VALUE class_type;
475
+ Type_t *ct;
476
+ R_GET_CLASS_DATA("Clangc", Type, class_type, ct);
477
+ ct->data = clang_Type_getClassType(t->data);
478
+ ct->parent = t->parent;
479
+ return class_type;
480
+ }
481
+
482
+ /**
483
+ * call-seq:
484
+ * Clangc::Type#offset_of(String) => Number
485
+ *
486
+ * Return the offset of a field named S in a record of type T in bits
487
+ * as it would be returned by __offsetof__ as per C++11[18.2p4]
488
+ *
489
+ * If the cursor is not a record field, Clangc::TypeLayoutError::INVALID is
490
+ * returned.
491
+ * If the field's type declaration is an incomplete type,
492
+ * Clangc::TypeLayoutError::INCOMPLETE
493
+ * is returned.
494
+ * If the field's type declaration is a dependent type,
495
+ * Clangc::TypeLayoutError::DEPENDENT is
496
+ * returned.
497
+ * If the field's name S is not found,
498
+ * Clanc::TypeLayoutError::INVALID_FIELD_NAME is returned
499
+ */
500
+ VALUE
501
+ c_Type_get_offset_of(VALUE self, VALUE field)
502
+ {
503
+ Type_t *t;
504
+ Data_Get_Struct(self, Type_t, t);
505
+ return CLLONG_2_NUM(clang_Type_getOffsetOf(t->data, RSTRING_2_CHAR(field)));
506
+ }
507
+
508
+ /**
509
+ * call-seq:
510
+ * Clangc::Type#num_template_arguments => Integer
511
+ *
512
+ * Returns the number of template arguments for given class template
513
+ * specialization, or -1 if type \c T is not a class template specialization.
514
+ *
515
+ * Variadic argument packs count as only one argument, and can not be inspected
516
+ * further.
517
+ */
518
+ VALUE
519
+ c_Type_get_num_template_arguments(VALUE self)
520
+ {
521
+ Type_t *t;
522
+ Data_Get_Struct(self, Type_t, t);
523
+ return CINT_2_NUM(clang_Type_getNumTemplateArguments(t->data));
524
+ }
525
+
526
+ /**
527
+ * call-seq:
528
+ * Clangc::Type#template_argument_as_type => Clangc::Type
529
+ *
530
+ * Returns the type template argument of a template class specialization
531
+ * at given index.
532
+ *
533
+ * This function only returns template type arguments and does not handle
534
+ * template template arguments or variadic packs.
535
+ */
536
+ VALUE
537
+ c_Type_get_template_argument_as_type(VALUE self, VALUE index)
538
+ {
539
+ Type_t *t;
540
+ Data_Get_Struct(self, Type_t, t);
541
+ VALUE template_argument;
542
+ Type_t *ta;
543
+ R_GET_CLASS_DATA("Clangc", Type, template_argument, ta);
544
+ ta->data = clang_Type_getTemplateArgumentAsType(t->data, NUM2UINT(index));
545
+ ta->parent = t->parent;
546
+ return template_argument;
547
+ }
548
+
549
+ /**
550
+ * call-seq:
551
+ * Clangc::Type#cxx_ref_qualifier => Clangc::RefQualifiers
552
+ *
553
+ * Retrieve the ref-qualifier kind of a function or method.
554
+ *
555
+ * The ref-qualifier is returned for C++ functions or methods. For other types
556
+ * or non-C++ declarations, CXRefQualifier_None is returned.
557
+ */
558
+ VALUE
559
+ c_Type_get_cxx_ref_qualifier(VALUE self)
560
+ {
561
+ Type_t *t;
562
+ Data_Get_Struct(self, Type_t, t);
563
+ return INT2NUM(clang_Type_getCXXRefQualifier(t->data));
564
+ }