Add basic libclang parsing infrastructure
This commit is contained in:
parent
e736da9089
commit
ac8b81400c
3 changed files with 225 additions and 0 deletions
44
include/cppast/libclang_parser.hpp
Normal file
44
include/cppast/libclang_parser.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||||
|
// This file is subject to the license terms in the LICENSE file
|
||||||
|
// found in the top-level directory of this distribution.
|
||||||
|
|
||||||
|
#ifndef CPPAST_LIBCLANG_PARSER_HPP_INCLUDED
|
||||||
|
#define CPPAST_LIBCLANG_PARSER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cppast/parser.hpp>
|
||||||
|
|
||||||
|
namespace cppast
|
||||||
|
{
|
||||||
|
/// Compilation config for the [cppast::libclang_parser]().
|
||||||
|
class libclang_compile_config final : public compile_config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
libclang_compile_config();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void do_set_flags(cpp_standard standard, type_safe::flag_set<compile_flag> flags) override;
|
||||||
|
|
||||||
|
void do_add_include_dir(std::string path) override;
|
||||||
|
|
||||||
|
void do_add_macro_definition(std::string name, std::string definition) override;
|
||||||
|
|
||||||
|
void do_remove_macro_definition(std::string name) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A parser that uses libclang.
|
||||||
|
class libclang_parser final : public parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
libclang_parser();
|
||||||
|
~libclang_parser() noexcept override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<cpp_file> do_parse(const cpp_entity_index& idx, const std::string& path,
|
||||||
|
const compile_config& config) const override;
|
||||||
|
|
||||||
|
struct impl;
|
||||||
|
std::unique_ptr<impl> pimpl_;
|
||||||
|
};
|
||||||
|
} // namespace cppast
|
||||||
|
|
||||||
|
#endif // CPPAST_LIBCLANG_PARSER_HPP_INCLUDED
|
||||||
92
src/libclang/libclang_parser.cpp
Normal file
92
src/libclang/libclang_parser.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||||
|
// This file is subject to the license terms in the LICENSE file
|
||||||
|
// found in the top-level directory of this distribution.
|
||||||
|
|
||||||
|
#include <cppast/libclang_parser.hpp>
|
||||||
|
|
||||||
|
#include "raii_wrapper.hpp"
|
||||||
|
|
||||||
|
using namespace cppast;
|
||||||
|
|
||||||
|
libclang_compile_config::libclang_compile_config() : compile_config({})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void libclang_compile_config::do_set_flags(cpp_standard standard,
|
||||||
|
type_safe::flag_set<compile_flag> flags)
|
||||||
|
{
|
||||||
|
switch (standard)
|
||||||
|
{
|
||||||
|
case cpp_standard::cpp_98:
|
||||||
|
if (flags & compile_flag::gnu_extensions)
|
||||||
|
add_flag("-std=gnu++98");
|
||||||
|
else
|
||||||
|
add_flag("-std=c++98");
|
||||||
|
break;
|
||||||
|
case cpp_standard::cpp_03:
|
||||||
|
if (flags & compile_flag::gnu_extensions)
|
||||||
|
add_flag("-std=gnu++03");
|
||||||
|
else
|
||||||
|
add_flag("-std=c++03");
|
||||||
|
break;
|
||||||
|
case cpp_standard::cpp_11:
|
||||||
|
if (flags & compile_flag::gnu_extensions)
|
||||||
|
add_flag("-std=gnu++11");
|
||||||
|
else
|
||||||
|
add_flag("-std=c++11");
|
||||||
|
break;
|
||||||
|
case cpp_standard::cpp_14:
|
||||||
|
if (flags & compile_flag::gnu_extensions)
|
||||||
|
add_flag("-std=gnu++14");
|
||||||
|
else
|
||||||
|
add_flag("-std=c++14");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & compile_flag::ms_compatibility)
|
||||||
|
add_flag("-fms-compatibility");
|
||||||
|
if (flags & compile_flag::ms_extensions)
|
||||||
|
add_flag("-fms-extensions");
|
||||||
|
}
|
||||||
|
|
||||||
|
void libclang_compile_config::do_add_include_dir(std::string path)
|
||||||
|
{
|
||||||
|
add_flag("-I" + std::move(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
void libclang_compile_config::do_add_macro_definition(std::string name, std::string definition)
|
||||||
|
{
|
||||||
|
auto str = "-D" + std::move(name);
|
||||||
|
if (!definition.empty())
|
||||||
|
str += "=" + std::move(definition);
|
||||||
|
add_flag(std::move(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void libclang_compile_config::do_remove_macro_definition(std::string name)
|
||||||
|
{
|
||||||
|
add_flag("-U" + std::move(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct libclang_parser::impl
|
||||||
|
{
|
||||||
|
detail::cxindex index;
|
||||||
|
|
||||||
|
impl() : index(clang_createIndex(1, 1))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
libclang_parser::libclang_parser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
libclang_parser::~libclang_parser() noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<cpp_file> libclang_parser::do_parse(const cpp_entity_index& idx,
|
||||||
|
const std::string& path,
|
||||||
|
const compile_config& config) const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
89
src/libclang/raii_wrapper.hpp
Normal file
89
src/libclang/raii_wrapper.hpp
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Copyright (C) 2017 Jonathan Müller <jonathanmueller.dev@gmail.com>
|
||||||
|
// This file is subject to the license terms in the LICENSE file
|
||||||
|
// found in the top-level directory of this distribution.
|
||||||
|
|
||||||
|
#ifndef CPPAST_RAII_WRAPPER_HPP_INCLUDED
|
||||||
|
#define CPPAST_RAII_WRAPPER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
|
#include <cppast/detail/assert.hpp>
|
||||||
|
|
||||||
|
namespace cppast
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <typename T, class Deleter>
|
||||||
|
class raii_wrapper : Deleter
|
||||||
|
{
|
||||||
|
static_assert(std::is_pointer<T>::value, "");
|
||||||
|
|
||||||
|
public:
|
||||||
|
raii_wrapper() noexcept : obj_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
raii_wrapper(T obj) noexcept : obj_(obj)
|
||||||
|
{
|
||||||
|
DEBUG_ASSERT(obj_, detail::assert_handler{});
|
||||||
|
}
|
||||||
|
|
||||||
|
raii_wrapper(raii_wrapper&& other) noexcept : obj_(other.obj_)
|
||||||
|
{
|
||||||
|
DEBUG_ASSERT(obj_, detail::assert_handler{});
|
||||||
|
other.obj_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~raii_wrapper() noexcept
|
||||||
|
{
|
||||||
|
if (obj_)
|
||||||
|
static_cast<Deleter&> (*this)(obj_);
|
||||||
|
}
|
||||||
|
|
||||||
|
raii_wrapper& operator=(raii_wrapper&& other) noexcept
|
||||||
|
{
|
||||||
|
raii_wrapper tmp(std::move(other));
|
||||||
|
swap(*this, tmp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend void swap(raii_wrapper& a, raii_wrapper& b) noexcept
|
||||||
|
{
|
||||||
|
std::swap(a.obj_, b.obj_);
|
||||||
|
}
|
||||||
|
|
||||||
|
T get() const noexcept
|
||||||
|
{
|
||||||
|
DEBUG_ASSERT(obj_, detail::assert_handler{});
|
||||||
|
return obj_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T obj_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cxindex_deleter
|
||||||
|
{
|
||||||
|
void operator()(CXIndex idx) noexcept
|
||||||
|
{
|
||||||
|
clang_disposeIndex(idx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using cxindex = raii_wrapper<CXIndex, cxindex_deleter>;
|
||||||
|
|
||||||
|
struct cxtranslation_unit_deleter
|
||||||
|
{
|
||||||
|
void operator()(CXTranslationUnit unit) noexcept
|
||||||
|
{
|
||||||
|
clang_disposeTranslationUnit(unit);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using cxtranslation_unit = raii_wrapper<CXTranslationUnit, cxtranslation_unit_deleter>;
|
||||||
|
}
|
||||||
|
} // namespace cppast::detail
|
||||||
|
|
||||||
|
#endif // CPPAST_RAII_WRAPPER_HPP_INCLUDED
|
||||||
Loading…
Add table
Add a link
Reference in a new issue