API

Parsing

Simplify the parsing of C/C++ using libclang. This module specifically supports the use case of single translation units where it isn’t important that symbols from other translation units would be visible.

parse(name, **kwargs) Parse a C/C++ file
parse_string(contents[, name]) Parse a string of C/C++ code

Traversal

Traverse the libclang generate AST using semantics similar to the python ast module.

walk(predicate, cursor) Yield all nodes found by recursively visiting the AST
iter_child_nodes(predicate, cursor) Yield all direct child nodes of node

AST Pretty Printing

Display the libclang AST, or a filtered subset of

dump(cursor) Display the AST represented by the cursor

Matchers

Code that implements Abstract Syntax Tree node matchers, or allow

allOf(*args) Matches if all of the argument matchers match
anyOf(*args) Matches if any of the argument matchers match
anything() Matches anything
builtinType(*args) Matches builtin primitive types (eg/ integers, booleans and float)
classTemplateDecl(*args) Match C++ template class declarations
cxxConstructorDecl(*args) Match C++ constructors
cxxDestructorDecl(*args) Match C++ destructors
cxxMethodDecl(*args) Match C++ methods
cxxRecordDecl(*args) Matches C++ class declarations.
decl(*args) Match any declaration
enumDecl(*args) Match enumerations
fieldDecl(*args) Match struct / class fields
functionDecl(*args) Match function declarations
has(*args) Match if a cursor has a child that matches
hasAncestor(matcher) Matches if the current cursor has an ancestor that matches
hasAnyParameter(matcher) Match if any method or function argument matches
hasCanonicalType(m) Matches if a cursor has the specified number of arguments
hasName(name) Match a cursors spelling against a pattern
hasParameter(N, inner) Matches if the N-th parameter matches the inner matcher
hasParent(*args) Matches if the direct parent node matches
hasReturnType(matcher) Match a function/method with a specified return type
hasStaticStorageDuration() Match an item has static storage duration
hasType(matcher) Matches if the type associated with the current cursor matches
hasTypename(typename) Match if the spelling of the type of a cursor matches a pattern
isClass() Matches if a cursor is a class
isDefinition() Matches if the cursor is a definition
isDerivedFrom(name) Match if a C++ type inherits from a named class
isExpansionInFileMatching(pattern) Matches if the nodes location matches a pattern
isPrivate() Test if a cursor is private
isProtected() Test if a cursor is protected
isPublic() Test if a cursor is public
isSameOrDerivedFrom(name) Match if derives-from (or is-a) class with a given name
isStruct() Matches if a cursor is a struct
namespaceDecl(*args) Match a C++ namespace declaration
parameterCountIs(N) Matches if a cursor has the specified number of arguments
pointee(inner) Traverse from a pointer to the dereferenced type
pointerType(*args) Test if a cursor has pointer type
recordDecl(*args) Matches class, struct, and union declarations.
stmt(*args) Matches statements
typedefDecl(*args) Matches typedef declarations
unless(*args) Inverts the match of the children
varDecl(*args) Matches variable declarations

Definitions

exception glud.parsing.ClangDiagnosticException(diagnostic)[source]

Encapsulates Clang diagnostics as an exception

glud.parsing.parse_string(contents, name='tmp.cpp', **kwargs)[source]

Parse a string of C/C++ code

glud.parsing.parse(name, **kwargs)[source]

Parse a C/C++ file

glud.traversal.iter_child_nodes(predicate, cursor)[source]

Yield all direct child nodes of node

glud.traversal.walk(predicate, cursor)[source]

Yield all nodes found by recursively visiting the AST

glud.display.dump(cursor)[source]

Display the AST represented by the cursor

glud.matchers.allOf(*args)[source]

Matches if all of the argument matchers match

>>> from glud import *
>>> config = '''
...  class X;
...  class Y;
... '''
>>> m = allOf(cxxRecordDecl(), hasName('X'))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.anyOf(*args)[source]

Matches if any of the argument matchers match

>>> from glud import *
>>> config = '''
...  int x;
...  class Y {};
...  enum Z {};
... '''
>>> m = anyOf(varDecl(), isClass())
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
x
Y
glud.matchers.hasType(matcher)[source]

Matches if the type associated with the current cursor matches

>>> from glud import *
>>> config = '''
...  int x;
...  long y;
... '''
>>> m = varDecl(hasType(hasName('int')))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
x
glud.matchers.anything()[source]

