For the complete documentation index, see llms.txt. This page is also available as Markdown.

Clang

Overview

The clang parser is the most powerful and complete parser shipped with IDA Pro. It is based on the clang compiler and can handle a wide variety of C/C++/Obj-C header files, including those with complex preprocessor directives and macros. It is meant as a replacement for IDAClang.

Note that cfg/idaclang.cfg is used as the config file for the clang parser as well, so that the new parser automatically picks up the settings you may have already configured for IDAClang.

LLVM

It is based on the LLVM project (21.1.5) and uses the clang compiler to parse header files and extract type information.

Motivation

Legacy parser

The built-in legacy parser is a simple yet efficient parser that can handle C header files. However, it is not very good at handling C++ header files.

IDAClang parser

The IDAClang parser can handle C++ header files, but it is purely based on the clang compiler and does not handle IDA-specific keywords, such as _BYTE or _QWORD.

clang parser

The official clang parser bridges the gap between the legacy parser and IDAClang, being able to handle both C and C++ header files, while also supporting IDA-specific keywords. On top of that, it adds support for Objective-C and Objective-C++ header files. You can enable the clang parser by going to Options → Compiler and setting the Source parser to clang.

There are three ways of importing types using the clang parser:

  1. Using the Add type option in Local Types window.

  2. Using the File → Load file → Parse C header file... option in the menu bar.

  3. Scripting the parsing process using IDAPython.

Examples

VTables

The following types will be generated in the database:

IDA-specific keywords

The following code will be correctly parsed by the clang parser:

It will be added to the database as:

C++ templates

To parse this code:

  1. Go to Options → Compiler → Parser specific options and mark "No IDA specific extensions".

  2. Put it in an include file and select File → Load file → Parse C header file... from the menu bar.

The parsed result will be:

C++20

In order to parse C++20 code, make sure your Include directories and Arguments options are set up correctly. For example, You can use the following commands to figure out the correct include paths and arguments for your system:

The Arguments option should include the -std=c++20 flag:

Here's an example of C++20 code that can be parsed by the clang parser:

Final result:

Objective-C

Before parsing, make sure to set the right language in Options → Compiler → Parser specific options (Objective-C or Objective-C++), and to have the right include paths set in Options → Compiler → Include directories.

To see what these are, for example on a macOS system, you can run the following command in the terminal:

You might also have to include the proper presets, for example:

In the end, the parsed result looks like this:

All the dependent types, such as NSString and NSInteger, will also be added to the database.

Fixed structs

Fixed layout structures can be created or edited directly in Local Types using the C-syntax editor. Make sure that IDA specific extensions are not disabled in Options → Compiler → Parser specific options. By default they are enabled, so you should be good to go.

The parser UI

Enabling the clang parser

Make sure to select clang as the Source parser in the Options → Compiler dialog:

Compiler Options

The parser can be fine-tuned using the Parser specific options button.

Parser Specific Options

Apply tinfo to demangled names

If enabled, the parser will look for mangled names in the database as types are being parsed, and automatically apply the type info to the address where the name was found.

For example, if this type is parsed:

And the function MyService::probe() is present in the database, a more precise prototype will automatically be applied to the function:

No IDA specific extensions

If enabled, the parser will not recognize IDA-specific keywords, such as _BYTE or _QWORD. This is useful if you want to parse code that uses these keywords for other purposes, such as Windows driver code.

Smart pointers

A semicolon-separated list of smart pointer template names. The parser will simplify instances of such templates to simple pointers when they are encountered in the input source.

For example, consider the OSSharedPtr template class from the XNU kernel source code:

Now let's say idaclang finds an instance of this template class in the input source:

Previously, to describe this type, the parser had to create 4 different types:

To avoid all that noise, you can add OSSharedPtr to the Smart pointers list, which will instruct the parser to reduce the template instances to simple pointers, simplifying the analysis:

For example, this is the configuration we use when generating the type libraries for xnu_7195_x64.til: OSPtr;OSSharedPtr;OSTaggedPtr;OSTaggedSharedPtr

Language

The language to use for parsing. This can be set to C, C++, Objective-C, or Objective-C++. Make sure to set the right flags in the Options → Compiler → Arguments field as well, for example -std=c++20 for C++20 code.

If enabled, the parser will print the abstract syntax tree (AST) of the parsed code in the output window. This is useful for debugging purposes. Slows down the parsing process significantly.

Adding types

Go to Local Types window, right-click and select Add type. Paste the code you want to parse in the editor and click OK.

Add type

Alternatively, you can use the File → Load file → Parse C header file... option in the menu bar to parse an entire header file. Using the parser in this way is generally faster and more robust than using the Add type option, which is meant for quick parsing of small code snippets.

The parser API

It is possible to invoke the parser from IDAPython. You may want to take a look at the ida_srclang package.

Here's a simple example of how one can use the API to parse an Objective-C header file:

Building type libraries with tilib

TILIB is a utility to create custom type libraries for IDA Pro. You can find it in the tools folder within the main IDA installation directory. For an overview just run tilib.

Basic examples

Important flags:

  • -TC - enables the clang parser

  • -P - enables C++ mode

  • -I - is used to specify include directories

  • -CT - is used to specify additional clang arguments, for example -std=c++20 for C++20 code

  • -v - you'll see CLANG command line: printed, which is the easiest way to debug your configuration

C++

Objective-C

Objective-C++

Complex type libraries

Qt

This example will be given using macOS and Qt 6.

To install Qt, one can use Homebrew:

For convenience, you can set some environment variables. These may vary based on your system and Qt installation.

Create an umbrella header (qt.h):

Create the type library:

Note that sometimes there may be inconsistencies between IDA's clang and the system's clang, which may cause parsing errors. For example, if Apple's clang header files use some features that are not supported by the LLVM clang, you may need to add some additional flags to the command line to work around the issue. You can use -v to see the exact command line used for parsing and debug the problem. However, if that doesn't work and the parser gets in your way, you can also pass -e in order to ignore potential parsing errors and get as much of the type information as possible. Most likely there will still be a good amount of useful information extracted.

To verify what has been parsed into the type library, dump the information using tilib -lc qt_mac_arm64.til > qt_mac_arm64.txt.

XNU Kernel

If you're on a macOS system, this is pretty straightforward, since you can use the system's SDK and clang headers.

Create xnu.h and include your headers of interest:

You can check your OS version and the corresponding SDK version using sw_vers.

Creating the type library for Darwin Kernel headers of macOS 26.3:

macOS/iOS SDK

The same process can be applied to create type libraries for macOS or iOS SDKs. Just make sure to set the right target and include paths.

An umbrella header (macos_sdk.h) can be found here:

8KB
Open

.

Here's a recipe of how to generate the umbrella header on your system:

Generate the type library for macOS:

For iOS, change the SDK path and the target:

Example tilib command:

Use -v (verbose) or -e (ignore errors) if you run into issues.

Last updated

Was this helpful?