Giter Club home page Giter Club logo

cppast's Introduction

cppast

Library interface to the C++ AST — parse source files, synthesize entities, get documentation comments and generate code.

Motivation

If you're writing a tool that needs access to the C++ AST (i.e. documentation generator, reflection library, …), your only option apart from writing your own parser is to use clang. It offers three interfaces for tools, but the only one that really works for standalone applications is libclang. However, libclang has various limitations and does not expose the entire AST.

So there is no feasible option — except for this library. It was originally a part of the standardese documentation generator, but has been extracted into an independent library.

See this blog post for more information about the motiviation and design.

Features

  • Exposes (almost) all C++ entities: Supports everything from functions to classes, templates to friend declarations, macros to enums;
  • Exposes full information about C++ types;
  • Supports and exposes documentation comments in various formats with smart entity matching;
  • Supports C++11 attributes (including user-defined ones);
  • AST hierarchy completely decoupled from parser: This allows synthesizing AST entities and multiple parsing backends;
  • Parser based on libclang: While libclang does have its limitations and/or bugs, the implemented parser uses various workarounds/hacks to provide a parser that breaks only in rare edge cases you won't notice. See issues tagged with libclang-parser for a list;
  • Simple yet customizable code generation interface.

Missing features

  • Support modification of parsed entities: they're currently all immutable, need to find a decent way of implementing that
  • Full support for expressions: currently only literal expressions are exposed;
  • Support for statements: currently function bodies aren't parsed at all;
  • Support for member specialization: members of a template can be specialized separately, this is not supported.

Example

See tool/main.cpp for a simple application of the library that prints the AST.

Documentation

TODO, refer to documentation comments in header file.

Installation

The library can be used as CMake subdirectory, download it and call add_subdirectory(path/to/cppast), then link to the cppast target and enable C++11 or higher.

The parser needs libclang and the clang++ binary, at least version 4.0.0. The clang++ binary will be found in PATH and in the same directory as the program that is being executed.

Note: The project will drop support for older LLVM versions very soon; this minimizes the workaround code when the libclang API catches up.

The CMake code requires llvm-config, you may need to install llvm and not just clang to get it (e.g. on ArchLinux). If llvm-config is in your path and the version is compatible, it should just work out of the box. Else you need to set the CMake variable LLVM_CONFIG_BINARY to the proper path.

If you don't have a proper clang version installed, it can also be downloaded. For that you need to set LLVM_DOWNLOAD_OS_NAME. This is the name of the operating system used on the LLVM pre-built binary archive, e.g. x86_64-linux-gnu-ubuntu-16.10 for Ubuntu 16.10.

You can also set LLVM_DOWNLOAD_URL to a custom url, to download a specific version or from a mirror.

If you don't have llvm-config, you need to pass the locations explictly. For that set the option LLVM_VERSION_EXPLICIT to the version you're using, LIBCLANG_LIBRARY to the location of the libclang library file, LIBCLANG_INCLUDE_DIR to the directory where the header files are located (so they can be included with clang-c/Index.h), and CLANG_BINARY to the full path of the clang++ exectuable.

The other dependencies like type_safe are installed automatically with FetchContent, if they're not installed already.

If you run into any issues with the installation, please report them.

Installation on Windows

Similar to the above instructions for cppast, there are a couple extra requirements for Windows.

The LLVM team does not currently distribute llvm-config.exe as part of the release binaries, so the only way to get it is through manual compilation or from 3rd parties. To prevent version mismatches, it's best to compile LLVM, libclang, and llvm-config.exe from source to ensure proper version matching. However, this is a non-trivial task, requiring a lot of time. The easiest way to work with LLVM and llvm-config.exe is to leverage the Chocolatey llvm package, and then compile the llvm-config.exe tool as a standalone binary.

  • Install Visual Studio 2017 with the Desktop C++ development feature enabled.
  • Install llvm and clang with choco install llvm
  • Check the version with clang.exe --version
  • Clone the LLVM project: git clone https://github.com/llvm/llvm-project
  • Checkout a release version matching the version output, such as 7.0.1, with git checkout llvmorg-7.0.1
  • cd llvm-project && mkdir build && cd build to prep the build environment.
  • cmake -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD="X86" -G "Visual Studio 15 2017" -Thost=x64 ..\llvm
    • This will configure clang and LLVM using a 64-bit toolchain. You'll have all the necessary projects configured for building clang, if you need other LLVM tools. See the LLVM documentation and clang documentation if you only need more assistance.
  • Open the LLVM.sln solution, and set the build type to be "Release".
  • Build the Tools/llvm-config target.
  • Copy the release binary to from build\Release\bin\llvm-config.exe to C:\Program Files\LLVM\bin\llvm-config.exe
  • Open a new Powershell window and test accessiblity of llvm-config.exe, it should return with it's help message.

In your cppast based project, if you run into issues with cmake not finding libclang, set LIBCLANG_LIBRARY to be C:/Program Files/LLVM/lib in your CMakeLists.txt file.

Quick API Overview

There are three class hierarchies that represent the AST:

  • cpp_entity: This is the base class for all C++ entities, i.e. declarations/definitions or things like static_assert() and function parameters;
  • cpp_type: This is the base class for the C++ type hierachy. It is used in the cpp_entity hierachy, i.e. cpp_type_alias contains an underlying_type(). Derived classes are, for example, cpp_builtin_type or cpp_pointer_type;
  • cpp_expression: This is the base class for all C++ expressions. It is used in the cpp_entity hierarchy, i.e. cpp_function_parameter contains a default_value() as expression. Derived classes are currently only cpp_literal_expression and cpp_unexposed_expression;

In order to parse a C++ source file, you need an implementation of parser. The library provides one, libclang_parser, but you could also write one yourself. Parsing is as simple as calling the parse() member function passing it three things:

  • An object of type cpp_entity_index: This is only required to resolve cross-references in the AST (i.e. if you want to get the cpp_class referenced in the return type of a cpp_function); it does not own the entities;
  • The path to the file;
  • An object of a type derived from compile_config: It stores the compilation flags used for compiling the file, it needs to match the parser, i.e. use libclang_compile_config with libclang_parser;

It returns nullptr on failure and prints diagnostics using a given diagnostic_logger — note that it will only return nullptr on fatal parse errors, else it will just skip the one where the error occured. If everything went succesful, it returns a std::unique_ptr<cpp_file> which is the top-level AST entity of the current file. You can then work with it.

cppast's People

Contributors

azure-pipelines[bot] avatar bkryza avatar carlosnihelton avatar chibidev avatar firefly35 avatar firodj avatar foonathan avatar grumbel avatar manu343726 avatar metalslime0 avatar minhlu12 avatar nealhow avatar ozars avatar rokups avatar saraedum avatar siennathesane avatar staticintlucas avatar sztomi avatar tobiashienzsch avatar topisani avatar ubsan avatar waitingtocompile avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cppast's Issues

Example using cpp_entity_index

Hey is it possible to use cpp_entity_index for our own purposes? I cant really see how.

What i am trying to do

As you know i am writing c# bindings generator. Part of the process is to drop certain parts of API that contain unknown types. Consider Texture* GetTexture() method. cpp_member_function pointing to GetTexture() provides return type Texture* as cpp_type. Is there any way to look into cpp_entity_index and see if there is class Texture defined? I did some debugging of cppast and i see that ids are like "c:@N@Urho3D@S@Texture". I probably should not go around trying to guess them manually myself..

Attribute list incorrect with declarators

Thanks for implementing attributes! I was initially the guy requesting them on your blog, so I am super happy! (the readme still says no attributes, so that is why it took me sometime to start testing)

  • cppast version: latest
  • parser: libclang_parser
  • clang version: 5.0

Input:

struct [[reflect]] my_struct{
  [[property1]] int foo;
} [[property2]] bar;

Input flags: -std=c++1z

For this struct, my_struct will have 1 attribute (correct), foo will have 1 attribute (correct) and bar will have 3 attributes [reflect, property1, property2], which I think is incorrect, it should only have 1 attribute (property2). Of course this is easily worked around by moving the declarator.

A possibly separate issue is that attributes after declarators are ignored.

Dependent types are always unexposed

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

The type cpp_depedent_type will never be created, instead a cpp_unexposed_type.

Visual Studio Support

I'm guessing this does not support windows or visual studio, because it depends on clang, but I was wondering if there was a chance, or similar tool that does support windows/visual studio. Thanks!

`extern` template are treated as class template specializations

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

An extern template will be treated as a (full) class template specialization.

Input:

template <typename T>
struct foo {};

template <>
extern struct foo<int>;

Output:

AST for 'file.cpp':
|-foo (class template) [definition]: `template<typename T> struct foo;`
+-foo (class template specialization): `template<> struct foo<int>;`

Use of preprocessor values in enum results in "no tokens available" error

  • cppast version: latest
  • clang version: 5.0.1

One enum i have is using macros from external library:

enum MouseButton
{
    MOUSEB_NONE,
    MOUSEB_LEFT = SDL_BUTTON_LMASK,
    MOUSEB_MIDDLE = SDL_BUTTON_MMASK,
    MOUSEB_RIGHT = SDL_BUTTON_RMASK,
    MOUSEB_X1 = SDL_BUTTON_X1MASK,
    MOUSEB_X2 = SDL_BUTTON_X2MASK,
    MOUSEB_ANY = ~0
};

Header includes SDL/SDL_mouse.h where these macros are defined. Parsing fails "no tokens available" for enum elements that are using preprocessor macros as values. Actual InputEvents.h.

Input flags: -fPIC -msse -msse2 -Wno-invalid-offsetof -std=gnu++11