Matches anything

>>> from glud import *
>>> config = '''
... namespace W {
...  int x;
...  class Y;
...  enum Z {};
... }
... '''
>>> m = allOf(anything(), hasParent(namespaceDecl()))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
x
Y
Z
glud.matchers.hasAnyParameter(matcher)[source]

Match if any method or function argument matches

>>> from glud import *
>>> config = '''
... void f();
... void g(int);
... '''
>>> m = functionDecl(hasAnyParameter(hasType(builtinType())))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
g
glud.matchers.builtinType(*args)[source]

Matches builtin primitive types (eg/ integers, booleans and float)

>>> from glud import *
>>> config = '''
...  int x;
...  bool y;
... '''
>>> m = varDecl(hasType(builtinType()))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
x
y
glud.matchers.classTemplateDecl(*args)[source]

Match C++ template class declarations

>>> from glud import *
>>> config = '''
...  template<typename T> class X {};
...  class Y {};
... '''
>>> m = classTemplateDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.cxxRecordDecl(*args)[source]

Matches C++ class declarations.

>>> from glud import *
>>> config = '''
...  class W;
...  template<typename T> class X {};
...  struct Y {};
...  union Z {};
... '''
>>> m = cxxRecordDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
W
X
glud.matchers.cxxConstructorDecl(*args)[source]

Match C++ constructors

>>> from glud import *
>>> config = '''
...  class X {
...    X();
...  };
...  class Y {};
... '''
>>> m = cxxConstructorDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.cxxDestructorDecl(*args)[source]

Match C++ destructors

>>> from glud import *
>>> config = '''
...  class X {
...    ~X();
...  };
...  class Y {};
... '''
>>> m = cxxDestructorDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
~X
glud.matchers.cxxMethodDecl(*args)[source]

Match C++ methods

>>> from glud import *
>>> config = '''
...  class X {
...    void u();
...    void v();
...  };
... '''
>>> m = cxxMethodDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
u
v
glud.matchers.decl(*args)[source]

Match any declaration

>>> from glud import *
>>> config = '''
...  class X {};
...  struct Y {};
...  enum Z {};
... '''
>>> m = decl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
Y
Z
glud.matchers.enumDecl(*args)[source]

Match enumerations

>>> from glud import *
>>> config = '''
...  enum X {};
...  enum class Y {};
... '''
>>> m = enumDecl()
>>> args = '-x c++ -std=c++11'.split()
>>> for c in walk(m, parse_string(config, args=args).cursor):
...     print(c.spelling)
X
Y
glud.matchers.fieldDecl(*args)[source]

Match struct / class fields

>>> from glud import *
>>> config = '''
...  struct X {
...   int u;
...   int v;
...  };
... '''
>>> m = fieldDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
u
v
glud.matchers.functionDecl(*args)[source]

Match function declarations

>>> from glud import *
>>> config = '''
...  int u();
...  int v();
... '''
>>> m = functionDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
u
v
glud.matchers.has(*args)[source]

Match if a cursor has a child that matches

>>> from glud import *
>>> config = '''
...  class X {
...   void f();
...  };
...  class Y;
... '''
>>> m = cxxRecordDecl(has(cxxMethodDecl()))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.hasName(name)[source]

Match a cursors spelling against a pattern

>>> from glud import *
>>> config = '''
...  class X {};
...  class Y {};
... '''
>>> m = cxxRecordDecl(hasName('X'))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.hasReturnType(matcher)[source]

Match a function/method with a specified return type

>>> from glud import *
>>> config = '''
... class X {};
... X u();
... int v();
... '''
>>> m = functionDecl(hasReturnType(builtinType()))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
v
glud.matchers.hasStaticStorageDuration()[source]

Match an item has static storage duration

>>> from glud import *
>>> config = '''
... class X {
...  static void u();
...  void v();
... };
... '''
>>> m = cxxMethodDecl(
...         hasStaticStorageDuration())
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
u
glud.matchers.hasTypename(typename)[source]

Match if the spelling of the type of a cursor matches a pattern

>>> from glud import *
>>> config = '''
... namespace X {
...  class Y {};
... }
... class Y {};
... '''
>>> m = cxxRecordDecl(hasTypename('X::Y'))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.type.spelling)
X::Y
glud.matchers.isDerivedFrom(name)[source]

