Clang

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Clang

0.09      2015-06-20 18:48:51+02:00 Europe/Rome

 - Add methods to determine whether a cursor represents a virtual method
   or a pure virtual method (GH#5) (thanks, @ArthurJahn!)
 - Add method to get a cursor's number of arguments (GH#5)
   (thanks, @Ziul, @LucianoAlmeida!)

0.08      2015-05-26 14:00:26+02:00 Europe/Rome

 - Return cursor's final line and column from Cursor -> location()
   (GH#3) (thanks, @gutorc92!)
 - Add method to retrieve cursor's access specifier (GH#4)
   (thanks, @gutorc92 and @lucasmoura!)

0.07      2015-04-23 20:09:52+02:00 Europe/Rome

 - Build with libclang v3.5 (GH#2) (thanks, @ArthurJahn!)
 - Do not suggest perl version in the example
 - Various test fixes

0.06      2012-08-20 13:20:25 Europe/Rome

Clang.xs  view on Meta::CPAN

#include <clang-c/Index.h>

typedef CXIndex			Index;
typedef CXTranslationUnit	TUnit;
typedef CXCursor *		Cursor;
typedef enum CXCursorKind	CursorKind;
typedef CXType *		Type;
typedef enum CXTypeKind		TypeKind;
typedef CXDiagnostic		Diagnostic;

enum CXChildVisitResult visitor(CXCursor cursor, CXCursor parent, CXClientData data) {
	SV *child;
	AV *children = data;

	CXCursor *ref = malloc(sizeof(CXCursor));
	*ref = cursor;

	child = sv_setref_pv(newSV(0), "Clang::Cursor", (void *) ref);

	av_push(children, child);

	return CXChildVisit_Continue;
}

MODULE = Clang				PACKAGE = Clang

MANIFEST  view on Meta::CPAN

lib/Clang.pm
lib/Clang/Cursor.pm
lib/Clang/CursorKind.pm
lib/Clang/Diagnostic.pm
lib/Clang/Index.pm
lib/Clang/TUnit.pm
lib/Clang/Type.pm
lib/Clang/TypeKind.pm
t/00-compile.t
t/01-tunit.t
t/02-cursor.t
t/03-cursorkind.t
t/05-typekind.t
t/06-diagnostic.t
t/fragments/animal.h
t/fragments/cat.cc
t/fragments/cat.h
t/fragments/main.cpp
t/fragments/mammal.h
t/fragments/person.cpp
t/fragments/person.h
t/fragments/test.c

README.pod  view on Meta::CPAN


Clang - Perl bindings to the Clang compiler's indexing interface

=head1 SYNOPSIS

    use Clang;

    my $index = Clang::Index -> new(1);

    my $tunit = $index -> parse('file.c');
    my $nodes = $tunit -> cursor -> children;

    foreach my $node (@$nodes) {
        say $node -> spelling;
        say $node -> kind -> spelling;
    }

=head1 DESCRIPTION

Clang is a compiler front end for the C, C++, Objective-C, and Objective-C++
programming languages which uses LLVM as its back end.

lib/Clang.pm  view on Meta::CPAN


version 0.09

=head1 SYNOPSIS

    use Clang;

    my $index = Clang::Index -> new(1);

    my $tunit = $index -> parse('file.c');
    my $nodes = $tunit -> cursor -> children;

    foreach my $node (@$nodes) {
        say $node -> spelling;
        say $node -> kind -> spelling;
    }

=head1 DESCRIPTION

Clang is a compiler front end for the C, C++, Objective-C, and Objective-C++
programming languages which uses LLVM as its back end.

lib/Clang/Cursor.pm  view on Meta::CPAN

package Clang::Cursor;
$Clang::Cursor::VERSION = '0.09';
use strict;
use warnings;

=head1 NAME

Clang::Cursor - Clang cursor class

=head1 VERSION

version 0.09

=head1 DESCRIPTION

A C<Clang::Cursor> represents an element in the abstract syntax tree of a
translation unit.

=head1 METHODS

=head2 kind( )

Retrieve the L<Clang::CursorKind> of the given cursor.

=head2 type( )

Retrieve the L<Clang::Type> of the entity referenced by the given cursor.

=head2 spelling( )

Retrieve the name for the entity referenced by the given cursor.

=head2 num_arguments( )

Retrieve the number of arguments referenced by the given cursor.

=head2 displayname( )

Return the display name for the entity referenced by the given cursor.

=head2 children( )

Retrieve a list of the children of the given cursor. The children are
C<Clang::Cursor> objects too.

=head2 is_pure_virtual( )

Determine whether the given cursor kind represents a pure virtual method.

=head2 is_virtual( )

Determine whether the given cursor kind represents a virtual method.

=head2 location( )

Retrieve the location of the given cursor. This function returns five values: a
string containing the source file name, an integer containing the initial line
number, an integer containing the initial column number, an integer containing
the final line number, and another integer containing the final column number.

=head2 access_specifier( )

Retrieve the access of the given cursor. This can return the following values:
C<invalid>, C<public>, C<protected> or C<private>. Note that this only works
for C++ code, it will return C<invalid> for C functions.

=head1 AUTHOR

Alessandro Ghedini <alexbio@cpan.org>

=head1 LICENSE AND COPYRIGHT

Copyright 2012 Alessandro Ghedini.

lib/Clang/CursorKind.pm  view on Meta::CPAN

package Clang::CursorKind;
$Clang::CursorKind::VERSION = '0.09';
use strict;
use warnings;

=head1 NAME

Clang::CursorKind - Clang cursor kind class

=head1 VERSION

version 0.09

=head1 DESCRIPTION

A C<Clang::CursorKind> describes the kind of entity that a cursor refers to.

=head1 METHODS

=head2 spelling( )

Retrieve the name of the given cursor kind.

=head2 is_declaration( )

Determine whether the given cursor kind represents a declaration.

=head2 is_reference( )

Determine whether the given cursor kind represents a reference.

=head2 is_expression( )

Determine whether the given cursor kind represents an expression.

=head2 is_statement( )

Determine whether the given cursor kind represents a statement.

=head2 is_attribute( )

Determine whether the given cursor kind represents an attribute.

=head2 is_invalid( )

Determine whether the given cursor kind represents an invalid cursor.

=head2 is_tunit( )

Determine whether the given cursor kind represents a translation unit.

=head2 is_preprocessing( )

Determine whether the given cursor kind represents a preprocessing element.

=head2 is_unexposed( )

Determine whether the given cursor kind represents an unexposed piece of the
AST.

=head1 AUTHOR

Alessandro Ghedini <alexbio@cpan.org>

=head1 LICENSE AND COPYRIGHT

Copyright 2012 Alessandro Ghedini.

lib/Clang/TUnit.pm  view on Meta::CPAN

=head1 VERSION

version 0.09

=head1 DESCRIPTION

A C<Clang::TUnit> represents a single translation unit which resides in an index.

=head1 METHODS

=head2 cursor( )

Retrieve the L<Clang::Cursor> corresponding to the given translation unit.

=head2 spelling( )

Retrieve the original translation unit source file name.

=head2 diagnostics( )

Retrieve the L<Clang::Diagnostic>s associated with the given C<Clang::TUnit>.

t/02-cursor.t  view on Meta::CPAN

#!perl -T

use Test::More;

use Clang;

my $index = Clang::Index -> new(0);
my $tunit = $index -> parse('t/fragments/test.c');
my $cursr = $tunit -> cursor;

is($cursr -> spelling, 't/fragments/test.c');
is($cursr -> displayname, 't/fragments/test.c');

my $cursors = $cursr -> children;

my @spellings = map { $_ -> spelling } @$cursors;
my @expected  = qw(
	foo
	main
);

is_deeply(\@spellings, \@expected);

my ($file, $line, $column) = $cursr -> location;
is($file, ''); is($line, 0); is($column, 0);

my @locations = map { join ' ', $_ -> location } @$cursors;
@expected     = (
	't/fragments/test.c 1 6 5 2',
	't/fragments/test.c 7 5 11 2'
);
is_deeply(\@locations, \@expected);

$index = Clang::Index -> new(0);
$tunit = $index -> parse('t/fragments/main.cpp');
$cursr = $tunit -> cursor;

#Testing of method spelling
is($cursr -> spelling, 't/fragments/main.cpp');

#Testing of method num_arguments

my $num_arguments = 0;
_visit_node_arguments($cursr);

sub _visit_node_arguments {

t/02-cursor.t  view on Meta::CPAN

	my $children = $node->children;
	foreach my $child(@$children) {
		_visit_node_arguments($child);
	}
}
is($num_arguments, 2);

#Testing of method displayname
is($cursr -> displayname, 't/fragments/main.cpp');

$cursors = $cursr -> children;

@spellings = map { $_ -> spelling } @$cursors;
@expected  = qw(
	Person
	main
);

is_deeply(\@spellings, \@expected);

($file, $line, $column) = $cursr -> location;
is($file, ''); is($line, 0); is($column, 0);

@locations = map { join ' ', $_ -> location } @$cursors;
@expected     = (
	't/fragments/person.h 4 7 13 2',
	't/fragments/main.cpp 3 5 5 2'
);
is_deeply(\@locations, \@expected);

$cursors = @$cursors[0] -> children;

@access = map { join ' ', $_ -> access_specifier } @$cursors;
@expected = (
		'public',
		'public',
		'public',
		'public',
		'private',
		'private',
		'private'
);
is_deeply(\@access,\@expected);

#Testing if a method is pure virtual or not

$index = Clang::Index -> new(0);
$tunit = $index -> parse('t/fragments/cat.cc');
$cursr = $tunit -> cursor;
$kind = $cursr -> kind;
$cursors = $cursr -> children;

my $check_pure_virtual = 'false';
my $pure_virtual_name = 'undef';

_visit_node($cursr);

sub _visit_node {
	my $node = shift;
	if($node->is_pure_virtual){
		$pure_virtual_name = $node->spelling;

t/02-cursor.t  view on Meta::CPAN

		_visit_node($child);
	}
}
is($check_pure_virtual,'true');
is($pure_virtual_name,'name');

#Testing if a method is virtual or not

$index = Clang::Index -> new(0);
$tunit = $index -> parse('t/fragments/cat.cc');
$cursr = $tunit -> cursor;
$kind = $cursr -> kind;
$cursors = $cursr -> children;

my $check_virtual = 'false';
my $virtual_name = 'undef';

_visit_node_virtual($cursr);

sub _visit_node_virtual {
	my $node = shift;
	if($node->is_virtual){
		$virtual_name = $node->spelling;

t/02-cursor.t  view on Meta::CPAN

	}
	my $children = $node->children;
	foreach my $child(@$children) {
		_visit_node_virtual($child);
	}
}
is($check_virtual,'true');
is($virtual_name,'name');

$tunit = $index -> parse('t/fragments/main.cpp');
$cursr = $tunit -> cursor;
my $method_num_arguments = -4;
_visit_node_method_arguments($cursr);

sub _visit_node_method_arguments {
	my $node = shift;
	if($node->kind->spelling() eq "CXXMethod"){
		if ($node->spelling() eq "walk"){
				$method_num_arguments = $node->num_arguments;
				is($method_num_arguments, 2);
			}

t/02-cursor.t  view on Meta::CPAN

			is($method_num_arguments, 0);
		}
	}
	my $children = $node->children;
	foreach my $child(@$children) {
		_visit_node_method_arguments($child);
	}
}

$tunit = $index -> parse('t/fragments/test.c');
$cursr = $tunit -> cursor;
my $function_num_arguments = -5;
_visit_node_method_arguments($cursr);

sub _visit_node_method_arguments {
	my $node = shift;
	if($node->kind->spelling() eq "FunctionDecl"){
		if ($node->spelling() eq "foo"){
				$method_num_arguments = $node->num_arguments;
				is($method_num_arguments, 1);
			}

t/03-cursorkind.t  view on Meta::CPAN

#!perl -T

use Test::More;

use Clang;

my $index = Clang::Index -> new(0);
my $tunit = $index -> parse('t/fragments/test.c');
my $cursr = $tunit -> cursor;
my $kind  = $cursr -> kind;

is($kind -> spelling, 'TranslationUnit');

my $cursors = $cursr -> children;

my @spellings = map { $_ -> kind -> spelling } @$cursors;
my @expected  = qw(
	FunctionDecl
	FunctionDecl
);
is_deeply(\@spellings, \@expected);

done_testing;

t/05-typekind.t  view on Meta::CPAN

#!perl -T

use Test::More;

use Clang;

my $index = Clang::Index -> new(0);
my $tunit = $index -> parse('t/fragments/test.c');
my $cursr = $tunit -> cursor;

is($cursr -> type -> kind -> spelling, 'Invalid');

my $cursors = $cursr -> children;

my @spellings = map { $_ -> type -> kind -> spelling } @$cursors;
my @expected  = qw(
	FunctionProto
	FunctionProto
);

is_deeply(\@spellings, \@expected);

done_testing;

t/06-diagnostic.t  view on Meta::CPAN

#!perl -T

use Test::More;

use Clang;

my $index = Clang::Index -> new(0);
my $tunit = $index -> parse('t/fragments/test.c');
my $cursr = $tunit -> cursor;

my $diags = $tunit -> diagnostics;

my @formats  = map { $_ -> format(1) } @$diags;
my @expected = (
	"t/fragments/test.c:2:10: error: use of undeclared identifier 'argp'",
	"t/fragments/test.c:4:2: error: void function 'foo' should not return a value",
	"t/fragments/test.c:8:6: error: initializing 'int' with an expression of incompatible type 'void'"
);

xs/TUnit.xs  view on Meta::CPAN

MODULE = Clang				PACKAGE = Clang::TUnit

Cursor
cursor(self)
	TUnit self

	CODE:
		Cursor retval = malloc(sizeof(CXCursor));
		CXCursor cursor = clang_getTranslationUnitCursor(self);
		*retval = cursor;
		RETVAL = retval;

	OUTPUT: RETVAL

SV *
spelling(self)
	TUnit self

	CODE:
		CXString spelling = clang_getTranslationUnitSpelling(self);

xs/Type.xs  view on Meta::CPAN

MODULE = Clang				PACKAGE = Clang::Type

Cursor
declaration(self)
	Type self

	CODE:
		Cursor retval = malloc(sizeof(CXCursor));
		CXCursor cursor  = clang_getTypeDeclaration(*self);
		*retval = cursor;

		RETVAL = retval;

	OUTPUT: RETVAL

TypeKind
kind(self)
	Type self

	CODE:



( run in 0.562 second using v1.01-cache-2.11-cpan-4d50c553e7e )