summaryrefslogtreecommitdiff
path: root/clang-plugin
diff options
context:
space:
mode:
authorPhilip Withnall <philip.withnall@collabora.co.uk>2013-12-10 12:57:38 +0000
committerPhilip Withnall <philip.withnall@collabora.co.uk>2013-12-10 12:57:38 +0000
commit20b5d8dafea938955dfbc22c68cce61726df3cc1 (patch)
tree8023da0d028d6760de68b7b2ff22ab1bf3b1a43a /clang-plugin
parent8f8d2944fae776d08681e036fa0de55e28708089 (diff)
clang-plugin: Factor out GIR repository management
It will be used by several different plugins, so needs to be factored out into a shared object.
Diffstat (limited to 'clang-plugin')
-rw-r--r--clang-plugin/gir-attributes.cpp81
-rw-r--r--clang-plugin/gir-attributes.h23
-rw-r--r--clang-plugin/gir-manager.cpp108
-rw-r--r--clang-plugin/gir-manager.h52
-rw-r--r--clang-plugin/plugin.cpp8
5 files changed, 174 insertions, 98 deletions
diff --git a/clang-plugin/gir-attributes.cpp b/clang-plugin/gir-attributes.cpp
index de97306..3f590f2 100644
--- a/clang-plugin/gir-attributes.cpp
+++ b/clang-plugin/gir-attributes.cpp
@@ -28,47 +28,6 @@
#include "debug.h"
#include "gir-attributes.h"
-GirAttributesConsumer::GirAttributesConsumer ()
-{
- this->_repo = g_irepository_get_default ();
-}
-
-GirAttributesConsumer::~GirAttributesConsumer ()
-{
- /* Nothing to see here. */
-}
-
-void
-GirAttributesConsumer::load_namespace (std::string& gi_namespace,
- std::string& gi_version, GError **error)
-{
- /* Load the GIR typelib. */
- GITypelib* typelib = g_irepository_require (this->_repo,
- gi_namespace.c_str (),
- gi_version.c_str (),
- (GIRepositoryLoadFlags) 0,
- error);
-
- if (typelib == NULL)
- return;
-
- /* Get the C prefix from the repository and convert it to lower case. */
- const char *c_prefix =
- g_irepository_get_c_prefix (this->_repo,
- gi_namespace.c_str ());
-
- Nspace r = Nspace ();
- r.nspace = gi_namespace;
- r.version = gi_version;
- r.c_prefix = std::string (c_prefix);
- r.typelib = typelib;
-
- std::transform (r.c_prefix.begin (), r.c_prefix.end (),
- r.c_prefix.begin (), ::tolower);
-
- this->_typelibs.push_back (r);
-}
-
/* Determine whether a type should be const, given its (transfer) annotation and
* base type. */
static bool
@@ -143,41 +102,8 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func)
return;
/* Try to find typelib information about the function. */
- GIBaseInfo *info = NULL;
- std::string func_name = func.getNameAsString (); /* TODO: expensive? */
- std::string func_name_stripped;
-
- for (std::vector<Nspace>::const_iterator it = this->_typelibs.begin ();
- it != this->_typelibs.end (); ++it) {
- Nspace r = *it;
-
- DEBUG ("Looking for function " << func_name <<
- " in repository " << r.nspace << " (version " <<
- r.version << ", C prefix ‘" << r.c_prefix << "’).");
-
- /* The func_name includes the namespace, which needs stripping.
- * e.g. g_irepository_find_by_name → find_by_name. */
- if (func_name.compare (0, r.c_prefix.size (),
- r.c_prefix) == 0) {
- size_t prefix_len =
- r.c_prefix.size () + 1 /* underscore */;
- func_name_stripped = func_name.substr (prefix_len);
- } else {
- DEBUG ("\tDoesn’t match C prefix ‘" << r.c_prefix <<
- "’.");
- continue;
- }
-
- info = g_irepository_find_by_name (this->_repo,
- r.nspace.c_str (),
- func_name_stripped.c_str ());
-
- if (info != NULL) {
- /* Successfully found an entry in the typelib. */
- DEBUG ("Found info!");
- break;
- }
- }
+ const std::string func_name = func.getNameAsString (); /* TODO: expensive? */
+ GIBaseInfo *info = this->_gir_manager.find_function_info (func_name);
if (info == NULL)
return;
@@ -309,8 +235,7 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func)
llvm::errs () << "Error: Unhandled GI type " <<
g_base_info_get_type (info) <<
" in introspection info for function ‘" <<
- func_name << "’ (" << func_name_stripped <<
- ").\n";
+ func_name << "’.\n";
}
g_base_info_unref (info);
diff --git a/clang-plugin/gir-attributes.h b/clang-plugin/gir-attributes.h
index e12165e..2b242e6 100644
--- a/clang-plugin/gir-attributes.h
+++ b/clang-plugin/gir-attributes.h
@@ -28,30 +28,19 @@
#include <girepository.h>
+#include "gir-manager.h"
+
using namespace clang;
class GirAttributesConsumer : public ASTConsumer {
-private:
- struct Nspace {
- /* All non-NULL. */
- std::string nspace;
- std::string version;
- std::string c_prefix;
-
- GITypelib* typelib; /* unowned */
- };
-
- GIRepository* _repo; /* unowned */
- std::vector<Nspace> _typelibs;
public:
- GirAttributesConsumer ();
- ~GirAttributesConsumer ();
-
- void load_namespace (std::string& gi_namespace, std::string& gi_version,
- GError **error);
+ explicit GirAttributesConsumer (const GirManager& gir_manager) :
+ _gir_manager (gir_manager) {}
private:
+ const GirManager& _gir_manager;
+
void _handle_function_decl (FunctionDecl& func);
public:
virtual bool HandleTopLevelDecl (DeclGroupRef decl_group);
diff --git a/clang-plugin/gir-manager.cpp b/clang-plugin/gir-manager.cpp
new file mode 100644
index 0000000..f75f564
--- /dev/null
+++ b/clang-plugin/gir-manager.cpp
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * gnome-clang
+ * Copyright © 2013 Collabora Ltd.
+ *
+ * gnome-clang is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gnome-clang is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gnome-clang. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Philip Withnall <philip.withnall@collabora.co.uk>
+ */
+
+#include <girepository.h>
+#include <gitypes.h>
+
+#include <clang/AST/Attr.h>
+
+#include "debug.h"
+#include "gir-manager.h"
+
+GirManager::GirManager ()
+{
+ this->_repo = g_irepository_get_default ();
+}
+
+void
+GirManager::load_namespace (const std::string& gi_namespace,
+ const std::string& gi_version,
+ GError** error)
+{
+ /* Load the GIR typelib. */
+ GITypelib* typelib = g_irepository_require (this->_repo,
+ gi_namespace.c_str (),
+ gi_version.c_str (),
+ (GIRepositoryLoadFlags) 0,
+ error);
+
+ if (typelib == NULL)
+ return;
+
+ /* Get the C prefix from the repository and convert it to lower case. */
+ const char *c_prefix =
+ g_irepository_get_c_prefix (this->_repo,
+ gi_namespace.c_str ());
+
+ Nspace r = Nspace ();
+ r.nspace = gi_namespace;
+ r.version = gi_version;
+ r.c_prefix = std::string (c_prefix);
+ r.typelib = typelib;
+
+ std::transform (r.c_prefix.begin (), r.c_prefix.end (),
+ r.c_prefix.begin (), ::tolower);
+
+ this->_typelibs.push_back (r);
+}
+
+/* Try to find typelib information about the function. */
+GIBaseInfo*
+GirManager::find_function_info (const std::string& func_name) const
+{
+ GIBaseInfo *info = NULL;
+ std::string func_name_stripped;
+
+ for (std::vector<Nspace>::const_iterator it = this->_typelibs.begin ();
+ it != this->_typelibs.end (); ++it) {
+ Nspace r = *it;
+
+ DEBUG ("Looking for function " << func_name <<
+ " in repository " << r.nspace << " (version " <<
+ r.version << ", C prefix ‘" << r.c_prefix << "’).");
+
+ /* The func_name includes the namespace, which needs stripping.
+ * e.g. g_irepository_find_by_name → find_by_name. */
+ if (func_name.compare (0, r.c_prefix.size (),
+ r.c_prefix) == 0) {
+ size_t prefix_len =
+ r.c_prefix.size () + 1 /* underscore */;
+ func_name_stripped = func_name.substr (prefix_len);
+ } else {
+ DEBUG ("\tDoesn’t match C prefix ‘" << r.c_prefix <<
+ "’.");
+ continue;
+ }
+
+ info = g_irepository_find_by_name (this->_repo,
+ r.nspace.c_str (),
+ func_name_stripped.c_str ());
+
+ if (info != NULL) {
+ /* Successfully found an entry in the typelib. */
+ DEBUG ("Found info!");
+ break;
+ }
+ }
+
+ return info;
+}
diff --git a/clang-plugin/gir-manager.h b/clang-plugin/gir-manager.h
new file mode 100644
index 0000000..c78afae
--- /dev/null
+++ b/clang-plugin/gir-manager.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * gnome-clang
+ * Copyright © 2013 Collabora Ltd.
+ *
+ * gnome-clang is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gnome-clang is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gnome-clang. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Philip Withnall <philip.withnall@collabora.co.uk>
+ */
+
+#ifndef GNOME_CLANG_GIR_MANAGER_H
+#define GNOME_CLANG_GIR_MANAGER_H
+
+#include <girepository.h>
+
+class GirManager {
+private:
+ struct Nspace {
+ /* All non-NULL. */
+ std::string nspace;
+ std::string version;
+ std::string c_prefix;
+
+ GITypelib* typelib; /* unowned */
+ };
+
+ GIRepository* _repo; /* unowned */
+ std::vector<Nspace> _typelibs;
+
+public:
+ GirManager ();
+
+ void load_namespace (const std::string& gi_namespace,
+ const std::string& gi_version,
+ GError** error);
+
+ GIBaseInfo* find_function_info (const std::string& func_name) const;
+};
+
+#endif /* !GNOME_CLANG_GIR_MANAGER_H */
diff --git a/clang-plugin/plugin.cpp b/clang-plugin/plugin.cpp
index d728f5b..cbf5977 100644
--- a/clang-plugin/plugin.cpp
+++ b/clang-plugin/plugin.cpp
@@ -42,12 +42,14 @@ private:
std::unique_ptr<GirAttributesConsumer> _gir_consumer;
std::unique_ptr<GAssertAttributesConsumer> _gassert_consumer;
+ GirManager _gir_manager;
+
public:
GnomeAction ()
{
this->_gir_consumer =
std::unique_ptr<GirAttributesConsumer> (
- new GirAttributesConsumer ());
+ new GirAttributesConsumer (this->_gir_manager));
this->_gassert_consumer =
std::unique_ptr<GAssertAttributesConsumer> (
new GAssertAttributesConsumer ());
@@ -111,8 +113,8 @@ private:
/* Load the repository. */
GError *error = NULL;
- this->_gir_consumer->load_namespace (gi_namespace, gi_version,
- &error);
+ this->_gir_manager.load_namespace (gi_namespace, gi_version,
+ &error);
if (error != NULL) {
DiagnosticsEngine &d = CI.getDiagnostics ();
unsigned int id = d.getCustomDiagID (