Match if a C++ type inherits from a named class

>>> from glud import *
>>> config = '''
... class X {};
... class Y : public X {};
... class Z : public Y {};
... '''
>>> m = cxxRecordDecl(isDerivedFrom('X'))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
Y
Z
glud.matchers.isSameOrDerivedFrom(name)[source]

Match if derives-from (or is-a) class with a given name

>>> from glud import *
>>> config = '''
... class X {};
... class Y : public X {};
... class Z : public Y {};
... '''
>>> m = cxxRecordDecl(isSameOrDerivedFrom('X'))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
Y
Z
glud.matchers.namespaceDecl(*args)[source]

Match a C++ namespace declaration

>>> from glud import *
>>> config = '''
... namespace X { }
... '''
>>> m = namespaceDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.recordDecl(*args)[source]

Matches class, struct, and union declarations.

>>> from glud import *
>>> config = '''
...  class W;
...  template<typename T> class X {};
...  struct Y {};
...  union Z {};
... '''
>>> m = recordDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
W
X
Y
Z
glud.matchers.stmt(*args)[source]

Matches statements

>>> from glud import *
>>> config = '''
... void f() { }
... '''
>>> m = stmt()
>>> i = 0
>>> for c in parse_string(config).cursor.walk_preorder():
...     if m(c):
...         i += 1
>>> print(i)
1
glud.matchers.typedefDecl(*args)[source]

Matches typedef declarations

>>> from glud import *
>>> config = '''
... typedef int X;
... '''
>>> m = typedefDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.unless(*args)[source]

Inverts the match of the children

>>> from glud import *
>>> config = '''
... class X { };
... class Y {};
... class Z {};
... '''
>>> m = cxxRecordDecl(unless(hasName('Y')))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
Z
glud.matchers.isDefinition()[source]

Matches if the cursor is a definition

>>> from glud import *
>>> config = '''
... class X {};
... class Y;
... '''
>>> m = cxxRecordDecl(isDefinition())
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.hasAncestor(matcher)[source]

Matches if the current cursor has an ancestor that matches

>>> from glud import *
>>> config = '''
... namespace X {
...   class Y {};
... }
... class Z {};
... '''
>>> m = cxxRecordDecl(
...         hasName('Y'),
...         hasAncestor(namespaceDecl(hasName('X'))))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
Y
glud.matchers.isExpansionInFileMatching(pattern)[source]

Matches if the nodes location matches a pattern

>>> from glud import *
>>> config = '''
... class X;
... '''
>>> m = isExpansionInFileMatching('tmp.cpp')
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.varDecl(*args)[source]

Matches variable declarations

>>> from glud import *
>>> config = '''
...  int a;
... '''
>>> m = varDecl()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
a
glud.matchers.hasParent(*args)[source]

Matches if the direct parent node matches

>>> from glud import *
>>> config = '''
... namespace X {
...   int a;
... }
... int b;
... '''
>>> m = varDecl(hasParent(namespaceDecl(hasName('X'))))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
a
glud.matchers.parameterCountIs(N)[source]

Matches if a cursor has the specified number of arguments

>>> from glud import *
>>> config = '''
...  int f();
...  int g(int);
...  int h(int, int);
... '''
>>> m = functionDecl(parameterCountIs(1))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
g
glud.matchers.hasCanonicalType(m)[source]

Matches if a cursor has the specified number of arguments

>>> from glud import *
>>> config = '''
...  namespace X {
...   struct Y;
...   Y f();
...  }
... '''
>>> m = functionDecl(hasReturnType(hasCanonicalType(hasName('X::Y'))))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
f
glud.matchers.isStruct()[source]

Matches if a cursor is a struct

>>> from glud import *
>>> config = '''
...  class X;
...  struct Y;
... '''
>>> m = isStruct()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
Y
glud.matchers.isClass()[source]

Matches if a cursor is a class

>>> from glud import *
>>> config = '''
...  class X;
...  struct Y;
... '''
>>> m = isClass()
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
X
glud.matchers.isPublic()[source]

Test if a cursor is public

>>> from glud import *
>>> config = '''
...  class X {
...   public:
...    int y;
...  };
... '''
>>> m = fieldDecl(isPublic())
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
y
glud.matchers.isProtected()[source]

Test if a cursor is protected

