[TargetVersion] Only enable on RISC-V and AArch64 (#115991)
[llvm-project.git] / clang / docs / LibClang.rst
blob08cf452a0df6c421453057597e4e009c27561d89
1 .. role:: raw-html(raw)
2     :format: html
4 Libclang tutorial
5 =================
6 The C Interface to Clang provides a relatively small API that exposes facilities for parsing source code into an abstract syntax tree (AST), loading already-parsed ASTs, traversing the AST, associating physical source locations with elements within the AST, and other facilities that support Clang-based development tools.
7 This C interface to Clang will never provide all of the information representation stored in Clang's C++ AST, nor should it: the intent is to maintain an API that is relatively stable from one release to the next, providing only the basic functionality needed to support development tools.
8 The entire C interface of libclang is available in the file `Index.h`_
10 Essential types overview
11 -------------------------
13 All types of libclang are prefixed with ``CX``
15 CXIndex
16 ~~~~~~~
17 An Index that consists of a set of translation units that would typically be linked together into an executable or library.
19 CXTranslationUnit
20 ~~~~~~~~~~~~~~~~~
21 A single translation unit, which resides in an index.
23 CXCursor
24 ~~~~~~~~
25 A cursor representing a pointer to some element in the abstract syntax tree of a translation unit.
28 Code example
29 """"""""""""
31 .. code-block:: cpp
33   // file.cpp
34   struct foo{
35     int bar;
36     int* bar_pointer;
37   };
39 .. code-block:: cpp
41   #include <clang-c/Index.h>
42   #include <iostream>
44   int main(){
45     CXIndex index = clang_createIndex(0, 0); //Create index
46     CXTranslationUnit unit = clang_parseTranslationUnit(
47       index,
48       "file.cpp", nullptr, 0,
49       nullptr, 0,
50       CXTranslationUnit_None); //Parse "file.cpp"
53     if (unit == nullptr){
54       std::cerr << "Unable to parse translation unit. Quitting.\n";
55       return 0;
56     }
57     CXCursor cursor = clang_getTranslationUnitCursor(unit); //Obtain a cursor at the root of the translation unit
58   }
60 Visiting elements of an AST
61 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 The elements of an AST can be recursively visited with pre-order traversal with ``clang_visitChildren``.
64 .. code-block:: cpp
66   clang_visitChildren(
67     cursor, //Root cursor
68     [](CXCursor current_cursor, CXCursor parent, CXClientData client_data){
70       CXString current_display_name = clang_getCursorDisplayName(current_cursor);
71       //Allocate a CXString representing the name of the current cursor
73       std::cout << "Visiting element " << clang_getCString(current_display_name) << "\n";
74       //Print the char* value of current_display_name
76       clang_disposeString(current_display_name);
77       //Since clang_getCursorDisplayName allocates a new CXString, it must be freed. This applies
78       //to all functions returning a CXString
80       return CXChildVisit_Recurse;
83     }, //CXCursorVisitor: a function pointer
84     nullptr //client_data
85     );
87 The return value of ``CXCursorVisitor``, the callable argument of ``clang_visitChildren``, can return one of the three:
89 #. ``CXChildVisit_Break``: Terminates the cursor traversal
91 #. ``CXChildVisit_Continue``: Continues the cursor traversal with the next sibling of the cursor just visited, without visiting its children.
93 #. ``CXChildVisit_Recurse``: Recursively traverse the children of this cursor, using the same visitor and client data
95 The expected output of that program is
97 .. code-block::
99   Visiting element foo
100   Visiting element bar
101   Visiting element bar_pointer
104 Extracting information from a Cursor
105 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
106 .. The following functions take a ``CXCursor`` as an argument and return associated information.
110 Extracting the Cursor kind
111 """"""""""""""""""""""""""
113 ``CXCursorKind clang_getCursorKind(CXCursor)`` Describes the kind of entity that a cursor refers to. Example values:
115 - ``CXCursor_StructDecl``: A C or C++ struct.
116 - ``CXCursor_FieldDecl``: A field in a struct, union, or C++ class.
117 - ``CXCursor_CallExpr``: An expression that calls a function.
120 Extracting the Cursor type
121 """"""""""""""""""""""""""
122 ``CXType clang_getCursorType(CXCursor)``: Retrieve the type of a CXCursor (if any).
124 A ``CXType`` represents a complete C++ type, including qualifiers and pointers. It has a member field ``CXTypeKind kind`` and additional opaque data.
126 Example values for ``CXTypeKind kind``
128 - ``CXType_Invalid``: Represents an invalid type (e.g., where no type is available)
129 - ``CXType_Pointer``: A pointer to another type
130 - ``CXType_Int``: Regular ``int``
131 - ``CXType_Elaborated``: Represents a type that was referred to using an elaborated type keyword e.g. struct S, or via a qualified name, e.g., N::M::type, or both.
133 Any ``CXTypeKind`` can be converted to a ``CXString`` using ``clang_getTypeKindSpelling(CXTypeKind)``.
135 A ``CXType`` holds additional necessary opaque type info, such as:
137 - Which struct was referred to?
138 - What type is the pointer pointing to?
139 - Qualifiers (e.g. ``const``, ``volatile``)?
141 Qualifiers of a ``CXType`` can be queried with:
143 - ``clang_isConstQualifiedType(CXType)`` to check for ``const``
144 - ``clang_isRestrictQualifiedType(CXType)`` to check for ``restrict``
145 - ``clang_isVolatileQualifiedType(CXType)`` to check for ``volatile``
147 Code example
148 """"""""""""
149 .. code-block:: cpp
151   //structs.cpp
152   struct A{
153     int value;
154   };
155   struct B{
156     int value;
157     A struct_value;
158   };
160 .. code-block:: cpp
162   #include <clang-c/Index.h>
163   #include <iostream>
165   int main(){
166     CXIndex index = clang_createIndex(0, 0); //Create index
167     CXTranslationUnit unit = clang_parseTranslationUnit(
168       index,
169       "structs.cpp", nullptr, 0,
170       nullptr, 0,
171       CXTranslationUnit_None); //Parse "structs.cpp"
173     if (unit == nullptr){
174       std::cerr << "Unable to parse translation unit. Quitting.\n";
175       return 0;
176     }
177     CXCursor cursor = clang_getTranslationUnitCursor(unit); //Obtain a cursor at the root of the translation unit
179     clang_visitChildren(
180     cursor,
181     [](CXCursor current_cursor, CXCursor parent, CXClientData client_data){
182       CXType cursor_type = clang_getCursorType(current_cursor);
184       CXString type_kind_spelling = clang_getTypeKindSpelling(cursor_type.kind);
185       std::cout << "Type Kind: " << clang_getCString(type_kind_spelling);
186       clang_disposeString(type_kind_spelling);
188       if(cursor_type.kind == CXType_Pointer ||                     // If cursor_type is a pointer
189         cursor_type.kind == CXType_LValueReference ||              // or an LValue Reference (&)
190         cursor_type.kind == CXType_RValueReference){               // or an RValue Reference (&&),
191         CXType pointed_to_type = clang_getPointeeType(cursor_type);// retrieve the pointed-to type
193         CXString pointed_to_type_spelling = clang_getTypeSpelling(pointed_to_type);     // Spell out the entire
194         std::cout << "pointing to type: " << clang_getCString(pointed_to_type_spelling);// pointed-to type
195         clang_disposeString(pointed_to_type_spelling);
196       }
197       else if(cursor_type.kind == CXType_Record){
198         CXString type_spelling = clang_getTypeSpelling(cursor_type);
199         std::cout <<  ", namely " << clang_getCString(type_spelling);
200         clang_disposeString(type_spelling);
201       }
202       std::cout << "\n";
203       return CXChildVisit_Recurse;
204     },
205     nullptr
206     );
208 The expected output of program is:
210 .. code-block::
212   Type Kind: Record, namely A
213   Type Kind: Int
214   Type Kind: Record, namely B
215   Type Kind: Int
216   Type Kind: Record, namely A
217   Type Kind: Record, namely A
220 Reiterating the difference between ``CXType`` and ``CXTypeKind``: For an example
222 .. code-block:: cpp
224    const char* __restrict__ variable;
226 - Type Kind will be: ``CXType_Pointer`` spelled ``"Pointer"``
227 - Type will be a complex ``CXType`` structure, spelled ``"const char* __restrict__``
229 Retrieving source locations
230 """""""""""""""""""""""""""
232 ``CXSourceRange clang_getCursorExtent(CXCursor)`` returns a ``CXSourceRange``, representing a half-open range in the source code.
234 Use ``clang_getRangeStart(CXSourceRange)`` and ``clang_getRangeEnd(CXSourceRange)`` to retrieve the starting and end ``CXSourceLocation`` from a source range, respectively.
236 Given a ``CXSourceLocation``, use ``clang_getExpansionLocation`` to retrieve file, line and column of a source location.
238 Code example
239 """"""""""""
240 .. code-block:: cpp
242   // Again, file.cpp
243   struct foo{
244     int bar;
245     int* bar_pointer;
246   };
247 .. code-block:: cpp
249   clang_visitChildren(
250     cursor,
251     [](CXCursor current_cursor, CXCursor parent, CXClientData client_data){
253       CXType cursor_type = clang_getCursorType(current_cursor);
254       CXString cursor_spelling = clang_getCursorSpelling(current_cursor);
255       CXSourceRange cursor_range = clang_getCursorExtent(current_cursor);
256       std::cout << "Cursor " << clang_getCString(cursor_spelling);
258       CXFile file;
259       unsigned start_line, start_column, start_offset;
260       unsigned end_line, end_column, end_offset;
262       clang_getExpansionLocation(clang_getRangeStart(cursor_range), &file, &start_line, &start_column, &start_offset);
263       clang_getExpansionLocation(clang_getRangeEnd  (cursor_range), &file, &end_line  , &end_column  , &end_offset);
264       std::cout << " spanning lines " << start_line << " to " << end_line;
265       clang_disposeString(cursor_spelling);
267       std::cout << "\n";
268       return CXChildVisit_Recurse;
269     },
270     nullptr
271   );
273 The expected output of this program is:
275 .. code-block::
277   Cursor foo spanning lines 2 to 5
278   Cursor bar spanning lines 3 to 3
279   Cursor bar_pointer spanning lines 4 to 4
281 Complete example code
282 ~~~~~~~~~~~~~~~~~~~~~
284 .. code-block:: cpp
286   #include <clang-c/Index.h>
287   #include <iostream>
289   int main(){
290     CXIndex index = clang_createIndex(0, 0); //Create index
291     CXTranslationUnit unit = clang_parseTranslationUnit(
292       index,
293       "file.cpp", nullptr, 0,
294       nullptr, 0,
295       CXTranslationUnit_None); //Parse "file.cpp"
297     if (unit == nullptr){
298       std::cerr << "Unable to parse translation unit. Quitting.\n";
299       return 0;
300     }
301     CXCursor cursor = clang_getTranslationUnitCursor(unit); //Obtain a cursor at the root of the translation unit
304     clang_visitChildren(
305     cursor,
306     [](CXCursor current_cursor, CXCursor parent, CXClientData client_data){
307       CXType cursor_type = clang_getCursorType(current_cursor);
309       CXString type_kind_spelling = clang_getTypeKindSpelling(cursor_type.kind);
310       std::cout << "TypeKind: " << clang_getCString(type_kind_spelling);
311       clang_disposeString(type_kind_spelling);
313       if(cursor_type.kind == CXType_Pointer ||                     // If cursor_type is a pointer
314         cursor_type.kind == CXType_LValueReference ||              // or an LValue Reference (&)
315         cursor_type.kind == CXType_RValueReference){               // or an RValue Reference (&&),
316         CXType pointed_to_type = clang_getPointeeType(cursor_type);// retrieve the pointed-to type
318         CXString pointed_to_type_spelling = clang_getTypeSpelling(pointed_to_type);     // Spell out the entire
319         std::cout << "pointing to type: " << clang_getCString(pointed_to_type_spelling);// pointed-to type
320         clang_disposeString(pointed_to_type_spelling);
321       }
322       else if(cursor_type.kind == CXType_Record){
323         CXString type_spelling = clang_getTypeSpelling(cursor_type);
324         std::cout <<  ", namely " << clang_getCString(type_spelling);
325         clang_disposeString(type_spelling);
326       }
327       std::cout << "\n";
328       return CXChildVisit_Recurse;
329     },
330     nullptr
331     );
334     clang_visitChildren(
335     cursor,
336     [](CXCursor current_cursor, CXCursor parent, CXClientData client_data){
338       CXType cursor_type = clang_getCursorType(current_cursor);
339       CXString cursor_spelling = clang_getCursorSpelling(current_cursor);
340       CXSourceRange cursor_range = clang_getCursorExtent(current_cursor);
341       std::cout << "Cursor " << clang_getCString(cursor_spelling);
343       CXFile file;
344       unsigned start_line, start_column, start_offset;
345       unsigned end_line, end_column, end_offset;
347       clang_getExpansionLocation(clang_getRangeStart(cursor_range), &file, &start_line, &start_column, &start_offset);
348       clang_getExpansionLocation(clang_getRangeEnd  (cursor_range), &file, &end_line  , &end_column  , &end_offset);
349       std::cout << " spanning lines " << start_line << " to " << end_line;
350       clang_disposeString(cursor_spelling);
352       std::cout << "\n";
353       return CXChildVisit_Recurse;
354     },
355     nullptr
356     );
357   }
360 .. _Index.h: https://github.com/llvm/llvm-project/blob/main/clang/include/clang-c/Index.h