~/src/games/Projects/Urho3D/Source % /home/rk/src/open/cppast/build/tool/cppast -I ThirdParty/SDL/include -I ThirdParty/SDL/include/SDL -I . -I /tmp/Urho3D-debug/Source/ThirdParty/SDL/include/SDL/generated/ Urho3D/Input/InputEvents.h
[libclang parser] [error] Urho3D/Input/InputEvents.h:251: no tokens available
[libclang parser] [error] Urho3D/Input/InputEvents.h:252: no tokens available
[libclang parser] [error] Urho3D/Input/InputEvents.h:253: no tokens available
[libclang parser] [error] Urho3D/Input/InputEvents.h:254: no tokens available
[libclang parser] [error] Urho3D/Input/InputEvents.h:255: no tokens available
AST for 'Urho3D/Input/InputEvents.h':
|-../Core/Object.h (include directive): `#include "../Core/Object.h"`
|-SDL/SDL_joystick.h (include directive): `#include <SDL/SDL_joystick.h>`
|-SDL/SDL_gamecontroller.h (include directive): `#include <SDL/SDL_gamecontroller.h>`
|-SDL/SDL_keycode.h (include directive): `#include <SDL/SDL_keycode.h>`
|-SDL/SDL_mouse.h (include directive): `#include <SDL/SDL_mouse.h>`
+-Urho3D (namespace)
  |-E_MOUSEBUTTONDOWN (variable) [definition]: `static Urho3D::StringHash const E_MOUSEBUTTONDOWN;`
  |-MouseButtonDown (namespace)
  | |-P_BUTTON (variable) [definition]: `static Urho3D::StringHash const P_BUTTON;`
  | |-P_BUTTONS (variable) [definition]: `static Urho3D::StringHash const P_BUTTONS;`
  | +-P_QUALIFIERS (variable) [definition]: `static Urho3D::StringHash const P_QUALIFIERS;`
  |-E_MOUSEBUTTONUP (variable) [definition]: `static Urho3D::StringHash const E_MOUSEBUTTONUP;`
  |-MouseButtonUp (namespace)
  | |-P_BUTTON (variable) [definition]: `static Urho3D::StringHash const P_BUTTON;`
  | |-P_BUTTONS (variable) [definition]: `static Urho3D::StringHash const P_BUTTONS;`
  | +-P_QUALIFIERS (variable) [definition]: `static Urho3D::StringHash const P_QUALIFIERS;`
  |-E_MOUSEMOVE (variable) [definition]: `static Urho3D::StringHash const E_MOUSEMOVE;`
  |-MouseMove (namespace)
  | |-P_X (variable) [definition]: `static Urho3D::StringHash const P_X;`
  | |-P_Y (variable) [definition]: `static Urho3D::StringHash const P_Y;`
  | |-P_DX (variable) [definition]: `static Urho3D::StringHash const P_DX;`
  | |-P_DY (variable) [definition]: `static Urho3D::StringHash const P_DY;`
  | |-P_BUTTONS (variable) [definition]: `static Urho3D::StringHash const P_BUTTONS;`
  | +-P_QUALIFIERS (variable) [definition]: `static Urho3D::StringHash const P_QUALIFIERS;`
  |-E_MOUSEWHEEL (variable) [definition]: `static Urho3D::StringHash const E_MOUSEWHEEL;`
  |-MouseWheel (namespace)
  | |-P_WHEEL (variable) [definition]: `static Urho3D::StringHash const P_WHEEL;`
  | |-P_BUTTONS (variable) [definition]: `static Urho3D::StringHash const P_BUTTONS;`
  | +-P_QUALIFIERS (variable) [definition]: `static Urho3D::StringHash const P_QUALIFIERS;`
  |-E_KEYDOWN (variable) [definition]: `static Urho3D::StringHash const E_KEYDOWN;`
  |-KeyDown (namespace)
  | |-P_KEY (variable) [definition]: `static Urho3D::StringHash const P_KEY;`
  | |-P_SCANCODE (variable) [definition]: `static Urho3D::StringHash const P_SCANCODE;`
  | |-P_BUTTONS (variable) [definition]: `static Urho3D::StringHash const P_BUTTONS;`
  | |-P_QUALIFIERS (variable) [definition]: `static Urho3D::StringHash const P_QUALIFIERS;`
  | +-P_REPEAT (variable) [definition]: `static Urho3D::StringHash const P_REPEAT;`
  |-E_KEYUP (variable) [definition]: `static Urho3D::StringHash const E_KEYUP;`
  |-KeyUp (namespace)
  | |-P_KEY (variable) [definition]: `static Urho3D::StringHash const P_KEY;`
  | |-P_SCANCODE (variable) [definition]: `static Urho3D::StringHash const P_SCANCODE;`
  | |-P_BUTTONS (variable) [definition]: `static Urho3D::StringHash const P_BUTTONS;`
  | +-P_QUALIFIERS (variable) [definition]: `static Urho3D::StringHash const P_QUALIFIERS;`
  |-E_TEXTINPUT (variable) [definition]: `static Urho3D::StringHash const E_TEXTINPUT;`
  |-TextInput (namespace)
  | +-P_TEXT (variable) [definition]: `static Urho3D::StringHash const P_TEXT;`
  |-E_TEXTEDITING (variable) [definition]: `static Urho3D::StringHash const E_TEXTEDITING;`
  |-TextEditing (namespace)
  | |-P_COMPOSITION (variable) [definition]: `static Urho3D::StringHash const P_COMPOSITION;`
  | |-P_CURSOR (variable) [definition]: `static Urho3D::StringHash const P_CURSOR;`
  | +-P_SELECTION_LENGTH (variable) [definition]: `static Urho3D::StringHash const P_SELECTION_LENGTH;`
  |-E_JOYSTICKCONNECTED (variable) [definition]: `static Urho3D::StringHash const E_JOYSTICKCONNECTED;`
  |-JoystickConnected (namespace)
  | +-P_JOYSTICKID (variable) [definition]: `static Urho3D::StringHash const P_JOYSTICKID;`
  |-E_JOYSTICKDISCONNECTED (variable) [definition]: `static Urho3D::StringHash const E_JOYSTICKDISCONNECTED;`
  |-JoystickDisconnected (namespace)
  | +-P_JOYSTICKID (variable) [definition]: `static Urho3D::StringHash const P_JOYSTICKID;`
  |-E_JOYSTICKBUTTONDOWN (variable) [definition]: `static Urho3D::StringHash const E_JOYSTICKBUTTONDOWN;`
  |-JoystickButtonDown (namespace)
  | |-P_JOYSTICKID (variable) [definition]: `static Urho3D::StringHash const P_JOYSTICKID;`
  | +-P_BUTTON (variable) [definition]: `static Urho3D::StringHash const P_BUTTON;`
  |-E_JOYSTICKBUTTONUP (variable) [definition]: `static Urho3D::StringHash const E_JOYSTICKBUTTONUP;`
  |-JoystickButtonUp (namespace)
  | |-P_JOYSTICKID (variable) [definition]: `static Urho3D::StringHash const P_JOYSTICKID;`
  | +-P_BUTTON (variable) [definition]: `static Urho3D::StringHash const P_BUTTON;`
  |-E_JOYSTICKAXISMOVE (variable) [definition]: `static Urho3D::StringHash const E_JOYSTICKAXISMOVE;`
  |-JoystickAxisMove (namespace)
  | |-P_JOYSTICKID (variable) [definition]: `static Urho3D::StringHash const P_JOYSTICKID;`
  | |-P_AXIS (variable) [definition]: `static Urho3D::StringHash const P_AXIS;`
  | +-P_POSITION (variable) [definition]: `static Urho3D::StringHash const P_POSITION;`
  |-E_JOYSTICKHATMOVE (variable) [definition]: `static Urho3D::StringHash const E_JOYSTICKHATMOVE;`
  |-JoystickHatMove (namespace)
  | |-P_JOYSTICKID (variable) [definition]: `static Urho3D::StringHash const P_JOYSTICKID;`
  | |-P_HAT (variable) [definition]: `static Urho3D::StringHash const P_HAT;`
  | +-P_POSITION (variable) [definition]: `static Urho3D::StringHash const P_POSITION;`
  |-E_TOUCHBEGIN (variable) [definition]: `static Urho3D::StringHash const E_TOUCHBEGIN;`
  |-TouchBegin (namespace)
  | |-P_TOUCHID (variable) [definition]: `static Urho3D::StringHash const P_TOUCHID;`
  | |-P_X (variable) [definition]: `static Urho3D::StringHash const P_X;`
  | |-P_Y (variable) [definition]: `static Urho3D::StringHash const P_Y;`
  | +-P_PRESSURE (variable) [definition]: `static Urho3D::StringHash const P_PRESSURE;`
  |-E_TOUCHEND (variable) [definition]: `static Urho3D::StringHash const E_TOUCHEND;`
  |-TouchEnd (namespace)
  | |-P_TOUCHID (variable) [definition]: `static Urho3D::StringHash const P_TOUCHID;`
  | |-P_X (variable) [definition]: `static Urho3D::StringHash const P_X;`
  | +-P_Y (variable) [definition]: `static Urho3D::StringHash const P_Y;`
  |-E_TOUCHMOVE (variable) [definition]: `static Urho3D::StringHash const E_TOUCHMOVE;`
  |-TouchMove (namespace)
  | |-P_TOUCHID (variable) [definition]: `static Urho3D::StringHash const P_TOUCHID;`
  | |-P_X (variable) [definition]: `static Urho3D::StringHash const P_X;`
  | |-P_Y (variable) [definition]: `static Urho3D::StringHash const P_Y;`
  | |-P_DX (variable) [definition]: `static Urho3D::StringHash const P_DX;`
  | |-P_DY (variable) [definition]: `static Urho3D::StringHash const P_DY;`
  | +-P_PRESSURE (variable) [definition]: `static Urho3D::StringHash const P_PRESSURE;`
  |-E_GESTURERECORDED (variable) [definition]: `static Urho3D::StringHash const E_GESTURERECORDED;`
  |-GestureRecorded (namespace)
  | +-P_GESTUREID (variable) [definition]: `static Urho3D::StringHash const P_GESTUREID;`
  |-E_GESTUREINPUT (variable) [definition]: `static Urho3D::StringHash const E_GESTUREINPUT;`
  |-GestureInput (namespace)
  | |-P_GESTUREID (variable) [definition]: `static Urho3D::StringHash const P_GESTUREID;`
  | |-P_CENTERX (variable) [definition]: `static Urho3D::StringHash const P_CENTERX;`
  | |-P_CENTERY (variable) [definition]: `static Urho3D::StringHash const P_CENTERY;`
  | |-P_NUMFINGERS (variable) [definition]: `static Urho3D::StringHash const P_NUMFINGERS;`
  | +-P_ERROR (variable) [definition]: `static Urho3D::StringHash const P_ERROR;`
  |-E_MULTIGESTURE (variable) [definition]: `static Urho3D::StringHash const E_MULTIGESTURE;`
  |-MultiGesture (namespace)
  | |-P_CENTERX (variable) [definition]: `static Urho3D::StringHash const P_CENTERX;`
  | |-P_CENTERY (variable) [definition]: `static Urho3D::StringHash const P_CENTERY;`
  | |-P_NUMFINGERS (variable) [definition]: `static Urho3D::StringHash const P_NUMFINGERS;`
  | |-P_DTHETA (variable) [definition]: `static Urho3D::StringHash const P_DTHETA;`
  | +-P_DDIST (variable) [definition]: `static Urho3D::StringHash const P_DDIST;`
  |-E_DROPFILE (variable) [definition]: `static Urho3D::StringHash const E_DROPFILE;`
  |-DropFile (namespace)
  | +-P_FILENAME (variable) [definition]: `static Urho3D::StringHash const P_FILENAME;`
  |-E_INPUTFOCUS (variable) [definition]: `static Urho3D::StringHash const E_INPUTFOCUS;`
  |-InputFocus (namespace)
  | |-P_FOCUS (variable) [definition]: `static Urho3D::StringHash const P_FOCUS;`
  | +-P_MINIMIZED (variable) [definition]: `static Urho3D::StringHash const P_MINIMIZED;`
  |-E_MOUSEVISIBLECHANGED (variable) [definition]: `static Urho3D::StringHash const E_MOUSEVISIBLECHANGED;`
  |-MouseVisibleChanged (namespace)
  | +-P_VISIBLE (variable) [definition]: `static Urho3D::StringHash const P_VISIBLE;`
  |-E_MOUSEMODECHANGED (variable) [definition]: `static Urho3D::StringHash const E_MOUSEMODECHANGED;`
  |-MouseModeChanged (namespace)
  | |-P_MODE (variable) [definition]: `static Urho3D::StringHash const P_MODE;`
  | +-P_MOUSELOCKED (variable) [definition]: `static Urho3D::StringHash const P_MOUSELOCKED;`
  |-E_EXITREQUESTED (variable) [definition]: `static Urho3D::StringHash const E_EXITREQUESTED;`
  |-ExitRequested (namespace)
  |-E_SDLRAWINPUT (variable) [definition]: `static Urho3D::StringHash const E_SDLRAWINPUT;`
  |-SDLRawInput (namespace)
  | |-P_SDLEVENT (variable) [definition]: `static Urho3D::StringHash const P_SDLEVENT;`
  | +-P_CONSUMED (variable) [definition]: `static Urho3D::StringHash const P_CONSUMED;`
  |-E_INPUTBEGIN (variable) [definition]: `static Urho3D::StringHash const E_INPUTBEGIN;`
  |-InputBegin (namespace)
  |-E_INPUTEND (variable) [definition]: `static Urho3D::StringHash const E_INPUTEND;`
  |-InputEnd (namespace)
  |-MouseButton (enum) [definition]: `enum MouseButton;`
  | |-MOUSEB_NONE (enum value): `MOUSEB_NONE`
  | +-MOUSEB_ANY (enum value): `MOUSEB_ANY=~0`
  |-QUAL_SHIFT (variable) [definition]: `static int const QUAL_SHIFT=1;`
  |-QUAL_CTRL (variable) [definition]: `static int const QUAL_CTRL=2;`
  |-QUAL_ALT (variable) [definition]: `static int const QUAL_ALT=4;`
  |-QUAL_ANY (variable) [definition]: `static int const QUAL_ANY=8;`
  |-KEY_UNKNOWN (variable) [definition]: `static int const KEY_UNKNOWN=SDLK_UNKNOWN;`
  |-KEY_A (variable) [definition]: `static int const KEY_A=SDLK_a;`
  |-KEY_B (variable) [definition]: `static int const KEY_B=SDLK_b;`
  |-KEY_C (variable) [definition]: `static int const KEY_C=SDLK_c;`
  |-KEY_D (variable) [definition]: `static int const KEY_D=SDLK_d;`
  |-KEY_E (variable) [definition]: `static int const KEY_E=SDLK_e;`
  |-KEY_F (variable) [definition]: `static int const KEY_F=SDLK_f;`
  |-KEY_G (variable) [definition]: `static int const KEY_G=SDLK_g;`
  |-KEY_H (variable) [definition]: `static int const KEY_H=SDLK_h;`
  |-KEY_I (variable) [definition]: `static int const KEY_I=SDLK_i;`
  |-KEY_J (variable) [definition]: `static int const KEY_J=SDLK_j;`
  |-KEY_K (variable) [definition]: `static int const KEY_K=SDLK_k;`
  |-KEY_L (variable) [definition]: `static int const KEY_L=SDLK_l;`
  |-KEY_M (variable) [definition]: `static int const KEY_M=SDLK_m;`
  |-KEY_N (variable) [definition]: `static int const KEY_N=SDLK_n;`
  |-KEY_O (variable) [definition]: `static int const KEY_O=SDLK_o;`
  |-KEY_P (variable) [definition]: `static int const KEY_P=SDLK_p;`
  |-KEY_Q (variable) [definition]: `static int const KEY_Q=SDLK_q;`
  |-KEY_R (variable) [definition]: `static int const KEY_R=SDLK_r;`
  |-KEY_S (variable) [definition]: `static int const KEY_S=SDLK_s;`
  |-KEY_T (variable) [definition]: `static int const KEY_T=SDLK_t;`
  |-KEY_U (variable) [definition]: `static int const KEY_U=SDLK_u;`
  |-KEY_V (variable) [definition]: `static int const KEY_V=SDLK_v;`
  |-KEY_W (variable) [definition]: `static int const KEY_W=SDLK_w;`
  |-KEY_X (variable) [definition]: `static int const KEY_X=SDLK_x;`
  |-KEY_Y (variable) [definition]: `static int const KEY_Y=SDLK_y;`
  |-KEY_Z (variable) [definition]: `static int const KEY_Z=SDLK_z;`
  |-KEY_0 (variable) [definition]: `static int const KEY_0=SDLK_0;`
  |-KEY_1 (variable) [definition]: `static int const KEY_1=SDLK_1;`
  |-KEY_2 (variable) [definition]: `static int const KEY_2=SDLK_2;`
  |-KEY_3 (variable) [definition]: `static int const KEY_3=SDLK_3;`
  |-KEY_4 (variable) [definition]: `static int const KEY_4=SDLK_4;`
  |-KEY_5 (variable) [definition]: `static int const KEY_5=SDLK_5;`
  |-KEY_6 (variable) [definition]: `static int const KEY_6=SDLK_6;`
  |-KEY_7 (variable) [definition]: `static int const KEY_7=SDLK_7;`
  |-KEY_8 (variable) [definition]: `static int const KEY_8=SDLK_8;`
  |-KEY_9 (variable) [definition]: `static int const KEY_9=SDLK_9;`
  |-KEY_BACKSPACE (variable) [definition]: `static int const KEY_BACKSPACE=SDLK_BACKSPACE;`
  |-KEY_TAB (variable) [definition]: `static int const KEY_TAB=SDLK_TAB;`
  |-KEY_RETURN (variable) [definition]: `static int const KEY_RETURN=SDLK_RETURN;`
  |-KEY_RETURN2 (variable) [definition]: `static int const KEY_RETURN2=SDLK_RETURN2;`
  |-KEY_KP_ENTER (variable) [definition]: `static int const KEY_KP_ENTER=SDLK_KP_ENTER;`
  |-KEY_SHIFT (variable) [definition]: `static int const KEY_SHIFT=SDLK_LSHIFT;`
  |-KEY_CTRL (variable) [definition]: `static int const KEY_CTRL=SDLK_LCTRL;`
  |-KEY_ALT (variable) [definition]: `static int const KEY_ALT=SDLK_LALT;`
  |-KEY_GUI (variable) [definition]: `static int const KEY_GUI=SDLK_LGUI;`
  |-KEY_PAUSE (variable) [definition]: `static int const KEY_PAUSE=SDLK_PAUSE;`
  |-KEY_CAPSLOCK (variable) [definition]: `static int const KEY_CAPSLOCK=SDLK_CAPSLOCK;`
  |-KEY_ESCAPE (variable) [definition]: `static int const KEY_ESCAPE=SDLK_ESCAPE;`
  |-KEY_SPACE (variable) [definition]: `static int const KEY_SPACE=SDLK_SPACE;`
  |-KEY_PAGEUP (variable) [definition]: `static int const KEY_PAGEUP=SDLK_PAGEUP;`
  |-KEY_PAGEDOWN (variable) [definition]: `static int const KEY_PAGEDOWN=SDLK_PAGEDOWN;`
  |-KEY_END (variable) [definition]: `static int const KEY_END=SDLK_END;`
  |-KEY_HOME (variable) [definition]: `static int const KEY_HOME=SDLK_HOME;`
  |-KEY_LEFT (variable) [definition]: `static int const KEY_LEFT=SDLK_LEFT;`
  |-KEY_UP (variable) [definition]: `static int const KEY_UP=SDLK_UP;`
  |-KEY_RIGHT (variable) [definition]: `static int const KEY_RIGHT=SDLK_RIGHT;`
  |-KEY_DOWN (variable) [definition]: `static int const KEY_DOWN=SDLK_DOWN;`
  |-KEY_SELECT (variable) [definition]: `static int const KEY_SELECT=SDLK_SELECT;`
  |-KEY_PRINTSCREEN (variable) [definition]: `static int const KEY_PRINTSCREEN=SDLK_PRINTSCREEN;`
  |-KEY_INSERT (variable) [definition]: `static int const KEY_INSERT=SDLK_INSERT;`
  |-KEY_DELETE (variable) [definition]: `static int const KEY_DELETE=SDLK_DELETE;`
  |-KEY_LGUI (variable) [definition]: `static int const KEY_LGUI=SDLK_LGUI;`
  |-KEY_RGUI (variable) [definition]: `static int const KEY_RGUI=SDLK_RGUI;`
  |-KEY_APPLICATION (variable) [definition]: `static int const KEY_APPLICATION=SDLK_APPLICATION;`
  |-KEY_KP_0 (variable) [definition]: `static int const KEY_KP_0=SDLK_KP_0;`
  |-KEY_KP_1 (variable) [definition]: `static int const KEY_KP_1=SDLK_KP_1;`
  |-KEY_KP_2 (variable) [definition]: `static int const KEY_KP_2=SDLK_KP_2;`
  |-KEY_KP_3 (variable) [definition]: `static int const KEY_KP_3=SDLK_KP_3;`
  |-KEY_KP_4 (variable) [definition]: `static int const KEY_KP_4=SDLK_KP_4;`
  |-KEY_KP_5 (variable) [definition]: `static int const KEY_KP_5=SDLK_KP_5;`
  |-KEY_KP_6 (variable) [definition]: `static int const KEY_KP_6=SDLK_KP_6;`
  |-KEY_KP_7 (variable) [definition]: `static int const KEY_KP_7=SDLK_KP_7;`
  |-KEY_KP_8 (variable) [definition]: `static int const KEY_KP_8=SDLK_KP_8;`
  |-KEY_KP_9 (variable) [definition]: `static int const KEY_KP_9=SDLK_KP_9;`
  |-KEY_KP_MULTIPLY (variable) [definition]: `static int const KEY_KP_MULTIPLY=SDLK_KP_MULTIPLY;`
  |-KEY_KP_PLUS (variable) [definition]: `static int const KEY_KP_PLUS=SDLK_KP_PLUS;`
  |-KEY_KP_MINUS (variable) [definition]: `static int const KEY_KP_MINUS=SDLK_KP_MINUS;`
  |-KEY_KP_PERIOD (variable) [definition]: `static int const KEY_KP_PERIOD=SDLK_KP_PERIOD;`
  |-KEY_KP_DIVIDE (variable) [definition]: `static int const KEY_KP_DIVIDE=SDLK_KP_DIVIDE;`
  |-KEY_F1 (variable) [definition]: `static int const KEY_F1=SDLK_F1;`
  |-KEY_F2 (variable) [definition]: `static int const KEY_F2=SDLK_F2;`
  |-KEY_F3 (variable) [definition]: `static int const KEY_F3=SDLK_F3;`
  |-KEY_F4 (variable) [definition]: `static int const KEY_F4=SDLK_F4;`
  |-KEY_F5 (variable) [definition]: `static int const KEY_F5=SDLK_F5;`
  |-KEY_F6 (variable) [definition]: `static int const KEY_F6=SDLK_F6;`
  |-KEY_F7 (variable) [definition]: `static int const KEY_F7=SDLK_F7;`
  |-KEY_F8 (variable) [definition]: `static int const KEY_F8=SDLK_F8;`
  |-KEY_F9 (variable) [definition]: `static int const KEY_F9=SDLK_F9;`
  |-KEY_F10 (variable) [definition]: `static int const KEY_F10=SDLK_F10;`
  |-KEY_F11 (variable) [definition]: `static int const KEY_F11=SDLK_F11;`
  |-KEY_F12 (variable) [definition]: `static int const KEY_F12=SDLK_F12;`
  |-KEY_F13 (variable) [definition]: `static int const KEY_F13=SDLK_F13;`
  |-KEY_F14 (variable) [definition]: `static int const KEY_F14=SDLK_F14;`
  |-KEY_F15 (variable) [definition]: `static int const KEY_F15=SDLK_F15;`
  |-KEY_F16 (variable) [definition]: `static int const KEY_F16=SDLK_F16;`
  |-KEY_F17 (variable) [definition]: `static int const KEY_F17=SDLK_F17;`
  |-KEY_F18 (variable) [definition]: `static int const KEY_F18=SDLK_F18;`
  |-KEY_F19 (variable) [definition]: `static int const KEY_F19=SDLK_F19;`
  |-KEY_F20 (variable) [definition]: `static int const KEY_F20=SDLK_F20;`
  |-KEY_F21 (variable) [definition]: `static int const KEY_F21=SDLK_F21;`
  |-KEY_F22 (variable) [definition]: `static int const KEY_F22=SDLK_F22;`
  |-KEY_F23 (variable) [definition]: `static int const KEY_F23=SDLK_F23;`
  |-KEY_F24 (variable) [definition]: `static int const KEY_F24=SDLK_F24;`
  |-KEY_NUMLOCKCLEAR (variable) [definition]: `static int const KEY_NUMLOCKCLEAR=SDLK_NUMLOCKCLEAR;`
  |-KEY_SCROLLLOCK (variable) [definition]: `static int const KEY_SCROLLLOCK=SDLK_SCROLLLOCK;`
  |-KEY_LSHIFT (variable) [definition]: `static int const KEY_LSHIFT=SDLK_LSHIFT;`
  |-KEY_RSHIFT (variable) [definition]: `static int const KEY_RSHIFT=SDLK_RSHIFT;`
  |-KEY_LCTRL (variable) [definition]: `static int const KEY_LCTRL=SDLK_LCTRL;`
  |-KEY_RCTRL (variable) [definition]: `static int const KEY_RCTRL=SDLK_RCTRL;`
  |-KEY_LALT (variable) [definition]: `static int const KEY_LALT=SDLK_LALT;`
  |-KEY_RALT (variable) [definition]: `static int const KEY_RALT=SDLK_RALT;`
  |-KEY_AC_BACK (variable) [definition]: `static int const KEY_AC_BACK=SDLK_AC_BACK;`
  |-KEY_AC_BOOKMARKS (variable) [definition]: `static int const KEY_AC_BOOKMARKS=SDLK_AC_BOOKMARKS;`
  |-KEY_AC_FORWARD (variable) [definition]: `static int const KEY_AC_FORWARD=SDLK_AC_FORWARD;`
  |-KEY_AC_HOME (variable) [definition]: `static int const KEY_AC_HOME=SDLK_AC_HOME;`
  |-KEY_AC_REFRESH (variable) [definition]: `static int const KEY_AC_REFRESH=SDLK_AC_REFRESH;`
  |-KEY_AC_SEARCH (variable) [definition]: `static int const KEY_AC_SEARCH=SDLK_AC_SEARCH;`
  |-KEY_AC_STOP (variable) [definition]: `static int const KEY_AC_STOP=SDLK_AC_STOP;`
  |-KEY_AGAIN (variable) [definition]: `static int const KEY_AGAIN=SDLK_AGAIN;`
  |-KEY_ALTERASE (variable) [definition]: `static int const KEY_ALTERASE=SDLK_ALTERASE;`
  |-KEY_AMPERSAND (variable) [definition]: `static int const KEY_AMPERSAND=SDLK_AMPERSAND;`
  |-KEY_ASTERISK (variable) [definition]: `static int const KEY_ASTERISK=SDLK_ASTERISK;`
  |-KEY_AT (variable) [definition]: `static int const KEY_AT=SDLK_AT;`
  |-KEY_AUDIOMUTE (variable) [definition]: `static int const KEY_AUDIOMUTE=SDLK_AUDIOMUTE;`
  |-KEY_AUDIONEXT (variable) [definition]: `static int const KEY_AUDIONEXT=SDLK_AUDIONEXT;`
  |-KEY_AUDIOPLAY (variable) [definition]: `static int const KEY_AUDIOPLAY=SDLK_AUDIOPLAY;`
  |-KEY_AUDIOPREV (variable) [definition]: `static int const KEY_AUDIOPREV=SDLK_AUDIOPREV;`
  |-KEY_AUDIOSTOP (variable) [definition]: `static int const KEY_AUDIOSTOP=SDLK_AUDIOSTOP;`
  |-KEY_BACKQUOTE (variable) [definition]: `static int const KEY_BACKQUOTE=SDLK_BACKQUOTE;`
  |-KEY_BACKSLASH (variable) [definition]: `static int const KEY_BACKSLASH=SDLK_BACKSLASH;`
  |-KEY_BRIGHTNESSDOWN (variable) [definition]: `static int const KEY_BRIGHTNESSDOWN=SDLK_BRIGHTNESSDOWN;`
  |-KEY_BRIGHTNESSUP (variable) [definition]: `static int const KEY_BRIGHTNESSUP=SDLK_BRIGHTNESSUP;`
  |-KEY_CALCULATOR (variable) [definition]: `static int const KEY_CALCULATOR=SDLK_CALCULATOR;`
  |-KEY_CANCEL (variable) [definition]: `static int const KEY_CANCEL=SDLK_CANCEL;`
  |-KEY_CARET (variable) [definition]: `static int const KEY_CARET=SDLK_CARET;`
  |-KEY_CLEAR (variable) [definition]: `static int const KEY_CLEAR=SDLK_CLEAR;`
  |-KEY_CLEARAGAIN (variable) [definition]: `static int const KEY_CLEARAGAIN=SDLK_CLEARAGAIN;`
  |-KEY_COLON (variable) [definition]: `static int const KEY_COLON=SDLK_COLON;`
  |-KEY_COMMA (variable) [definition]: `static int const KEY_COMMA=SDLK_COMMA;`
  |-KEY_COMPUTER (variable) [definition]: `static int const KEY_COMPUTER=SDLK_COMPUTER;`
  |-KEY_COPY (variable) [definition]: `static int const KEY_COPY=SDLK_COPY;`
  |-KEY_CRSEL (variable) [definition]: `static int const KEY_CRSEL=SDLK_CRSEL;`
  |-KEY_CURRENCYSUBUNIT (variable) [definition]: `static int const KEY_CURRENCYSUBUNIT=SDLK_CURRENCYSUBUNIT;`
  |-KEY_CURRENCYUNIT (variable) [definition]: `static int const KEY_CURRENCYUNIT=SDLK_CURRENCYUNIT;`
  |-KEY_CUT (variable) [definition]: `static int const KEY_CUT=SDLK_CUT;`
  |-KEY_DECIMALSEPARATOR (variable) [definition]: `static int const KEY_DECIMALSEPARATOR=SDLK_DECIMALSEPARATOR;`
  |-KEY_DISPLAYSWITCH (variable) [definition]: `static int const KEY_DISPLAYSWITCH=SDLK_DISPLAYSWITCH;`
  |-KEY_DOLLAR (variable) [definition]: `static int const KEY_DOLLAR=SDLK_DOLLAR;`
  |-KEY_EJECT (variable) [definition]: `static int const KEY_EJECT=SDLK_EJECT;`
  |-KEY_EQUALS (variable) [definition]: `static int const KEY_EQUALS=SDLK_EQUALS;`
  |-KEY_EXCLAIM (variable) [definition]: `static int const KEY_EXCLAIM=SDLK_EXCLAIM;`
  |-KEY_EXSEL (variable) [definition]: `static int const KEY_EXSEL=SDLK_EXSEL;`
  |-KEY_FIND (variable) [definition]: `static int const KEY_FIND=SDLK_FIND;`
  |-KEY_GREATER (variable) [definition]: `static int const KEY_GREATER=SDLK_GREATER;`
  |-KEY_HASH (variable) [definition]: `static int const KEY_HASH=SDLK_HASH;`
  |-KEY_HELP (variable) [definition]: `static int const KEY_HELP=SDLK_HELP;`
  |-KEY_KBDILLUMDOWN (variable) [definition]: `static int const KEY_KBDILLUMDOWN=SDLK_KBDILLUMDOWN;`
  |-KEY_KBDILLUMTOGGLE (variable) [definition]: `static int const KEY_KBDILLUMTOGGLE=SDLK_KBDILLUMTOGGLE;`
  |-KEY_KBDILLUMUP (variable) [definition]: `static int const KEY_KBDILLUMUP=SDLK_KBDILLUMUP;`
  |-KEY_KP_00 (variable) [definition]: `static int const KEY_KP_00=SDLK_KP_00;`
  |-KEY_KP_000 (variable) [definition]: `static int const KEY_KP_000=SDLK_KP_000;`
  |-KEY_KP_A (variable) [definition]: `static int const KEY_KP_A=SDLK_KP_A;`
  |-KEY_KP_AMPERSAND (variable) [definition]: `static int const KEY_KP_AMPERSAND=SDLK_KP_AMPERSAND;`
  |-KEY_KP_AT (variable) [definition]: `static int const KEY_KP_AT=SDLK_KP_AT;`
  |-KEY_KP_B (variable) [definition]: `static int const KEY_KP_B=SDLK_KP_B;`
  |-KEY_KP_BACKSPACE (variable) [definition]: `static int const KEY_KP_BACKSPACE=SDLK_KP_BACKSPACE;`
  |-KEY_KP_BINARY (variable) [definition]: `static int const KEY_KP_BINARY=SDLK_KP_BINARY;`
  |-KEY_KP_C (variable) [definition]: `static int const KEY_KP_C=SDLK_KP_C;`
  |-KEY_KP_CLEAR (variable) [definition]: `static int const KEY_KP_CLEAR=SDLK_KP_CLEAR;`
  |-KEY_KP_CLEARENTRY (variable) [definition]: `static int const KEY_KP_CLEARENTRY=SDLK_KP_CLEARENTRY;`
  |-KEY_KP_COLON (variable) [definition]: `static int const KEY_KP_COLON=SDLK_KP_COLON;`
  |-KEY_KP_COMMA (variable) [definition]: `static int const KEY_KP_COMMA=SDLK_KP_COMMA;`
  |-KEY_KP_D (variable) [definition]: `static int const KEY_KP_D=SDLK_KP_D;`
  |-KEY_KP_DBLAMPERSAND (variable) [definition]: `static int const KEY_KP_DBLAMPERSAND=SDLK_KP_DBLAMPERSAND;`
  |-KEY_KP_DBLVERTICALBAR (variable) [definition]: `static int const KEY_KP_DBLVERTICALBAR=SDLK_KP_DBLVERTICALBAR;`
  |-KEY_KP_DECIMAL (variable) [definition]: `static int const KEY_KP_DECIMAL=SDLK_KP_DECIMAL;`
  |-KEY_KP_E (variable) [definition]: `static int const KEY_KP_E=SDLK_KP_E;`
  |-KEY_KP_EQUALS (variable) [definition]: `static int const KEY_KP_EQUALS=SDLK_KP_EQUALS;`
  |-KEY_KP_EQUALSAS400 (variable) [definition]: `static int const KEY_KP_EQUALSAS400=SDLK_KP_EQUALSAS400;`
  |-KEY_KP_EXCLAM (variable) [definition]: `static int const KEY_KP_EXCLAM=SDLK_KP_EXCLAM;`
  |-KEY_KP_F (variable) [definition]: `static int const KEY_KP_F=SDLK_KP_F;`
  |-KEY_KP_GREATER (variable) [definition]: `static int const KEY_KP_GREATER=SDLK_KP_GREATER;`
  |-KEY_KP_HASH (variable) [definition]: `static int const KEY_KP_HASH=SDLK_KP_HASH;`
  |-KEY_KP_HEXADECIMAL (variable) [definition]: `static int const KEY_KP_HEXADECIMAL=SDLK_KP_HEXADECIMAL;`
  |-KEY_KP_LEFTBRACE (variable) [definition]: `static int const KEY_KP_LEFTBRACE=SDLK_KP_LEFTBRACE;`
  |-KEY_KP_LEFTPAREN (variable) [definition]: `static int const KEY_KP_LEFTPAREN=SDLK_KP_LEFTPAREN;`
  |-KEY_KP_LESS (variable) [definition]: `static int const KEY_KP_LESS=SDLK_KP_LESS;`
  |-KEY_KP_MEMADD (variable) [definition]: `static int const KEY_KP_MEMADD=SDLK_KP_MEMADD;`
  |-KEY_KP_MEMCLEAR (variable) [definition]: `static int const KEY_KP_MEMCLEAR=SDLK_KP_MEMCLEAR;`
  |-KEY_KP_MEMDIVIDE (variable) [definition]: `static int const KEY_KP_MEMDIVIDE=SDLK_KP_MEMDIVIDE;`
  |-KEY_KP_MEMMULTIPLY (variable) [definition]: `static int const KEY_KP_MEMMULTIPLY=SDLK_KP_MEMMULTIPLY;`
  |-KEY_KP_MEMRECALL (variable) [definition]: `static int const KEY_KP_MEMRECALL=SDLK_KP_MEMRECALL;`
  |-KEY_KP_MEMSTORE (variable) [definition]: `static int const KEY_KP_MEMSTORE=SDLK_KP_MEMSTORE;`
  |-KEY_KP_MEMSUBTRACT (variable) [definition]: `static int const KEY_KP_MEMSUBTRACT=SDLK_KP_MEMSUBTRACT;`
  |-KEY_KP_OCTAL (variable) [definition]: `static int const KEY_KP_OCTAL=SDLK_KP_OCTAL;`
  |-KEY_KP_PERCENT (variable) [definition]: `static int const KEY_KP_PERCENT=SDLK_KP_PERCENT;`
  |-KEY_KP_PLUSMINUS (variable) [definition]: `static int const KEY_KP_PLUSMINUS=SDLK_KP_PLUSMINUS;`
  |-KEY_KP_POWER (variable) [definition]: `static int const KEY_KP_POWER=SDLK_KP_POWER;`
  |-KEY_KP_RIGHTBRACE (variable) [definition]: `static int const KEY_KP_RIGHTBRACE=SDLK_KP_RIGHTBRACE;`
  |-KEY_KP_RIGHTPAREN (variable) [definition]: `static int const KEY_KP_RIGHTPAREN=SDLK_KP_RIGHTPAREN;`
  |-KEY_KP_SPACE (variable) [definition]: `static int const KEY_KP_SPACE=SDLK_KP_SPACE;`
  |-KEY_KP_TAB (variable) [definition]: `static int const KEY_KP_TAB=SDLK_KP_TAB;`
  |-KEY_KP_VERTICALBAR (variable) [definition]: `static int const KEY_KP_VERTICALBAR=SDLK_KP_VERTICALBAR;`
  |-KEY_KP_XOR (variable) [definition]: `static int const KEY_KP_XOR=SDLK_KP_XOR;`
  |-KEY_LEFTBRACKET (variable) [definition]: `static int const KEY_LEFTBRACKET=SDLK_LEFTBRACKET;`
  |-KEY_LEFTPAREN (variable) [definition]: `static int const KEY_LEFTPAREN=SDLK_LEFTPAREN;`
  |-KEY_LESS (variable) [definition]: `static int const KEY_LESS=SDLK_LESS;`
  |-KEY_MAIL (variable) [definition]: `static int const KEY_MAIL=SDLK_MAIL;`
  |-KEY_MEDIASELECT (variable) [definition]: `static int const KEY_MEDIASELECT=SDLK_MEDIASELECT;`
  |-KEY_MENU (variable) [definition]: `static int const KEY_MENU=SDLK_MENU;`
  |-KEY_MINUS (variable) [definition]: `static int const KEY_MINUS=SDLK_MINUS;`
  |-KEY_MODE (variable) [definition]: `static int const KEY_MODE=SDLK_MODE;`
  |-KEY_MUTE (variable) [definition]: `static int const KEY_MUTE=SDLK_MUTE;`
  |-KEY_OPER (variable) [definition]: `static int const KEY_OPER=SDLK_OPER;`
  |-KEY_OUT (variable) [definition]: `static int const KEY_OUT=SDLK_OUT;`
  |-KEY_PASTE (variable) [definition]: `static int const KEY_PASTE=SDLK_PASTE;`
  |-KEY_PERCENT (variable) [definition]: `static int const KEY_PERCENT=SDLK_PERCENT;`
  |-KEY_PERIOD (variable) [definition]: `static int const KEY_PERIOD=SDLK_PERIOD;`
  |-KEY_PLUS (variable) [definition]: `static int const KEY_PLUS=SDLK_PLUS;`
  |-KEY_POWER (variable) [definition]: `static int const KEY_POWER=SDLK_POWER;`
  |-KEY_PRIOR (variable) [definition]: `static int const KEY_PRIOR=SDLK_PRIOR;`
  |-KEY_QUESTION (variable) [definition]: `static int const KEY_QUESTION=SDLK_QUESTION;`
  |-KEY_QUOTE (variable) [definition]: `static int const KEY_QUOTE=SDLK_QUOTE;`
  |-KEY_QUOTEDBL (variable) [definition]: `static int const KEY_QUOTEDBL=SDLK_QUOTEDBL;`
  |-KEY_RIGHTBRACKET (variable) [definition]: `static int const KEY_RIGHTBRACKET=SDLK_RIGHTBRACKET;`
  |-KEY_RIGHTPAREN (variable) [definition]: `static int const KEY_RIGHTPAREN=SDLK_RIGHTPAREN;`
  |-KEY_SEMICOLON (variable) [definition]: `static int const KEY_SEMICOLON=SDLK_SEMICOLON;`
  |-KEY_SEPARATOR (variable) [definition]: `static int const KEY_SEPARATOR=SDLK_SEPARATOR;`
  |-KEY_SLASH (variable) [definition]: `static int const KEY_SLASH=SDLK_SLASH;`
  |-KEY_SLEEP (variable) [definition]: `static int const KEY_SLEEP=SDLK_SLEEP;`
  |-KEY_STOP (variable) [definition]: `static int const KEY_STOP=SDLK_STOP;`
  |-KEY_SYSREQ (variable) [definition]: `static int const KEY_SYSREQ=SDLK_SYSREQ;`
  |-KEY_THOUSANDSSEPARATOR (variable) [definition]: `static int const KEY_THOUSANDSSEPARATOR=SDLK_THOUSANDSSEPARATOR;`
  |-KEY_UNDERSCORE (variable) [definition]: `static int const KEY_UNDERSCORE=SDLK_UNDERSCORE;`
  |-KEY_UNDO (variable) [definition]: `static int const KEY_UNDO=SDLK_UNDO;`
  |-KEY_VOLUMEDOWN (variable) [definition]: `static int const KEY_VOLUMEDOWN=SDLK_VOLUMEDOWN;`
  |-KEY_VOLUMEUP (variable) [definition]: `static int const KEY_VOLUMEUP=SDLK_VOLUMEUP;`
  |-KEY_WWW (variable) [definition]: `static int const KEY_WWW=SDLK_WWW;`
  |-SCANCODE_UNKNOWN (variable) [definition]: `static int const SCANCODE_UNKNOWN=SDL_SCANCODE_UNKNOWN;`
  |-SCANCODE_CTRL (variable) [definition]: `static int const SCANCODE_CTRL=SDL_SCANCODE_LCTRL;`
  |-SCANCODE_SHIFT (variable) [definition]: `static int const SCANCODE_SHIFT=SDL_SCANCODE_LSHIFT;`
  |-SCANCODE_ALT (variable) [definition]: `static int const SCANCODE_ALT=SDL_SCANCODE_LALT;`
  |-SCANCODE_GUI (variable) [definition]: `static int const SCANCODE_GUI=SDL_SCANCODE_LGUI;`
  |-SCANCODE_A (variable) [definition]: `static int const SCANCODE_A=SDL_SCANCODE_A;`
  |-SCANCODE_B (variable) [definition]: `static int const SCANCODE_B=SDL_SCANCODE_B;`
  |-SCANCODE_C (variable) [definition]: `static int const SCANCODE_C=SDL_SCANCODE_C;`
  |-SCANCODE_D (variable) [definition]: `static int const SCANCODE_D=SDL_SCANCODE_D;`
  |-SCANCODE_E (variable) [definition]: `static int const SCANCODE_E=SDL_SCANCODE_E;`
  |-SCANCODE_F (variable) [definition]: `static int const SCANCODE_F=SDL_SCANCODE_F;`
  |-SCANCODE_G (variable) [definition]: `static int const SCANCODE_G=SDL_SCANCODE_G;`
  |-SCANCODE_H (variable) [definition]: `static int const SCANCODE_H=SDL_SCANCODE_H;`
  |-SCANCODE_I (variable) [definition]: `static int const SCANCODE_I=SDL_SCANCODE_I;`
  |-SCANCODE_J (variable) [definition]: `static int const SCANCODE_J=SDL_SCANCODE_J;`
  |-SCANCODE_K (variable) [definition]: `static int const SCANCODE_K=SDL_SCANCODE_K;`
  |-SCANCODE_L (variable) [definition]: `static int const SCANCODE_L=SDL_SCANCODE_L;`
  |-SCANCODE_M (variable) [definition]: `static int const SCANCODE_M=SDL_SCANCODE_M;`
  |-SCANCODE_N (variable) [definition]: `static int const SCANCODE_N=SDL_SCANCODE_N;`
  |-SCANCODE_O (variable) [definition]: `static int const SCANCODE_O=SDL_SCANCODE_O;`
  |-SCANCODE_P (variable) [definition]: `static int const SCANCODE_P=SDL_SCANCODE_P;`
  |-SCANCODE_Q (variable) [definition]: `static int const SCANCODE_Q=SDL_SCANCODE_Q;`
  |-SCANCODE_R (variable) [definition]: `static int const SCANCODE_R=SDL_SCANCODE_R;`
  |-SCANCODE_S (variable) [definition]: `static int const SCANCODE_S=SDL_SCANCODE_S;`
  |-SCANCODE_T (variable) [definition]: `static int const SCANCODE_T=SDL_SCANCODE_T;`
  |-SCANCODE_U (variable) [definition]: `static int const SCANCODE_U=SDL_SCANCODE_U;`
  |-SCANCODE_V (variable) [definition]: `static int const SCANCODE_V=SDL_SCANCODE_V;`
  |-SCANCODE_W (variable) [definition]: `static int const SCANCODE_W=SDL_SCANCODE_W;`
  |-SCANCODE_X (variable) [definition]: `static int const SCANCODE_X=SDL_SCANCODE_X;`
  |-SCANCODE_Y (variable) [definition]: `static int const SCANCODE_Y=SDL_SCANCODE_Y;`
  |-SCANCODE_Z (variable) [definition]: `static int const SCANCODE_Z=SDL_SCANCODE_Z;`
  |-SCANCODE_1 (variable) [definition]: `static int const SCANCODE_1=SDL_SCANCODE_1;`
  |-SCANCODE_2 (variable) [definition]: `static int const SCANCODE_2=SDL_SCANCODE_2;`
  |-SCANCODE_3 (variable) [definition]: `static int const SCANCODE_3=SDL_SCANCODE_3;`
  |-SCANCODE_4 (variable) [definition]: `static int const SCANCODE_4=SDL_SCANCODE_4;`
  |-SCANCODE_5 (variable) [definition]: `static int const SCANCODE_5=SDL_SCANCODE_5;`
  |-SCANCODE_6 (variable) [definition]: `static int const SCANCODE_6=SDL_SCANCODE_6;`
  |-SCANCODE_7 (variable) [definition]: `static int const SCANCODE_7=SDL_SCANCODE_7;`
  |-SCANCODE_8 (variable) [definition]: `static int const SCANCODE_8=SDL_SCANCODE_8;`
  |-SCANCODE_9 (variable) [definition]: `static int const SCANCODE_9=SDL_SCANCODE_9;`
  |-SCANCODE_0 (variable) [definition]: `static int const SCANCODE_0=SDL_SCANCODE_0;`
  |-SCANCODE_RETURN (variable) [definition]: `static int const SCANCODE_RETURN=SDL_SCANCODE_RETURN;`
  |-SCANCODE_ESCAPE (variable) [definition]: `static int const SCANCODE_ESCAPE=SDL_SCANCODE_ESCAPE;`
  |-SCANCODE_BACKSPACE (variable) [definition]: `static int const SCANCODE_BACKSPACE=SDL_SCANCODE_BACKSPACE;`
  |-SCANCODE_TAB (variable) [definition]: `static int const SCANCODE_TAB=SDL_SCANCODE_TAB;`
  |-SCANCODE_SPACE (variable) [definition]: `static int const SCANCODE_SPACE=SDL_SCANCODE_SPACE;`
  |-SCANCODE_MINUS (variable) [definition]: `static int const SCANCODE_MINUS=SDL_SCANCODE_MINUS;`
  |-SCANCODE_EQUALS (variable) [definition]: `static int const SCANCODE_EQUALS=SDL_SCANCODE_EQUALS;`
  |-SCANCODE_LEFTBRACKET (variable) [definition]: `static int const SCANCODE_LEFTBRACKET=SDL_SCANCODE_LEFTBRACKET;`
  |-SCANCODE_RIGHTBRACKET (variable) [definition]: `static int const SCANCODE_RIGHTBRACKET=SDL_SCANCODE_RIGHTBRACKET;`
  |-SCANCODE_BACKSLASH (variable) [definition]: `static int const SCANCODE_BACKSLASH=SDL_SCANCODE_BACKSLASH;`
  |-SCANCODE_NONUSHASH (variable) [definition]: `static int const SCANCODE_NONUSHASH=SDL_SCANCODE_NONUSHASH;`
  |-SCANCODE_SEMICOLON (variable) [definition]: `static int const SCANCODE_SEMICOLON=SDL_SCANCODE_SEMICOLON;`
  |-SCANCODE_APOSTROPHE (variable) [definition]: `static int const SCANCODE_APOSTROPHE=SDL_SCANCODE_APOSTROPHE;`
  |-SCANCODE_GRAVE (variable) [definition]: `static int const SCANCODE_GRAVE=SDL_SCANCODE_GRAVE;`
  |-SCANCODE_COMMA (variable) [definition]: `static int const SCANCODE_COMMA=SDL_SCANCODE_COMMA;`
  |-SCANCODE_PERIOD (variable) [definition]: `static int const SCANCODE_PERIOD=SDL_SCANCODE_PERIOD;`
  |-SCANCODE_SLASH (variable) [definition]: `static int const SCANCODE_SLASH=SDL_SCANCODE_SLASH;`
  |-SCANCODE_CAPSLOCK (variable) [definition]: `static int const SCANCODE_CAPSLOCK=SDL_SCANCODE_CAPSLOCK;`
  |-SCANCODE_F1 (variable) [definition]: `static int const SCANCODE_F1=SDL_SCANCODE_F1;`
  |-SCANCODE_F2 (variable) [definition]: `static int const SCANCODE_F2=SDL_SCANCODE_F2;`
  |-SCANCODE_F3 (variable) [definition]: `static int const SCANCODE_F3=SDL_SCANCODE_F3;`
  |-SCANCODE_F4 (variable) [definition]: `static int const SCANCODE_F4=SDL_SCANCODE_F4;`
  |-SCANCODE_F5 (variable) [definition]: `static int const SCANCODE_F5=SDL_SCANCODE_F5;`
  |-SCANCODE_F6 (variable) [definition]: `static int const SCANCODE_F6=SDL_SCANCODE_F6;`
  |-SCANCODE_F7 (variable) [definition]: `static int const SCANCODE_F7=SDL_SCANCODE_F7;`
  |-SCANCODE_F8 (variable) [definition]: `static int const SCANCODE_F8=SDL_SCANCODE_F8;`
  |-SCANCODE_F9 (variable) [definition]: `static int const SCANCODE_F9=SDL_SCANCODE_F9;`
  |-SCANCODE_F10 (variable) [definition]: `static int const SCANCODE_F10=SDL_SCANCODE_F10;`
  |-SCANCODE_F11 (variable) [definition]: `static int const SCANCODE_F11=SDL_SCANCODE_F11;`
  |-SCANCODE_F12 (variable) [definition]: `static int const SCANCODE_F12=SDL_SCANCODE_F12;`
  |-SCANCODE_PRINTSCREEN (variable) [definition]: `static int const SCANCODE_PRINTSCREEN=SDL_SCANCODE_PRINTSCREEN;`
  |-SCANCODE_SCROLLLOCK (variable) [definition]: `static int const SCANCODE_SCROLLLOCK=SDL_SCANCODE_SCROLLLOCK;`
  |-SCANCODE_PAUSE (variable) [definition]: `static int const SCANCODE_PAUSE=SDL_SCANCODE_PAUSE;`
  |-SCANCODE_INSERT (variable) [definition]: `static int const SCANCODE_INSERT=SDL_SCANCODE_INSERT;`
  |-SCANCODE_HOME (variable) [definition]: `static int const SCANCODE_HOME=SDL_SCANCODE_HOME;`
  |-SCANCODE_PAGEUP (variable) [definition]: `static int const SCANCODE_PAGEUP=SDL_SCANCODE_PAGEUP;`
  |-SCANCODE_DELETE (variable) [definition]: `static int const SCANCODE_DELETE=SDL_SCANCODE_DELETE;`
  |-SCANCODE_END (variable) [definition]: `static int const SCANCODE_END=SDL_SCANCODE_END;`
  |-SCANCODE_PAGEDOWN (variable) [definition]: `static int const SCANCODE_PAGEDOWN=SDL_SCANCODE_PAGEDOWN;`
  |-SCANCODE_RIGHT (variable) [definition]: `static int const SCANCODE_RIGHT=SDL_SCANCODE_RIGHT;`
  |-SCANCODE_LEFT (variable) [definition]: `static int const SCANCODE_LEFT=SDL_SCANCODE_LEFT;`
  |-SCANCODE_DOWN (variable) [definition]: `static int const SCANCODE_DOWN=SDL_SCANCODE_DOWN;`
  |-SCANCODE_UP (variable) [definition]: `static int const SCANCODE_UP=SDL_SCANCODE_UP;`
  |-SCANCODE_NUMLOCKCLEAR (variable) [definition]: `static int const SCANCODE_NUMLOCKCLEAR=SDL_SCANCODE_NUMLOCKCLEAR;`
  |-SCANCODE_KP_DIVIDE (variable) [definition]: `static int const SCANCODE_KP_DIVIDE=SDL_SCANCODE_KP_DIVIDE;`
  |-SCANCODE_KP_MULTIPLY (variable) [definition]: `static int const SCANCODE_KP_MULTIPLY=SDL_SCANCODE_KP_MULTIPLY;`
  |-SCANCODE_KP_MINUS (variable) [definition]: `static int const SCANCODE_KP_MINUS=SDL_SCANCODE_KP_MINUS;`
  |-SCANCODE_KP_PLUS (variable) [definition]: `static int const SCANCODE_KP_PLUS=SDL_SCANCODE_KP_PLUS;`
  |-SCANCODE_KP_ENTER (variable) [definition]: `static int const SCANCODE_KP_ENTER=SDL_SCANCODE_KP_ENTER;`
  |-SCANCODE_KP_1 (variable) [definition]: `static int const SCANCODE_KP_1=SDL_SCANCODE_KP_1;`
  |-SCANCODE_KP_2 (variable) [definition]: `static int const SCANCODE_KP_2=SDL_SCANCODE_KP_2;`
  |-SCANCODE_KP_3 (variable) [definition]: `static int const SCANCODE_KP_3=SDL_SCANCODE_KP_3;`
  |-SCANCODE_KP_4 (variable) [definition]: `static int const SCANCODE_KP_4=SDL_SCANCODE_KP_4;`
  |-SCANCODE_KP_5 (variable) [definition]: `static int const SCANCODE_KP_5=SDL_SCANCODE_KP_5;`
  |-SCANCODE_KP_6 (variable) [definition]: `static int const SCANCODE_KP_6=SDL_SCANCODE_KP_6;`
  |-SCANCODE_KP_7 (variable) [definition]: `static int const SCANCODE_KP_7=SDL_SCANCODE_KP_7;`
  |-SCANCODE_KP_8 (variable) [definition]: `static int const SCANCODE_KP_8=SDL_SCANCODE_KP_8;`
  |-SCANCODE_KP_9 (variable) [definition]: `static int const SCANCODE_KP_9=SDL_SCANCODE_KP_9;`
  |-SCANCODE_KP_0 (variable) [definition]: `static int const SCANCODE_KP_0=SDL_SCANCODE_KP_0;`
  |-SCANCODE_KP_PERIOD (variable) [definition]: `static int const SCANCODE_KP_PERIOD=SDL_SCANCODE_KP_PERIOD;`
  |-SCANCODE_NONUSBACKSLASH (variable) [definition]: `static int const SCANCODE_NONUSBACKSLASH=SDL_SCANCODE_NONUSBACKSLASH;`
  |-SCANCODE_APPLICATION (variable) [definition]: `static int const SCANCODE_APPLICATION=SDL_SCANCODE_APPLICATION;`
  |-SCANCODE_POWER (variable) [definition]: `static int const SCANCODE_POWER=SDL_SCANCODE_POWER;`
  |-SCANCODE_KP_EQUALS (variable) [definition]: `static int const SCANCODE_KP_EQUALS=SDL_SCANCODE_KP_EQUALS;`
  |-SCANCODE_F13 (variable) [definition]: `static int const SCANCODE_F13=SDL_SCANCODE_F13;`
  |-SCANCODE_F14 (variable) [definition]: `static int const SCANCODE_F14=SDL_SCANCODE_F14;`
  |-SCANCODE_F15 (variable) [definition]: `static int const SCANCODE_F15=SDL_SCANCODE_F15;`
  |-SCANCODE_F16 (variable) [definition]: `static int const SCANCODE_F16=SDL_SCANCODE_F16;`
  |-SCANCODE_F17 (variable) [definition]: `static int const SCANCODE_F17=SDL_SCANCODE_F17;`
  |-SCANCODE_F18 (variable) [definition]: `static int const SCANCODE_F18=SDL_SCANCODE_F18;`
  |-SCANCODE_F19 (variable) [definition]: `static int const SCANCODE_F19=SDL_SCANCODE_F19;`
  |-SCANCODE_F20 (variable) [definition]: `static int const SCANCODE_F20=SDL_SCANCODE_F20;`
  |-SCANCODE_F21 (variable) [definition]: `static int const SCANCODE_F21=SDL_SCANCODE_F21;`
  |-SCANCODE_F22 (variable) [definition]: `static int const SCANCODE_F22=SDL_SCANCODE_F22;`
  |-SCANCODE_F23 (variable) [definition]: `static int const SCANCODE_F23=SDL_SCANCODE_F23;`
  |-SCANCODE_F24 (variable) [definition]: `static int const SCANCODE_F24=SDL_SCANCODE_F24;`
  |-SCANCODE_EXECUTE (variable) [definition]: `static int const SCANCODE_EXECUTE=SDL_SCANCODE_EXECUTE;`
  |-SCANCODE_HELP (variable) [definition]: `static int const SCANCODE_HELP=SDL_SCANCODE_HELP;`
  |-SCANCODE_MENU (variable) [definition]: `static int const SCANCODE_MENU=SDL_SCANCODE_MENU;`
  |-SCANCODE_SELECT (variable) [definition]: `static int const SCANCODE_SELECT=SDL_SCANCODE_SELECT;`
  |-SCANCODE_STOP (variable) [definition]: `static int const SCANCODE_STOP=SDL_SCANCODE_STOP;`
  |-SCANCODE_AGAIN (variable) [definition]: `static int const SCANCODE_AGAIN=SDL_SCANCODE_AGAIN;`
  |-SCANCODE_UNDO (variable) [definition]: `static int const SCANCODE_UNDO=SDL_SCANCODE_UNDO;`
  |-SCANCODE_CUT (variable) [definition]: `static int const SCANCODE_CUT=SDL_SCANCODE_CUT;`
  |-SCANCODE_COPY (variable) [definition]: `static int const SCANCODE_COPY=SDL_SCANCODE_COPY;`
  |-SCANCODE_PASTE (variable) [definition]: `static int const SCANCODE_PASTE=SDL_SCANCODE_PASTE;`
  |-SCANCODE_FIND (variable) [definition]: `static int const SCANCODE_FIND=SDL_SCANCODE_FIND;`
  |-SCANCODE_MUTE (variable) [definition]: `static int const SCANCODE_MUTE=SDL_SCANCODE_MUTE;`
  |-SCANCODE_VOLUMEUP (variable) [definition]: `static int const SCANCODE_VOLUMEUP=SDL_SCANCODE_VOLUMEUP;`
  |-SCANCODE_VOLUMEDOWN (variable) [definition]: `static int const SCANCODE_VOLUMEDOWN=SDL_SCANCODE_VOLUMEDOWN;`
  |-SCANCODE_KP_COMMA (variable) [definition]: `static int const SCANCODE_KP_COMMA=SDL_SCANCODE_KP_COMMA;`
  |-SCANCODE_KP_EQUALSAS400 (variable) [definition]: `static int const SCANCODE_KP_EQUALSAS400=SDL_SCANCODE_KP_EQUALSAS400;`
  |-SCANCODE_INTERNATIONAL1 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL1=SDL_SCANCODE_INTERNATIONAL1;`
  |-SCANCODE_INTERNATIONAL2 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL2=SDL_SCANCODE_INTERNATIONAL2;`
  |-SCANCODE_INTERNATIONAL3 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL3=SDL_SCANCODE_INTERNATIONAL3;`
  |-SCANCODE_INTERNATIONAL4 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL4=SDL_SCANCODE_INTERNATIONAL4;`
  |-SCANCODE_INTERNATIONAL5 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL5=SDL_SCANCODE_INTERNATIONAL5;`
  |-SCANCODE_INTERNATIONAL6 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL6=SDL_SCANCODE_INTERNATIONAL6;`
  |-SCANCODE_INTERNATIONAL7 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL7=SDL_SCANCODE_INTERNATIONAL7;`
  |-SCANCODE_INTERNATIONAL8 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL8=SDL_SCANCODE_INTERNATIONAL8;`
  |-SCANCODE_INTERNATIONAL9 (variable) [definition]: `static int const SCANCODE_INTERNATIONAL9=SDL_SCANCODE_INTERNATIONAL9;`
  |-SCANCODE_LANG1 (variable) [definition]: `static int const SCANCODE_LANG1=SDL_SCANCODE_LANG1;`
  |-SCANCODE_LANG2 (variable) [definition]: `static int const SCANCODE_LANG2=SDL_SCANCODE_LANG2;`
  |-SCANCODE_LANG3 (variable) [definition]: `static int const SCANCODE_LANG3=SDL_SCANCODE_LANG3;`
  |-SCANCODE_LANG4 (variable) [definition]: `static int const SCANCODE_LANG4=SDL_SCANCODE_LANG4;`
  |-SCANCODE_LANG5 (variable) [definition]: `static int const SCANCODE_LANG5=SDL_SCANCODE_LANG5;`
  |-SCANCODE_LANG6 (variable) [definition]: `static int const SCANCODE_LANG6=SDL_SCANCODE_LANG6;`
  |-SCANCODE_LANG7 (variable) [definition]: `static int const SCANCODE_LANG7=SDL_SCANCODE_LANG7;`
  |-SCANCODE_LANG8 (variable) [definition]: `static int const SCANCODE_LANG8=SDL_SCANCODE_LANG8;`
  |-SCANCODE_LANG9 (variable) [definition]: `static int const SCANCODE_LANG9=SDL_SCANCODE_LANG9;`
  |-SCANCODE_ALTERASE (variable) [definition]: `static int const SCANCODE_ALTERASE=SDL_SCANCODE_ALTERASE;`
  |-SCANCODE_SYSREQ (variable) [definition]: `static int const SCANCODE_SYSREQ=SDL_SCANCODE_SYSREQ;`
  |-SCANCODE_CANCEL (variable) [definition]: `static int const SCANCODE_CANCEL=SDL_SCANCODE_CANCEL;`
  |-SCANCODE_CLEAR (variable) [definition]: `static int const SCANCODE_CLEAR=SDL_SCANCODE_CLEAR;`
  |-SCANCODE_PRIOR (variable) [definition]: `static int const SCANCODE_PRIOR=SDL_SCANCODE_PRIOR;`
  |-SCANCODE_RETURN2 (variable) [definition]: `static int const SCANCODE_RETURN2=SDL_SCANCODE_RETURN2;`
  |-SCANCODE_SEPARATOR (variable) [definition]: `static int const SCANCODE_SEPARATOR=SDL_SCANCODE_SEPARATOR;`
  |-SCANCODE_OUT (variable) [definition]: `static int const SCANCODE_OUT=SDL_SCANCODE_OUT;`
  |-SCANCODE_OPER (variable) [definition]: `static int const SCANCODE_OPER=SDL_SCANCODE_OPER;`
  |-SCANCODE_CLEARAGAIN (variable) [definition]: `static int const SCANCODE_CLEARAGAIN=SDL_SCANCODE_CLEARAGAIN;`
  |-SCANCODE_CRSEL (variable) [definition]: `static int const SCANCODE_CRSEL=SDL_SCANCODE_CRSEL;`
  |-SCANCODE_EXSEL (variable) [definition]: `static int const SCANCODE_EXSEL=SDL_SCANCODE_EXSEL;`
  |-SCANCODE_KP_00 (variable) [definition]: `static int const SCANCODE_KP_00=SDL_SCANCODE_KP_00;`
  |-SCANCODE_KP_000 (variable) [definition]: `static int const SCANCODE_KP_000=SDL_SCANCODE_KP_000;`
  |-SCANCODE_THOUSANDSSEPARATOR (variable) [definition]: `static int const SCANCODE_THOUSANDSSEPARATOR=SDL_SCANCODE_THOUSANDSSEPARATOR;`
  |-SCANCODE_DECIMALSEPARATOR (variable) [definition]: `static int const SCANCODE_DECIMALSEPARATOR=SDL_SCANCODE_DECIMALSEPARATOR;`
  |-SCANCODE_CURRENCYUNIT (variable) [definition]: `static int const SCANCODE_CURRENCYUNIT=SDL_SCANCODE_CURRENCYUNIT;`
  |-SCANCODE_CURRENCYSUBUNIT (variable) [definition]: `static int const SCANCODE_CURRENCYSUBUNIT=SDL_SCANCODE_CURRENCYSUBUNIT;`
  |-SCANCODE_KP_LEFTPAREN (variable) [definition]: `static int const SCANCODE_KP_LEFTPAREN=SDL_SCANCODE_KP_LEFTPAREN;`
  |-SCANCODE_KP_RIGHTPAREN (variable) [definition]: `static int const SCANCODE_KP_RIGHTPAREN=SDL_SCANCODE_KP_RIGHTPAREN;`
  |-SCANCODE_KP_LEFTBRACE (variable) [definition]: `static int const SCANCODE_KP_LEFTBRACE=SDL_SCANCODE_KP_LEFTBRACE;`
  |-SCANCODE_KP_RIGHTBRACE (variable) [definition]: `static int const SCANCODE_KP_RIGHTBRACE=SDL_SCANCODE_KP_RIGHTBRACE;`
  |-SCANCODE_KP_TAB (variable) [definition]: `static int const SCANCODE_KP_TAB=SDL_SCANCODE_KP_TAB;`
  |-SCANCODE_KP_BACKSPACE (variable) [definition]: `static int const SCANCODE_KP_BACKSPACE=SDL_SCANCODE_KP_BACKSPACE;`
  |-SCANCODE_KP_A (variable) [definition]: `static int const SCANCODE_KP_A=SDL_SCANCODE_KP_A;`
  |-SCANCODE_KP_B (variable) [definition]: `static int const SCANCODE_KP_B=SDL_SCANCODE_KP_B;`
  |-SCANCODE_KP_C (variable) [definition]: `static int const SCANCODE_KP_C=SDL_SCANCODE_KP_C;`
  |-SCANCODE_KP_D (variable) [definition]: `static int const SCANCODE_KP_D=SDL_SCANCODE_KP_D;`
  |-SCANCODE_KP_E (variable) [definition]: `static int const SCANCODE_KP_E=SDL_SCANCODE_KP_E;`
  |-SCANCODE_KP_F (variable) [definition]: `static int const SCANCODE_KP_F=SDL_SCANCODE_KP_F;`
  |-SCANCODE_KP_XOR (variable) [definition]: `static int const SCANCODE_KP_XOR=SDL_SCANCODE_KP_XOR;`
  |-SCANCODE_KP_POWER (variable) [definition]: `static int const SCANCODE_KP_POWER=SDL_SCANCODE_KP_POWER;`
  |-SCANCODE_KP_PERCENT (variable) [definition]: `static int const SCANCODE_KP_PERCENT=SDL_SCANCODE_KP_PERCENT;`
  |-SCANCODE_KP_LESS (variable) [definition]: `static int const SCANCODE_KP_LESS=SDL_SCANCODE_KP_LESS;`
  |-SCANCODE_KP_GREATER (variable) [definition]: `static int const SCANCODE_KP_GREATER=SDL_SCANCODE_KP_GREATER;`
  |-SCANCODE_KP_AMPERSAND (variable) [definition]: `static int const SCANCODE_KP_AMPERSAND=SDL_SCANCODE_KP_AMPERSAND;`
  |-SCANCODE_KP_DBLAMPERSAND (variable) [definition]: `static int const SCANCODE_KP_DBLAMPERSAND=SDL_SCANCODE_KP_DBLAMPERSAND;`
  |-SCANCODE_KP_VERTICALBAR (variable) [definition]: `static int const SCANCODE_KP_VERTICALBAR=SDL_SCANCODE_KP_VERTICALBAR;`
  |-SCANCODE_KP_DBLVERTICALBAR (variable) [definition]: `static int const SCANCODE_KP_DBLVERTICALBAR=SDL_SCANCODE_KP_DBLVERTICALBAR;`
  |-SCANCODE_KP_COLON (variable) [definition]: `static int const SCANCODE_KP_COLON=SDL_SCANCODE_KP_COLON;`
  |-SCANCODE_KP_HASH (variable) [definition]: `static int const SCANCODE_KP_HASH=SDL_SCANCODE_KP_HASH;`
  |-SCANCODE_KP_SPACE (variable) [definition]: `static int const SCANCODE_KP_SPACE=SDL_SCANCODE_KP_SPACE;`
  |-SCANCODE_KP_AT (variable) [definition]: `static int const SCANCODE_KP_AT=SDL_SCANCODE_KP_AT;`
  |-SCANCODE_KP_EXCLAM (variable) [definition]: `static int const SCANCODE_KP_EXCLAM=SDL_SCANCODE_KP_EXCLAM;`
  |-SCANCODE_KP_MEMSTORE (variable) [definition]: `static int const SCANCODE_KP_MEMSTORE=SDL_SCANCODE_KP_MEMSTORE;`
  |-SCANCODE_KP_MEMRECALL (variable) [definition]: `static int const SCANCODE_KP_MEMRECALL=SDL_SCANCODE_KP_MEMRECALL;`
  |-SCANCODE_KP_MEMCLEAR (variable) [definition]: `static int const SCANCODE_KP_MEMCLEAR=SDL_SCANCODE_KP_MEMCLEAR;`
  |-SCANCODE_KP_MEMADD (variable) [definition]: `static int const SCANCODE_KP_MEMADD=SDL_SCANCODE_KP_MEMADD;`
  |-SCANCODE_KP_MEMSUBTRACT (variable) [definition]: `static int const SCANCODE_KP_MEMSUBTRACT=SDL_SCANCODE_KP_MEMSUBTRACT;`
  |-SCANCODE_KP_MEMMULTIPLY (variable) [definition]: `static int const SCANCODE_KP_MEMMULTIPLY=SDL_SCANCODE_KP_MEMMULTIPLY;`
  |-SCANCODE_KP_MEMDIVIDE (variable) [definition]: `static int const SCANCODE_KP_MEMDIVIDE=SDL_SCANCODE_KP_MEMDIVIDE;`
  |-SCANCODE_KP_PLUSMINUS (variable) [definition]: `static int const SCANCODE_KP_PLUSMINUS=SDL_SCANCODE_KP_PLUSMINUS;`
  |-SCANCODE_KP_CLEAR (variable) [definition]: `static int const SCANCODE_KP_CLEAR=SDL_SCANCODE_KP_CLEAR;`
  |-SCANCODE_KP_CLEARENTRY (variable) [definition]: `static int const SCANCODE_KP_CLEARENTRY=SDL_SCANCODE_KP_CLEARENTRY;`
  |-SCANCODE_KP_BINARY (variable) [definition]: `static int const SCANCODE_KP_BINARY=SDL_SCANCODE_KP_BINARY;`
  |-SCANCODE_KP_OCTAL (variable) [definition]: `static int const SCANCODE_KP_OCTAL=SDL_SCANCODE_KP_OCTAL;`
  |-SCANCODE_KP_DECIMAL (variable) [definition]: `static int const SCANCODE_KP_DECIMAL=SDL_SCANCODE_KP_DECIMAL;`
  |-SCANCODE_KP_HEXADECIMAL (variable) [definition]: `static int const SCANCODE_KP_HEXADECIMAL=SDL_SCANCODE_KP_HEXADECIMAL;`
  |-SCANCODE_LCTRL (variable) [definition]: `static int const SCANCODE_LCTRL=SDL_SCANCODE_LCTRL;`
  |-SCANCODE_LSHIFT (variable) [definition]: `static int const SCANCODE_LSHIFT=SDL_SCANCODE_LSHIFT;`
  |-SCANCODE_LALT (variable) [definition]: `static int const SCANCODE_LALT=SDL_SCANCODE_LALT;`
  |-SCANCODE_LGUI (variable) [definition]: `static int const SCANCODE_LGUI=SDL_SCANCODE_LGUI;`
  |-SCANCODE_RCTRL (variable) [definition]: `static int const SCANCODE_RCTRL=SDL_SCANCODE_RCTRL;`
  |-SCANCODE_RSHIFT (variable) [definition]: `static int const SCANCODE_RSHIFT=SDL_SCANCODE_RSHIFT;`
  |-SCANCODE_RALT (variable) [definition]: `static int const SCANCODE_RALT=SDL_SCANCODE_RALT;`
  |-SCANCODE_RGUI (variable) [definition]: `static int const SCANCODE_RGUI=SDL_SCANCODE_RGUI;`
  |-SCANCODE_MODE (variable) [definition]: `static int const SCANCODE_MODE=SDL_SCANCODE_MODE;`
  |-SCANCODE_AUDIONEXT (variable) [definition]: `static int const SCANCODE_AUDIONEXT=SDL_SCANCODE_AUDIONEXT;`
  |-SCANCODE_AUDIOPREV (variable) [definition]: `static int const SCANCODE_AUDIOPREV=SDL_SCANCODE_AUDIOPREV;`
  |-SCANCODE_AUDIOSTOP (variable) [definition]: `static int const SCANCODE_AUDIOSTOP=SDL_SCANCODE_AUDIOSTOP;`
  |-SCANCODE_AUDIOPLAY (variable) [definition]: `static int const SCANCODE_AUDIOPLAY=SDL_SCANCODE_AUDIOPLAY;`
  |-SCANCODE_AUDIOMUTE (variable) [definition]: `static int const SCANCODE_AUDIOMUTE=SDL_SCANCODE_AUDIOMUTE;`
  |-SCANCODE_MEDIASELECT (variable) [definition]: `static int const SCANCODE_MEDIASELECT=SDL_SCANCODE_MEDIASELECT;`
  |-SCANCODE_WWW (variable) [definition]: `static int const SCANCODE_WWW=SDL_SCANCODE_WWW;`
  |-SCANCODE_MAIL (variable) [definition]: `static int const SCANCODE_MAIL=SDL_SCANCODE_MAIL;`
  |-SCANCODE_CALCULATOR (variable) [definition]: `static int const SCANCODE_CALCULATOR=SDL_SCANCODE_CALCULATOR;`
  |-SCANCODE_COMPUTER (variable) [definition]: `static int const SCANCODE_COMPUTER=SDL_SCANCODE_COMPUTER;`
  |-SCANCODE_AC_SEARCH (variable) [definition]: `static int const SCANCODE_AC_SEARCH=SDL_SCANCODE_AC_SEARCH;`
  |-SCANCODE_AC_HOME (variable) [definition]: `static int const SCANCODE_AC_HOME=SDL_SCANCODE_AC_HOME;`
  |-SCANCODE_AC_BACK (variable) [definition]: `static int const SCANCODE_AC_BACK=SDL_SCANCODE_AC_BACK;`
  |-SCANCODE_AC_FORWARD (variable) [definition]: `static int const SCANCODE_AC_FORWARD=SDL_SCANCODE_AC_FORWARD;`
  |-SCANCODE_AC_STOP (variable) [definition]: `static int const SCANCODE_AC_STOP=SDL_SCANCODE_AC_STOP;`
  |-SCANCODE_AC_REFRESH (variable) [definition]: `static int const SCANCODE_AC_REFRESH=SDL_SCANCODE_AC_REFRESH;`
  |-SCANCODE_AC_BOOKMARKS (variable) [definition]: `static int const SCANCODE_AC_BOOKMARKS=SDL_SCANCODE_AC_BOOKMARKS;`
  |-SCANCODE_BRIGHTNESSDOWN (variable) [definition]: `static int const SCANCODE_BRIGHTNESSDOWN=SDL_SCANCODE_BRIGHTNESSDOWN;`
  |-SCANCODE_BRIGHTNESSUP (variable) [definition]: `static int const SCANCODE_BRIGHTNESSUP=SDL_SCANCODE_BRIGHTNESSUP;`
  |-SCANCODE_DISPLAYSWITCH (variable) [definition]: `static int const SCANCODE_DISPLAYSWITCH=SDL_SCANCODE_DISPLAYSWITCH;`
  |-SCANCODE_KBDILLUMTOGGLE (variable) [definition]: `static int const SCANCODE_KBDILLUMTOGGLE=SDL_SCANCODE_KBDILLUMTOGGLE;`
  |-SCANCODE_KBDILLUMDOWN (variable) [definition]: `static int const SCANCODE_KBDILLUMDOWN=SDL_SCANCODE_KBDILLUMDOWN;`
  |-SCANCODE_KBDILLUMUP (variable) [definition]: `static int const SCANCODE_KBDILLUMUP=SDL_SCANCODE_KBDILLUMUP;`
  |-SCANCODE_EJECT (variable) [definition]: `static int const SCANCODE_EJECT=SDL_SCANCODE_EJECT;`
  |-SCANCODE_SLEEP (variable) [definition]: `static int const SCANCODE_SLEEP=SDL_SCANCODE_SLEEP;`
  |-SCANCODE_APP1 (variable) [definition]: `static int const SCANCODE_APP1=SDL_SCANCODE_APP1;`
  |-SCANCODE_APP2 (variable) [definition]: `static int const SCANCODE_APP2=SDL_SCANCODE_APP2;`
  |-HAT_CENTER (variable) [definition]: `static int const HAT_CENTER=SDL_HAT_CENTERED;`
  |-HAT_UP (variable) [definition]: `static int const HAT_UP=SDL_HAT_UP;`
  |-HAT_RIGHT (variable) [definition]: `static int const HAT_RIGHT=SDL_HAT_RIGHT;`
  |-HAT_DOWN (variable) [definition]: `static int const HAT_DOWN=SDL_HAT_DOWN;`
  |-HAT_LEFT (variable) [definition]: `static int const HAT_LEFT=SDL_HAT_LEFT;`
  |-CONTROLLER_BUTTON_A (variable) [definition]: `static int const CONTROLLER_BUTTON_A=SDL_CONTROLLER_BUTTON_A;`
  |-CONTROLLER_BUTTON_B (variable) [definition]: `static int const CONTROLLER_BUTTON_B=SDL_CONTROLLER_BUTTON_B;`
  |-CONTROLLER_BUTTON_X (variable) [definition]: `static int const CONTROLLER_BUTTON_X=SDL_CONTROLLER_BUTTON_X;`
  |-CONTROLLER_BUTTON_Y (variable) [definition]: `static int const CONTROLLER_BUTTON_Y=SDL_CONTROLLER_BUTTON_Y;`
  |-CONTROLLER_BUTTON_BACK (variable) [definition]: `static int const CONTROLLER_BUTTON_BACK=SDL_CONTROLLER_BUTTON_BACK;`
  |-CONTROLLER_BUTTON_GUIDE (variable) [definition]: `static int const CONTROLLER_BUTTON_GUIDE=SDL_CONTROLLER_BUTTON_GUIDE;`
  |-CONTROLLER_BUTTON_START (variable) [definition]: `static int const CONTROLLER_BUTTON_START=SDL_CONTROLLER_BUTTON_START;`
  |-CONTROLLER_BUTTON_LEFTSTICK (variable) [definition]: `static int const CONTROLLER_BUTTON_LEFTSTICK=SDL_CONTROLLER_BUTTON_LEFTSTICK;`
  |-CONTROLLER_BUTTON_RIGHTSTICK (variable) [definition]: `static int const CONTROLLER_BUTTON_RIGHTSTICK=SDL_CONTROLLER_BUTTON_RIGHTSTICK;`
  |-CONTROLLER_BUTTON_LEFTSHOULDER (variable) [definition]: `static int const CONTROLLER_BUTTON_LEFTSHOULDER=SDL_CONTROLLER_BUTTON_LEFTSHOULDER;`
  |-CONTROLLER_BUTTON_RIGHTSHOULDER (variable) [definition]: `static int const CONTROLLER_BUTTON_RIGHTSHOULDER=SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;`
  |-CONTROLLER_BUTTON_DPAD_UP (variable) [definition]: `static int const CONTROLLER_BUTTON_DPAD_UP=SDL_CONTROLLER_BUTTON_DPAD_UP;`
  |-CONTROLLER_BUTTON_DPAD_DOWN (variable) [definition]: `static int const CONTROLLER_BUTTON_DPAD_DOWN=SDL_CONTROLLER_BUTTON_DPAD_DOWN;`
  |-CONTROLLER_BUTTON_DPAD_LEFT (variable) [definition]: `static int const CONTROLLER_BUTTON_DPAD_LEFT=SDL_CONTROLLER_BUTTON_DPAD_LEFT;`
  |-CONTROLLER_BUTTON_DPAD_RIGHT (variable) [definition]: `static int const CONTROLLER_BUTTON_DPAD_RIGHT=SDL_CONTROLLER_BUTTON_DPAD_RIGHT;`
  |-CONTROLLER_AXIS_LEFTX (variable) [definition]: `static int const CONTROLLER_AXIS_LEFTX=SDL_CONTROLLER_AXIS_LEFTX;`
  |-CONTROLLER_AXIS_LEFTY (variable) [definition]: `static int const CONTROLLER_AXIS_LEFTY=SDL_CONTROLLER_AXIS_LEFTY;`
  |-CONTROLLER_AXIS_RIGHTX (variable) [definition]: `static int const CONTROLLER_AXIS_RIGHTX=SDL_CONTROLLER_AXIS_RIGHTX;`
  |-CONTROLLER_AXIS_RIGHTY (variable) [definition]: `static int const CONTROLLER_AXIS_RIGHTY=SDL_CONTROLLER_AXIS_RIGHTY;`
  |-CONTROLLER_AXIS_TRIGGERLEFT (variable) [definition]: `static int const CONTROLLER_AXIS_TRIGGERLEFT=SDL_CONTROLLER_AXIS_TRIGGERLEFT;`
  +-CONTROLLER_AXIS_TRIGGERRIGHT (variable) [definition]: `static int const CONTROLLER_AXIS_TRIGGERRIGHT=SDL_CONTROLLER_AXIS_TRIGGERRIGHT;`