>>> from glud import *
>>> config = '''
...  class X {
...   protected:
...    int y;
...  };
... '''
>>> m = fieldDecl(isProtected())
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
y
glud.matchers.isPrivate()[source]

Test if a cursor is private

>>> from glud import *
>>> config = '''
...  class X {
...   private:
...    int y;
...  };
... '''
>>> m = fieldDecl(isPrivate())
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
y
glud.matchers.pointerType(*args)[source]

Test if a cursor has pointer type

>>> from glud import *
>>> config = '''
...  int w;
...  int* x;
...  int** y;
...  int& z = w;
... '''
>>> m = varDecl(hasType(pointerType()))
>>> for c in parse_string(config, args='-x c++ -std=c++11'.split()).cursor.walk_preorder():
...     if m(c):
...         print(c.spelling)
x
y
glud.matchers.pointee(inner)[source]

Traverse from a pointer to the dereferenced type

>>> from glud import *
>>> config = '''
...  int *x;
...  void *y;
... '''
>>> m = varDecl(hasType(pointerType(pointee(hasName('int')))))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
x
glud.matchers.hasParameter(N, inner)[source]

Matches if the N-th parameter matches the inner matcher

>>> from glud import *
>>> config = '''
... void f(int x);
... void g(int y, int x);
... void h();
... '''
>>> m = functionDecl(hasParameter(1, hasName('x')))
>>> for c in walk(m, parse_string(config).cursor):
...     print(c.spelling)
g

Internal API

Internal implementation details that may be useful for building new matchers, or understanding the behavior of existing matchers. Nothing in this section is guaranteed to remain stable between releases.

glud.predicates.has_access(access)[source]

Test if a cursor has a access specifier

glud.predicates.has_storage_class(kind)[source]

Check if the cursor has a particular (eg/ static) storage class

glud.predicates.is_builtin(n)[source]

Test if a type is a simple types (integer, boolean, char, float)

glud.predicates.is_decl(c)[source]

Check if a cursor is a declaration

glud.predicates.is_definition(cursor)[source]

Test if a cursor refers to a definition

This occurs when the cursor has a definition, and shares the location of that definiton

glud.predicates.is_kind(kind)[source]

Test if a cursor or type is of a particular kind

glud.predicates.is_stmt(c)[source]

Check if a cursor is a statement

class glud.internal.Matcher[source]

Base class for matchers

class glud.internal.TrueMatcher[source]

Matcher that always returns true

class glud.internal.PredMatcher(pred)[source]
class glud.internal.UnlessMatcher(innerMatcher)[source]

Inverts the match of the children

class glud.internal.AllOfMatcher(*innerMatchers)[source]

Matches if all inner matchers match

matchNode(cursor)[source]
class glud.internal.AllOfTypeMatcher(*args)[source]
class glud.internal.AnyOfMatcher(*args)[source]

Matches if any of the inner matchers match

matchNode(cursor)[source]
class glud.internal.ChildAnyOfMatcher(*args)[source]
children(cursor)[source]
class glud.internal.AnyBaseClassMatcher(*args)[source]
traverse(cursor)[source]
class glud.internal.NameMatcher(pattern)[source]
name(cursor)[source]
class glud.internal.TypenameMatcher(pattern)[source]
name(cursor)[source]
class glud.internal.TypeTraversalMatcher(innerMatcher)[source]
traverse(cursor)[source]
class glud.internal.ReturnTypeTraversalMatcher(matcher)[source]
traverse(cursor)[source]
class glud.internal.AnyParameterMatcher(innerMatcher)[source]
matchNode(cursor)[source]
traverse(cursor)[source]
class glud.internal.AncestorMatcher(innerMatcher)[source]
matchNode(cursor)[source]
traverse(cursor)[source]
class glud.internal.LocationMatcher(pattern)[source]
class glud.internal.ParentMatcher(innerMatcher)[source]
matchNode(cursor)[source]
traverse(cursor)[source]
class glud.internal.ParameterMatcher(N, innerMatcher)[source]
matchNode(cursor)[source]
class glud.internal.ParameterCountMatcher(N)[source]
class glud.internal.CanonicalTypeTraversalMatcher(matcher)[source]
traverse(t)[source]
class glud.internal.PointeeTypeTraversalMatcher(innerMatcher)[source]
traverse(t)[source]