Constructor attributes are not captured when they precede the name.

  • cppast version: latest
  • parser: libclang_parser
  • clang version: 6.0

Attributes in constructors are captured only if they appear after constructor's name.

Input:

// this works:
struct X
{
    X [[my_ctor]]] () {}
};

// but this doesn't work as I would expect it to:
struct Y
{
    [[my_ctor]]
    Y() {}
};

Input flags: same as for unit tests.

How do i tell if cpp_type is enum?

I am generating a c wrapper over api using cppast and i came to need to decide if type is complex or not. Checking cppast source code i noticed that user_defined_t is treated as non-complex. I may not understand what exactly is complex type here because for example user-defined class types are also user_defined_t. So is there a way to figure out if particular cpp_type is backed by a simple data type like enums are backed by integers for example?

error: invalid filename for #line directive on windows

  • cppast version: latest
  • clang version: 5.0.1 / 6.0.0
  • MSVC 19.12.25834.0 (vs 2017)

Input cpp file:

#include <type_traits>
void foo() { }

Output:

cppast.exe --msvc_extensions --msvc_compatibility test.cpp
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2518):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:70: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2544):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:69: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2548):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:70: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2552):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:69: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2563):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:69: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2567):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:70: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2571):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:69: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2583):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:69: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2587):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:70: note: expanded from here
[preprocessor] [error] In file included from ..\test.cpp: 1:
[preprocessor] [error] C: \Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\type_traits(2591):  error: invalid filename for #line directive
[preprocessor] [error] <scratch space>:69: note: expanded from here
[fatal parsing error] preprocessor: command 'C:/LLVM/bin/clang++.exe -x c++ -E -CC -dD -Xclang -dI -fno-caret-diagnostics -fno-show-column -fdiagnostics-format=msvc -Wno-macro-redefined -Wno-pragma-once-outside-header -Wno-pragma-system-header-outside-header -Wno-include-next-outside-header -IC:/LLVM -D__cppast__="libclang" -D__cppast_version_major__="0" -D__cppast_version_minor__="0" -std=c++14 -fms-compatibility -fms-extensions "test.cpp"' exited with non-zero exit code (1)
``

Compilation database parsing

I'm reading a compilation database, and I don't want to use the flags abstractions to supply the flags to the config. I would have to parse the string flags just have cppast put the same string together. So, is there a way to set the directly?

Filtered node visitation

I started playing with the library and I found myself often writing visitor callbacks, that:

  • Filter out "exit" tokens
  • Blacklist-style filter out certain entity types (e.g. file node)
  • Whitelist-style filter for certain node types ("iterate over only enums")

Some form of declarative filtering would be quite useful, e.g.

visit(file, cppast::whitelist(cpp_entity_type::enum_t, cpp_entity_type::class_t), [&](const cpp_entity& e, visitor_info info) {

or

visit(file, cppast::blacklist(cpp_entity_type::enum_value_t, cpp_entity_type::struct_t), [&](const cpp_entity& e, visitor_info info) {

(not sure about the syntax, but you get the idea). As for the enter-exit events, it might even make sense to provide a simple_visit function that only does enter events, since that's a large use-case.

`decltype` expression is always `cpp_unexposed_expression`

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

The expression inside a decltype() will always be a cpp_unexposed_expression and the type of the expression is not exposed either. On a related note, cpp_decltype_auto_type will never be created, decltype(auto) will create a simple cpp_auto_type instead.

Extracting constructor signature

Hi,

I'm trying to generate reflection information of class constructors, and I would like to extract the exact signature of a given cpp_constructor as an string. For example:

struct Foo
{
     Foo(int i, const std::string& str);
};

would return "Foo(int, const std::string&)" for that Foo constructor.

I've found that manipulating the cpp_type hierarchy myself is a bit tedious (handling all the different kinds of types, cross-referencing types thanks to pointers and reference qualifiers, etc), so I was wondering if you already wrote such a functionality. I see that Standardese outputs full signature function names, but I wasn't sure if Standardese just got the displayname from libclang (which is complete iirc) or if it implemented a complex get-function-signature algorithm like what I need.

After checking Standardese sources for 30m I didn't find anything like that, so here I am asking for some pointers in that regard.

Thanks.

Mangled names

Would it be possible to expose mangled names? It could be very helpful when generating API wrappers for foreign languages.

Arguments in a template specialization are not exposed

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

Due to a libclang limitation, the arguments in a template specialization are only available as a string unless the specialization is in a friend declaration.

Input:

template <typename T, int I>
struct foo {};

template <>
struct foo<int, 42> {};

Here, the only information available about the specialization arguments is the string "int, 42".

Parsing fails at the end of the file with "no tokens available" message

  • cppast version: latest
  • clang version: 5.0.1

In addition to issue explained to the title cppast output also does not show base classes. Could it be related?

Input file: https://github.com/rokups/Urho3D/blob/master/Source/Urho3D/IO/AbstractFile.h
Input flags: -std=c++11

Output of cppast -v -I . -I .. -D URHO3D_API --std c++11 IO/AbstractFile.h:

[preprocessor] [debug] IO/AbstractFile.h:25: parsing include '../IO/Serializer.h'
[preprocessor] [debug] IO/AbstractFile.h:26: parsing include '../IO/Deserializer.h'
[libclang parser] [debug] IO/AbstractFile.h:28: parsing cursor of type 'Namespace'
[libclang parser] [debug] IO/AbstractFile.h:32: parsing cursor of type 'ClassDecl'
[libclang parser] [debug] IO/AbstractFile.h:32: parsing cursor of type 'attribute(visibility)'
[libclang parser] [debug] IO/AbstractFile.h:36: parsing cursor of type 'CXXConstructor'
[libclang parser] [debug] IO/AbstractFile.h:38: parsing cursor of type 'CXXConstructor'
[libclang parser] [debug] IO/AbstractFile.h:40: parsing cursor of type 'CXXDestructor'
[libclang parser] [debug] IO/AbstractFile.h:43: parsing cursor of type 'UnexposedDecl'
[libclang parser] [error] IO/AbstractFile.h:43: no tokens available
AST for 'IO/AbstractFile.h':
|-../IO/Serializer.h (include directive): `#include "../IO/Serializer.h"`
|-../IO/Deserializer.h (include directive): `#include "../IO/Deserializer.h"`
+-Urho3D (namespace)
  +-AbstractFile (class) [definition]: `class AbstractFile;`
    |-public (access specifier): `public:`
    |-AbstractFile (constructor) [definition]: `AbstractFile();`
    |-AbstractFile (constructor) [definition]: `explicit AbstractFile(unsigned int size);`
    +-~AbstractFile (destructor) [definition]: `virtual ~AbstractFile()=default;`

Getting arguments of template instantiation

I am trying to get templated type parameter. This oversimplified example fails:

if (type.kind() == cppast::cpp_type_kind::template_instantiation_t)
{
    const auto& templateType = dynamic_cast<const cppast::cpp_template_instantiation_type&>(type);
    templateType.arguments().value();    // type_safe/tagged_union.hpp:262: Assertion 'cur_type_ == type' failed - different type stored in union.
}

Am i doing something wrong or is this a bug?

Default type of template type parameter is unexposed

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

The default type of a template type parameter is always unexposed, as there is no way to retrieve them from libclang.

Input:

template <typename T = int>
void foo();

Variable type of pointer to member variable is unexposed

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

If you have a pointer to a member variable, you'll correctly get a cpp_pointer_type to a cpp_member_object_type but the type returned by object_type() is always a cpp_unexposed_type.
This is due to an issue with libclang's clang_getPointeeType() returning an invalid type for pointers to member variable (works fine with pointers to member functions).

Input:

struct foo {};

using type = int(foo::*);

Any chance for examples of common usage?

Right now it's hard to see where to get started, what are the main "entry points" from the library users' perspective. Examples of extracting member functions, attributes, enums etc. would be great.

Comments in macro parameter lists trigger an error

  • cppast version: 0.0 (1053429)
  • parser: libclang_parser
  • clang version: 3.9.1

Input:

#define ADD(A /* plus */, B) ((A) + (B))

Input flags:

none

Output:

[preprocessor] [error] main.cpp:3: expected comma in macro parameter list
[fatal parsing error] preprocessor: command '/usr/bin/clang -x c++ -I. -E -CC -dD -fno-caret-diagnostics -fno-show-column -fdiagnostics-format=msvc -Wno-pragma-once-outside-header -Wno-pragma-system-header-outside-header -Wno-include-next-outside-header -I/usr/lib64/clang/3.9.1/include -D__cppast__=libclang -D__cppast_version_major__=0 -D__cppast_version_minor__=0 -std=c++14 "main.cpp"' exited with non-zero exit code (1)

Output of cppast -v <input>

(the exact same error as above)

functions with the same name as their return type are misparsed

  • cppast version: latest master
  • clang version: tested with 5.0 and latest svn

If a function has the same name as its return type, it is misparsed as a class declaration it seems.

struct name {};
name name();

Now, this is a weird thing to do, but this is not as weird:

std::string string();

In fact it came up while implementing the filesystem ts, because of filesystem::path::string().

This is what standardese reports:

[libclang parser] [error] test.cpp:4: expected a bracket, got 'name'

Inconsistency when using C++11 `friend` syntax for types

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 4.0

C++11 introduced a new syntax to mark types as friends, friend foo instead of friend class foo.
When parsing friend foo it will be treated as if friend class foo was written.
But when parsing friend ns::foo, it will be detected properly.

Support for custom llvm binary download URL

Hi,

To have reliable builds I'm thinking about patching external/external.cmake to allow passing a custom LLVM download URL (Say an internal binary server instead of pulling directly from LLVM releases). I would like to know your opinion on this.

Thanks in advance.

Walking a template specialization

Consider std::vector<std::string> used as return type somewhere. Is there a way to somehow use that return type and walk instantiation of class std::vector<std::string> so that methods of std::vector have std::string type inserted where appropriate? Or do i have to resolve these template types manually somehow?

P.S. I hope i am not getting annoying with spamming issue tracker with random questions. If there is a better place to ask these things please let me know.
P.P.S. Thank you for the help with other issues, i greatly appreciate swift response. Just never posted "thanks" messages to save you some spam in the mailbox :)

Variable templates are unexposed

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

A C++14 variable template isn't exposed by libclang, so it won't be parsed as a cpp_variable_template but as a cpp_unexposed_entity. Variable template specializations do not even have their own class yet.

Parsing fails on array function arguments

  • cppast version: latest
  • clang version: 5.0.1

test.cpp:

void foo(const char* const items[]);

cppast -v test.cpp:

[libclang parser] [debug] test.cpp:1: parsing cursor of type 'FunctionDecl'
[libclang parser] [error] test.cpp:1: expected '[', got exhausted stream
AST for 'test.cpp':
+-foo (function): `void foo();`

test.cpp.pp:

void foo(const char* const items[]);

Policies regarding project dependencies

I would like to open a discussion regarding how dependencies (and especially updating dependencies) should be handled in this project.

Please note I'm not talking about dependency managers or using a dependency manager

After some weeks working with the lib I found myself experimenting (Suffering, actually :P) the following scenario multiple times:

  • A dependency of a cppast dependency causes an issue.
  • Fix the issue
  • Update the cppast dependency to include the dependency of dependency fix
  • Update cppast to include the latest version of its dependency

This is exacerbated by the fact git submodules are a pain to work with (I'm at a 4th level in the dependency tree, with cppast being a submodule of my project). Maybe it's just me...

Anyway, I'm here because I think most of this issues would not be so if we write down some policies regarding cppast dependencies. Some ideas/questions:

  • Should cppast master include the latest master type_safe available?
  • What about type_safe and debug_assert? Same "always-up-to-date" policy as above?

Properly versioning the library(ies) would fix this situation ("cppast v1.3 uses type_safe v0.5, which uses debug_assert v1.0", but since all the three are under active development versioning is not a complete solution (In the case of stable releases the same issues would arise during development on the active branches).
Also, this same policies would make much more clear to me how to package the libraries.

Regarding versioning, maybe you could adopt a release train strategy, where you use cppast development (And Standardese) as locomotives of the train, releasing new versions of your libs every two months or so, including all master changes since the last release. In that case, I'm sure 90% of the time the release would be something like this:

  • debug_assert: Fixes, if any. Increase fix number
  • type_safe: Fixes, if any. Increase fix number. Reference debug_assert release above. A change whose sole purpose is to update to a non-breaking fix release of debug_assert is considered a fix. Updating to debug_assert minors (Like you developed a non-breaking debug_assert feature you find interesting for type_safe) is up to you. Else is major.
  • cppast: Features and/or fixes. Increase fix or minor number. Reference type_safe above. Same policies regarding dependencies described above.

Just some ideas, I would love to hear your opinion.

Thanks in advance.

Expression of default values is always `cpp_unexposed_expression`

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

The default value of a function parameter, template non type parameter and the initializer of a (member) variable is not exposed.
This is due to an ambiguity when parsing the children of the libclang cursor, there is no way to distinguish between the expression in the array size and the expression of the initializer.

Also see #7.

LIBCLANG_LIBRARY-NOTFOUND.lib

  • cppast version:
  • parser: libclang_parser
  • clang version: <4.0.1>

compile error:
1>------ 已启动生成: 项目: cppast_test, 配置: Debug Win32 ------
2>------ 已启动生成: 项目: cppast_tool, 配置: Debug Win32 ------
2>LINK : fatal error LNK1104: 无法打开文件“LIBCLANG_LIBRARY-NOTFOUND.lib”
1>LINK : fatal error LNK1104: 无法打开文件“LIBCLANG_LIBRARY-NOTFOUND.lib”

I can't find the library in clang or llvm project.
I don't understand why the library name.

Missing identifiers in global namespace

  • cppast version: fork (Current cppast master + two commits, see diff in the link).
  • libclang version: 3.9.1

Hi,

I'm sure this issue is not a cppast bug, but since I'm clueless right now I'm approaching you for help...

I've found that my parser is giving errors about undeclared entities in the global namespace, like std in std::string foo;, or tinyrefl in tinyrefl::foobar foo();

I think the issue is not related to missing include directories (there are no warnings/errors about missing headers), but just in case I've added the gcc/clang search include directories to the set of include directories of the parser. That doesn't fix the issue though.

Here is an example of the error, from a CI build. The tool parser setup is as follows:

bool reflect_file(const std::string& filepath, const std::string& cpp_standard, const std::vector<std::string>& include_dirs)
{
    using parser_t = cppast::simple_file_parser<cppast::libclang_parser>;

    if(!is_outdated_file(filepath))
    {
        std::cout << "file " << filepath << " metadata is up to date, skipping\n";
        return true;
    }

    cppast::cpp_entity_index index;
    parser_t parser{type_safe::ref(index)};
    parser_t::config config;
    config.set_flags(get_cpp_standard(cpp_standard));
    config.add_flag("-fPIC");

    std::cout << "parsing file " << filepath << " -std=c++"
        << cpp_standard << " ";

    for(const std::string& include_dir : include_dirs)
    {
        std::cout << "-I" << include_dir << " ";
        config.add_include_dir(include_dir);
    }

    std::cout << " ...\n";

    try
    {
        auto file = parser.parse(filepath, config);
        ...

as you can see the parser is fed with the C++ standard and set of include directories given as command line arguments to the tool.

Member class typedefs and weird ast content

cppast version: Manu343726@b58405b
libclang parser
libclang version: 4.0.0
Explanation of the error:

I'm trying to parse and examine the contents of classes declared as:

typdef struct
{
    int a, b, c;
} Foo;

I've written a function that tries to extract the cpp_class entity out of a cpp_type_alias, trying to match my requirements (anonymous struct type alias, struct declared in that same header, etc). If the type alias entity matches, getting the aliased class would be equivalent to:

type_safe::optional_ref<const cppast::cpp_class> class_typedef(index, typedef_entity)
{
    return type_safe::cref(typedef_entity.underlying_type().entity().get(index)[0]);
}

Things get interesting once I put the typedef struct as a class member (Which is my target use case):

struct Class
{
    typedef struct
    {
        int a, b;
    } InnerTypedefClass;

    int a, b;
};

My current AST "scanner" currently handles classes and enums only, so a typedef entity like TypedefClass there is ignored.

If I introduce a case for typedefs as members and apply the typedef struct matching logic described earlier, I successfully find a class declaration node. But also a class declaration node is automagically added as a member of the Class class.

My class members scanning system us just a plain call to visit on the class node (See https://gitlab.com/Manu343726/tinyrefl/blob/master/tool/tool.cpp#L267), and it's from inside that visitor that the typedef check algorithm is run (An extra case for the switch for the typedef):

case cppast::cpp_entity_kind::cpp_type_alias:
    const auto alias = class_typedef(child);
    if(alias) std::cout << " - class typedef " << child.name() << "\n";
    break;

...

With that change only (Note there's nothing done with the alias in the switch side), I see a TypedefClass class declaration appearing as class declaration member of Class, as if already were a child of the class. Note also I get the right class name (from the typedef pov, not an empty class name). Tool output:

    - (class typedef) TypedefStruct
    - (class) TypedefStruct (declaration) [attributes: ] <-- MAGIC

That's fairly weird, but maybe I'm misunderstanding something about how the AST works.

After that, I said "Ok, if a child is automatically added to the class, let's take advantage of that". Now I register typedef classes that are automatically added to my parent class to be scanned later. When I run an scan on TypedefStruct cpp_class entity, I get no members, and parent class members as base classes of TypedefStruct:

 # my_namespace::MyClass [attributes: ]
    - (member) f [attributes: ]
    - (member) str [attributes: ]
    - (enum) Enum [attributes: ]
    - (class) Foo (definition) [attributes: ]
    - (class) InnerClassWithMembers (definition) [attributes: ]
[warning] Found class with empty name at my_namespace::MyClass
    - (class typedef) TypedefStruct
    - (class) TypedefStruct (declaration) [attributes: ]
    - (member) innerClassInstance [attributes: ]
    - (base) my_namespace::BaseClass
    - (base) my_namespace::Foo
 # my_namespace::MyClass::TypedefStruct [attributes: ]
    - (base) my_namespace::MyClass::Foo                                  // WTF ???
    - (base) my_namespace::MyClass::InnerClassWithMembers // WTF ???
    - (base) my_namespace::MyClass::                                        // WTF ??? 
    - (base) my_namespace::MyClass::TypedefStruct                  // WHAAAAT ???
    - (base) my_namespace::MyClass::innerClassInstance         // WTF ???
    - (base) my_namespace::MyClass::private                             // WTF ???
    - (base) my_namespace::MyClass::_private                           // WTF ???

base classes are retrieved with cpp_class::bases().

I will try to get a minimal repo ASAP.

Function parameters are not visited

I think this is because member_function_t is not treated as a container in detail::visit, and simply the callback is called instead of recursive visitation. I'd assume standardese would need to parse function paramters, wouldn't it?

  • cppast version: 2be20f6
  • parser: libclang_parser
  • clang version: 4.0

Explanation of the error.

Input:

    auto code = R"(
          class foo {
            void f(int a, int b){};
          };
    )";

    cpp_entity_index idx;
    auto file = parse(idx, "cpp_class.cpp", code);
    unsigned filtered_count = 0;
    auto visitor_callback = [&](const cpp_entity &e, cppast::visitor_info info) {
      if (info.event == cppast::visitor_info::container_entity_exit)
        return true;
      std::cout << e.name() << " : " << cppast::to_string(e.kind()) << "\n";
    };

    cppast::visit(*file, visitor_callback);

Output:

cpp_class.cpp : file
foo : class
f : member function

I would expect the function parameters a and b to be visible in the output.

Problems with spaces in paths

This is a very odd issue. I have encountered it on my local windows VM while CI on appveyor does not have this issue. Same code is used in both places.

Using cppast causes application to terminate because clang executable invocation returns non-zero return code. This happens because clang include directory is passed unquoted so -IC:/Program is treated as include directory and Files/LLVM/... is treated as source file which wont be found and cause clang to fail.

I have made a workaround quoting paths that contain spaces: rbfx/rbfx@7f7423c
For some reason quoting all paths caused parsing errors in my project. Given obscurity of the issue i am not sure if this is a right fix. If its good enough - let me know and i will submit a PR. If not - please look into it whenever possible :)

Edit: just realized I quoted path so wrong. Shame on me.

Expose __attribute__ and __declspec attributes

I found myself in need of these attributes. When generating bindings it is useful to know if certain type is exported from dll or not. These attributes are used for exactly this purpose and it would be extremely handy to get info. I myself hacked a sort of working solution: rokups/Urho3DNet@50babf2. If you think it is good enough i can submit a PR. If not - this is a feature request then :)

std::atoi throws invalid argument exception

  • cppast version: master ca2fae0
  • parser: libclang_parser
  • clang version: 5.0

While parsing a header file with my libclang parser instance, an std::atoi() call throws an std::invalid_argument exception. Seems to be a regression introduced by #32 (My previous working version of cppast was master 24365e8, the issue started after updating my project submodules).

I've set up a branch of my project with the mentioned ca2fae0 cppast commit to reproduce the error, named type_safe_atoi_throws. Here's a link to the latest CI build of that branch. (The project has not been released yet, but I've added your gitlab account as a guest).

For reference, here's the same build in the master branch, which uses the cppast commit 24365e8.

Both builds are run in a docker container with an image named geordiejones/cpp14-build-machine, which provides a minimal libclang-5 ubuntu environment. The issue happens when running my tool with my example header.

Also for reference, here's the commit in the type_safe_atoi_throws branch, the difference from master:

commit 38885f6b8b98ef94176f5127d66a91e3dd659912
Author: Manuel Sanchez <[email protected]>
Date:   Wed Jan 24 09:19:40 2018 +0000

    update cppast version to ca2fae08a2c50c9759433b5abb1345fc78dcfc55

diff --git a/cppast b/cppast
index 24365e8..ca2fae0 160000
--- a/cppast
+++ b/cppast
@@ -1 +1 @@
-Subproject commit 24365e8b8288c8949e9585d0dda4b59c69d0b6b2
+Subproject commit ca2fae08a2c50c9759433b5abb1345fc78dcfc55

Unexposed expression string representation is not complete

  • cppast version: latest
  • clang version: 5.0.1

In some rare cases string representation of unexposed expression is incomplete. Happened to me exactly once, last character is missing in this case.

Input:

void SetEventFrame(float time, const StringHash& eventType, const VariantMap& eventData = VariantMap());

Output:
dynamic_cast<const cppast::cpp_unexposed_expression&>(expression).expression().as_string() returns VariantMap(.

AST for 'Scene/ValueAnimation.h':
|-../Core/Variant.h (include directive): `#include "../Core/Variant.h"`
|-../Resource/Resource.h (include directive): `#include "../Resource/Resource.h"`
+-Urho3D (namespace)
  +-ValueAnimation (class) [definition]: `class ValueAnimation;`
    |-public (access specifier): `public:`
    |-ClassName (type alias): `using ClassName=Urho3D::ValueAnimation;`
    |-BaseClassName (type alias): `using BaseClassName=Urho3D::Resource;`
    |-SetEventFrame (member function): `void SetEventFrame(float time,Urho3D::StringHash const& eventType,Urho3D::VariantMap const& eventData=VariantMap();`

wrong assert for multiple definition for redundant conversion to related types

  • cppast version: 70ac5cf
  • parser: libclang_parser
  • clang version: 4.0

Explanation of the error.
[debug assert] /home/bf/devel/asttoy/cppast/src/cpp_entity_index.cpp:25: Assertion '!value.is_definition' failed - duplicate entity registration.

Input:

#include <memory>

struct A {
  virtual ~A() = default;
};
struct B : A {};

struct M
{
  operator std::unique_ptr<B>() { return nullptr; }
  operator std::unique_ptr<A>() { return nullptr; }
};

Changing the above to raw pointers makes the problem go away.

Input flags: -std=c++14

Output of cppast -v <input>

[preprocessor] [debug] /tmp/t.cpp: parsing include 'memory'
[libclang parser] [debug] A: parsing cursor of type 'StructDecl'
[libclang parser] [debug] ~A(): parsing cursor of type 'CXXDestructor'
[libclang parser] [debug] B: parsing cursor of type 'StructDecl'
[libclang parser] [debug] M: parsing cursor of type 'StructDecl'
[libclang parser] [debug] operator unique_ptr(): parsing cursor of type 'CXXConversion'
[libclang parser] [debug] operator unique_ptr(): parsing cursor of type 'CXXConversion'
[debug assert] /home/bf/devel/asttoy/cppast/src/cpp_entity_index.cpp:25: Assertion '!value.is_definition' failed - duplicate entity registration.

Typedefs of element type in pointer/reference to array are ignored

  • cppast version: latest one
  • parser: libclang_parser
  • clang version: 3.9.1+

When having a pointer/reference to an array, the element type of the array will ignore typedefs and return the underlying type as element type instead. This is due to a libclang workaround that requires a call to clang_getCanonicalType() on the array type returned by a call to clang_getPointeeType(); otherwise clang_getElementType() won't work. But clang_getCanonicalType() strips away all typedefs, so they can't be exposed.

Input:

using foo = int;
using type = foo(&)[10];

Element type of the array will be a plain int, not foo.

Why can't read multiple attributes?

  • cppast version: last one
  • parser: libclang_parser
  • clang version: 6.0.0

Explanation of the error.

Input:

[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // declare f with four attributes.
//this is ok,but cppast only read last attribute(nodiscard)
//https://en.cppreference.com/w/cpp/language/attributes

Input flags:

Output:

Output of `cppast -v <input>`

Fast preprocessing causes file_name here to come up either <built-in> or <command line>

https://github.com/foonathan/cppast/blob/4c34587668ba9958f75bf345b8f68e48f2569c64/src/libclang/libclang_visitor.hpp#L49

Hi there,
I have been using your AST traversing tool to search codebases that I have marked up with attributes, and using those attributes to generate some code that automates the process for me to easily add classes into a scripting runtime (chaiscript).

With the most recent update to master, I was excited about the fast preprocessing option. With one of the codebases I'm loading into the AST parses just fine. The other however, I'm finding that when it is in visit_tu, there is a mismatch of the filenames which causes it to not actually visit the tu, and thus I get none of the information I need. Instead it filename comes out of clang_getPresumedLocation as "'<'built-in'>'" or "'<'command line'>'" instead of actual file names. Because of this, cppast::visit, only looks at the file object and then kicks out as if it were the only entity parsed.

With the one that parses successfully, it has to use fast_preprocessing, otherwise I get unknown token errors. With the other, it works fine if I turn fast_preprocessing off, but not if fast_preprocessing is on. This discrepancy is really confusing to me, and while I could put a flag in to turn it on or off through my command line, I still feel like I should find out what is causing the issue in the first place.

I interface with cppast as such:

cppast::libclang_compile_config config;
cppast::compile_flags flags;

config.fast_preprocessing(true);

config.set_flags(cppast::cpp_standard::cpp_14, flags);

for(auto i : includes) {
  config.add_include_dir(i); //Includes from argv
}
...
cppast::cpp_entity_index idx;
std::vector<std::unique_ptr<cppast::cpp_file>> parsed_files;
cppast::libclang_parser parser;
for(auto f : filenames) { //Filenames from a recursive tinydir search
  auto file = parser.parse(idx, f, config);
  if(parser.error()) {
    std::cout<<"There was a parser error when parsing "<<f<<std::endl;
    parser.reset_error();
  }
  else {
    parsed_files.push_back(std::move(file));
  }
}
...
for(auto& file : parsed_files) {
    cppast::visit(*file, [&](const cppast::cpp_entity& ent, cppast::visitor_info info) {
      if(info.event != cppast::visitor_info::container_entity_exit) {
        if(ent.kind() == cppast::cpp_entity_kind::namespace_t) {
          processNamespace(ent);
        }
        else if(ent.kind() == cppast::cpp_entity_kind::enum_t) {
          processEnum(ent);
        }
        else if(ent.kind() == cppast::cpp_entity_kind::class_t) {
          processModule(ent);
        }
        else if(ent.kind() == cppast::cpp_entity_kind::constructor_t) {
          processConstructor(ent);
        }
        else if(ent.kind() == cppast::cpp_entity_kind::member_function_t) {
          processMemberFunction(ent);
        }
        else if(ent.kind() == cppast::cpp_entity_kind::function_t) {
          processStaticFunction(ent);
        }
      }
      else if(info.event == cppast::visitor_info::container_entity_exit && ent.kind() == cppast::cpp_entity_kind::namespace_t) {
        if(current_namespace.find_last_of("::") == std::string::npos)
          current_namespace.clear();
        else
          current_namespace = current_namespace.substr(0, current_namespace.find_last_of("::") - 1);
      }
      return true;
    });
  }

If you need anymore information from me, let me know. :)

cmake build only the static lib

I'm trying to incorporate cppast into another project and so want only to build the static lib, no example, test, etc. when i pass -DCPPAST_BUILD_EXAMPLE=OFF -DCPPAST_BUILD_TEST=OFF -DCPPAST_BUILD_TOOL=OFF to the cmake command it still builds example, test, etc.

I'm not a cmake expert but i think i tracked it down to this statement in CMakeLists.txt:

if(${CPPAST_BUILD_EXAMPLE} OR (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR))

(on line 29).

from the cmake docs:

CMAKE_CURRENT_SOURCE_DIR
this is the directory where the currently processed CMakeLists.txt is located in

CMAKE_SOURCE_DIR
this is the directory which contains the top-level CMakeLists.txt, i.e. the top level source directory

so this will always be true the way i configure:

cd cppast
mkdir build
cmake ..

perhaps i'm configuring incorrectly but i thought this was the accepted cmake way.

thanks

Parsing function bodies

I've run the example and it fits exactly what I'm looking for, the only problem I have is that function bodies aren't parsed. Do you have a roadmap of when this might be implemented? Cheers.

Integer promotion issue in 32 bit builds

It seems that std::size_t is not unsigned long long in 32 bit builds. I would change the hash type to std::uin64_t or unsigned long long.

/home/conan/build/cppast-src/src/../include/cppast/cpp_entity_index.hpp:26:43: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
         constexpr std::size_t fnv_basis = 14695981039346656037ull;       
                                           ^                       
/home/conan/build/cppast-src/src/../include/cppast/cpp_entity_index.hpp:27:43: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
         constexpr std::size_t fnv_prime = 1099511628211ull; 

How to selectively parse a header file

I want to parse a header file and run through the AST. I'm using the Tool code as a base.
My code layout is like this:

// MyCppFile.cpp
#include "DataXYZ.h"
#include "MyHeader.h" // makes use of things in DataXYZ.h

If I parse just MyHeader.h, it cannot see DataXYZ, (as expected), and so there are unknown types. So I want to parse MyCppFile.cpp, run through the AST and only pay attention to the entries once I hit MyHeader.h

I thought I could achieve this by parsing MyCppFile.cpp, then visiting the AST until I get to the relevant include_directive_t and then parsing everything inside that, but the AST does not seem to include anything outside of the original source file.

I've tried a few other approaches too, with no luck, and I feel like I'm missing something simple.
Can you clarify how I should be approaching this please?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.