Updated cppast ref
This commit is contained in:
@@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
* src/cx/compilation_database.cc
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
#include "compilation_database.h"
|
|
||||||
#include "util/util.h"
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <spdlog/fmt/fmt.h>
|
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
namespace clanguml {
|
|
||||||
namespace cx {
|
|
||||||
compilation_database::compilation_database(CXCompilationDatabase &&d)
|
|
||||||
: m_database{std::move(d)}
|
|
||||||
, m_index{clang_createIndex(0, 1)}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
compilation_database::~compilation_database()
|
|
||||||
{
|
|
||||||
// clang_CompilationDatabase_dispose(m_database);
|
|
||||||
}
|
|
||||||
|
|
||||||
compilation_database::compilation_database(compilation_database &&d)
|
|
||||||
: m_database{std::move(d.m_database)}
|
|
||||||
, m_index{std::move(d.m_index)}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
compilation_database compilation_database::from_directory(
|
|
||||||
const std::string &dir)
|
|
||||||
{
|
|
||||||
CXCompilationDatabase_Error error;
|
|
||||||
auto path = std::filesystem::path{dir};
|
|
||||||
CXCompilationDatabase cdb =
|
|
||||||
clang_CompilationDatabase_fromDirectory(path.c_str(), &error);
|
|
||||||
|
|
||||||
if (error != CXCompilationDatabase_Error::CXCompilationDatabase_NoError) {
|
|
||||||
throw std::runtime_error(fmt::format(
|
|
||||||
"Cannot load compilation database database from: {}", dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
return compilation_database{std::move(cdb)};
|
|
||||||
}
|
|
||||||
|
|
||||||
CXTranslationUnit compilation_database::parse_translation_unit(
|
|
||||||
const std::string &path)
|
|
||||||
{
|
|
||||||
const auto p = std::filesystem::canonical(path);
|
|
||||||
|
|
||||||
CXCompileCommands compile_commands =
|
|
||||||
clang_CompilationDatabase_getCompileCommands(m_database, p.c_str());
|
|
||||||
|
|
||||||
unsigned int compile_commands_count =
|
|
||||||
clang_CompileCommands_getSize(compile_commands);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
// for (i = 0; i < compile_commands_count; i++) {
|
|
||||||
CXCompileCommand compile_command =
|
|
||||||
clang_CompileCommands_getCommand(compile_commands, 0);
|
|
||||||
|
|
||||||
auto cc_filename = clang_CompileCommand_getFilename(compile_command);
|
|
||||||
LOG_DBG(
|
|
||||||
"Processing compile command file: {}", clang_getCString(cc_filename));
|
|
||||||
|
|
||||||
auto num_args = clang_CompileCommand_getNumArgs(compile_command);
|
|
||||||
|
|
||||||
char **arguments = NULL;
|
|
||||||
if (num_args) {
|
|
||||||
int j;
|
|
||||||
arguments = (char **)malloc(sizeof(char *) * num_args);
|
|
||||||
for (j = 0; j < num_args; ++j) {
|
|
||||||
CXString arg = clang_CompileCommand_getArg(compile_command, j);
|
|
||||||
LOG_DBG("Processing argument: {}", clang_getCString(arg));
|
|
||||||
arguments[j] = strdup(clang_getCString(arg));
|
|
||||||
clang_disposeString(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CXTranslationUnit tu = clang_parseTranslationUnit(m_index, nullptr,
|
|
||||||
(const char *const *)arguments, num_args, NULL, 0,
|
|
||||||
CXTranslationUnit_None);
|
|
||||||
|
|
||||||
if (num_args) {
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < num_args; ++j) {
|
|
||||||
free(arguments[j]);
|
|
||||||
}
|
|
||||||
free(arguments);
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
|
|
||||||
return tu;
|
|
||||||
}
|
|
||||||
|
|
||||||
CXCompilationDatabase &compilation_database::db() { return m_database; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* src/cx/compilation_database.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <clang-c/CXCompilationDatabase.h>
|
|
||||||
#include <clang-c/Index.h>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace clanguml {
|
|
||||||
namespace cx {
|
|
||||||
|
|
||||||
class compilation_database {
|
|
||||||
public:
|
|
||||||
compilation_database(CXCompilationDatabase &&d);
|
|
||||||
~compilation_database();
|
|
||||||
|
|
||||||
compilation_database(compilation_database &&d);
|
|
||||||
|
|
||||||
CXCompilationDatabase &db();
|
|
||||||
|
|
||||||
CXIndex &index();
|
|
||||||
|
|
||||||
CXTranslationUnit parse_translation_unit(const std::string &path);
|
|
||||||
|
|
||||||
static compilation_database from_directory(const std::string &dir);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CXCompilationDatabase m_database;
|
|
||||||
CXIndex m_index;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
328
src/cx/cursor.cc
328
src/cx/cursor.cc
@@ -1,328 +0,0 @@
|
|||||||
/**
|
|
||||||
* src/cx/cursor.cc
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cx/cursor.h"
|
|
||||||
|
|
||||||
namespace clanguml::cx {
|
|
||||||
|
|
||||||
cursor::cursor()
|
|
||||||
: m_cursor{clang_getNullCursor()}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor::cursor(CXCursor &&c)
|
|
||||||
: m_cursor{std::move(c)}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor::cursor(const CXCursor &c)
|
|
||||||
: m_cursor{c}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor::cursor(const cursor &c)
|
|
||||||
: m_cursor{c.get()}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::operator==(const cursor &b) const
|
|
||||||
{
|
|
||||||
return clang_equalCursors(m_cursor, b.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
cx::type cursor::type() const { return {clang_getCursorType(m_cursor)}; }
|
|
||||||
|
|
||||||
std::string cursor::display_name() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getCursorDisplayName(m_cursor));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cursor::spelling() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getCursorSpelling(m_cursor));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_void() const
|
|
||||||
{
|
|
||||||
// Why do I have to do this like this?
|
|
||||||
return spelling() == "void";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return fully qualified cursor spelling
|
|
||||||
*
|
|
||||||
* This method generates a fully qualified name for the cursor by
|
|
||||||
* traversing the namespaces upwards.
|
|
||||||
*
|
|
||||||
* TODO: Add caching of this value.
|
|
||||||
*
|
|
||||||
* @return Fully qualified cursor spelling
|
|
||||||
*/
|
|
||||||
std::string cursor::fully_qualified() const
|
|
||||||
{
|
|
||||||
std::list<std::string> res;
|
|
||||||
cursor iterator{m_cursor};
|
|
||||||
if (iterator.spelling().empty())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
int limit = 100;
|
|
||||||
while (iterator.kind() != CXCursor_TranslationUnit) {
|
|
||||||
auto name = iterator.spelling();
|
|
||||||
if (!name.empty())
|
|
||||||
res.push_front(iterator.spelling());
|
|
||||||
iterator = iterator.semantic_parent();
|
|
||||||
if (limit-- == 0)
|
|
||||||
throw std::runtime_error(fmt::format(
|
|
||||||
"Generating fully qualified name for '{}' failed at: '{}'",
|
|
||||||
spelling(), fmt::join(res, "::")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt::format("{}", fmt::join(res, "::"));
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor cursor::referenced() const
|
|
||||||
{
|
|
||||||
return cx::cursor{clang_getCursorReferenced(m_cursor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor cursor::semantic_parent() const
|
|
||||||
{
|
|
||||||
return {clang_getCursorSemanticParent(m_cursor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor cursor::lexical_parent() const
|
|
||||||
{
|
|
||||||
return {clang_getCursorLexicalParent(m_cursor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
CXCursorKind cursor::kind() const { return m_cursor.kind; }
|
|
||||||
|
|
||||||
std::string cursor::kind_spelling() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getCursorKindSpelling(m_cursor.kind));
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor cursor::definition() const
|
|
||||||
{
|
|
||||||
return clang_getCursorDefinition(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_definition() const
|
|
||||||
{
|
|
||||||
return clang_isCursorDefinition(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_declaration() const { return clang_isDeclaration(kind()); }
|
|
||||||
|
|
||||||
bool cursor::is_forward_declaration() const
|
|
||||||
{
|
|
||||||
auto definition = clang_getCursorDefinition(m_cursor);
|
|
||||||
|
|
||||||
if (clang_equalCursors(definition, clang_getNullCursor()))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return !clang_equalCursors(m_cursor, definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_invalid_declaration() const
|
|
||||||
{
|
|
||||||
return clang_isInvalidDeclaration(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXSourceLocation cursor::location() const
|
|
||||||
{
|
|
||||||
return clang_getCursorLocation(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_reference() const { return clang_isReference(kind()); }
|
|
||||||
|
|
||||||
bool cursor::is_expression() const { return clang_isExpression(kind()); }
|
|
||||||
|
|
||||||
bool cursor::is_statement() const { return clang_isStatement(kind()); }
|
|
||||||
|
|
||||||
bool cursor::is_namespace() const { return kind() == CXCursor_Namespace; }
|
|
||||||
|
|
||||||
bool cursor::is_attribute() const { return clang_isAttribute(kind()); }
|
|
||||||
|
|
||||||
bool cursor::has_attrs() const { return clang_Cursor_hasAttrs(m_cursor); }
|
|
||||||
|
|
||||||
bool cursor::is_invalid() const { return clang_isInvalid(kind()); }
|
|
||||||
|
|
||||||
bool cursor::is_translation_unit() const
|
|
||||||
{
|
|
||||||
return clang_isTranslationUnit(kind());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_preprocessing() const { return clang_isPreprocessing(kind()); }
|
|
||||||
|
|
||||||
bool cursor::is_method_virtual() const
|
|
||||||
{
|
|
||||||
return clang_CXXMethod_isVirtual(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_static() const
|
|
||||||
{
|
|
||||||
return clang_Cursor_getStorageClass(m_cursor) == CX_SC_Static;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_method_static() const
|
|
||||||
{
|
|
||||||
return clang_CXXMethod_isStatic(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_method_const() const
|
|
||||||
{
|
|
||||||
return clang_CXXMethod_isConst(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_method_pure_virtual() const
|
|
||||||
{
|
|
||||||
return clang_CXXMethod_isPureVirtual(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_method_defaulted() const
|
|
||||||
{
|
|
||||||
return clang_CXXMethod_isDefaulted(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_method_parameter() const { return kind() == CXCursor_ParmDecl; }
|
|
||||||
|
|
||||||
CXVisibilityKind cursor::visibitity() const
|
|
||||||
{
|
|
||||||
return clang_getCursorVisibility(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXAvailabilityKind cursor::availability() const
|
|
||||||
{
|
|
||||||
return clang_getCursorAvailability(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CX_CXXAccessSpecifier cursor::cxxaccess_specifier() const
|
|
||||||
{
|
|
||||||
return clang_getCXXAccessSpecifier(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
cx::type cursor::underlying_type() const
|
|
||||||
{
|
|
||||||
return clang_getTypedefDeclUnderlyingType(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cursor::template_argument_count() const
|
|
||||||
{
|
|
||||||
return clang_Cursor_getNumTemplateArguments(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXTemplateArgumentKind cursor::template_argument_kind(unsigned i) const
|
|
||||||
{
|
|
||||||
return clang_Cursor_getTemplateArgumentKind(m_cursor, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
cx::type cursor::template_argument_type(unsigned i) const
|
|
||||||
{
|
|
||||||
return clang_Cursor_getTemplateArgumentType(m_cursor, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
long long cursor::template_argument_value(unsigned i) const
|
|
||||||
{
|
|
||||||
return clang_Cursor_getTemplateArgumentValue(m_cursor, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor cursor::specialized_cursor_template() const
|
|
||||||
{
|
|
||||||
return clang_getSpecializedCursorTemplate(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
CXTranslationUnit cursor::translation_unit() const
|
|
||||||
{
|
|
||||||
return clang_Cursor_getTranslationUnit(m_cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cursor::is_template_parameter_variadic() const
|
|
||||||
{
|
|
||||||
const auto &tokens = tokenize();
|
|
||||||
return tokens.size() > 2 && tokens[1] == "...";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cursor::usr() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getCursorUSR(m_cursor));
|
|
||||||
}
|
|
||||||
|
|
||||||
CXSourceRange cursor::extent() const { return clang_getCursorExtent(m_cursor); }
|
|
||||||
|
|
||||||
std::vector<std::string> cursor::tokenize() const
|
|
||||||
{
|
|
||||||
auto range = extent();
|
|
||||||
std::vector<std::string> res;
|
|
||||||
CXToken *toks;
|
|
||||||
unsigned toks_count{0};
|
|
||||||
auto tu = translation_unit();
|
|
||||||
|
|
||||||
clang_tokenize(tu, range, &toks, &toks_count);
|
|
||||||
|
|
||||||
for (int i = 0; i < toks_count; i++) {
|
|
||||||
res.push_back(to_string(clang_getTokenSpelling(tu, toks[i])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cursor::default_value() const
|
|
||||||
{
|
|
||||||
assert(is_method_parameter());
|
|
||||||
|
|
||||||
auto toks = tokenize();
|
|
||||||
std::string res;
|
|
||||||
auto it = std::find(toks.begin(), toks.end(), "=");
|
|
||||||
if (it != toks.end()) {
|
|
||||||
res = fmt::format("{}", fmt::join(it + 1, toks.end(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> cursor::tokenize_template_parameters() const
|
|
||||||
{
|
|
||||||
auto toks = tokenize();
|
|
||||||
std::vector<std::string> res;
|
|
||||||
bool inside_template{false};
|
|
||||||
bool is_namespace{false};
|
|
||||||
|
|
||||||
for (int i = 0; i < toks.size(); i++) {
|
|
||||||
// libclang returns ">..>>" in template as a single token...
|
|
||||||
auto t = toks[i];
|
|
||||||
if (std::all_of(
|
|
||||||
t.begin(), t.end(), [](const char &c) { return c == '>'; })) {
|
|
||||||
toks[i] = ">";
|
|
||||||
for (int j = 0; j < t.size() - 1; j++)
|
|
||||||
toks.insert(toks.begin() + i, ">");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto template_start = std::find(toks.begin(), toks.end(), "<");
|
|
||||||
auto template_end = std::find(toks.rbegin(), toks.rend(), ">");
|
|
||||||
|
|
||||||
decltype(res) template_contents(
|
|
||||||
template_start + 1, template_end.base() - 1);
|
|
||||||
|
|
||||||
return clanguml::util::split(
|
|
||||||
fmt::format("{}", fmt::join(template_contents, "")), ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
const CXCursor &cursor::get() const { return m_cursor; }
|
|
||||||
|
|
||||||
}
|
|
||||||
153
src/cx/cursor.h
153
src/cx/cursor.h
@@ -1,153 +0,0 @@
|
|||||||
/**
|
|
||||||
* src/cx/cursor.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "cx/type.h"
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace clanguml {
|
|
||||||
namespace cx {
|
|
||||||
|
|
||||||
class cursor {
|
|
||||||
public:
|
|
||||||
cursor();
|
|
||||||
|
|
||||||
cursor(CXCursor &&c);
|
|
||||||
|
|
||||||
cursor(const CXCursor &c);
|
|
||||||
|
|
||||||
cursor(const cursor &c);
|
|
||||||
|
|
||||||
~cursor() = default;
|
|
||||||
|
|
||||||
bool operator==(const cursor &b) const;
|
|
||||||
|
|
||||||
cx::type type() const;
|
|
||||||
std::string display_name() const;
|
|
||||||
|
|
||||||
std::string spelling() const;
|
|
||||||
|
|
||||||
bool is_void() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return fully qualified cursor spelling
|
|
||||||
*
|
|
||||||
* This method generates a fully qualified name for the cursor by
|
|
||||||
* traversing the namespaces upwards.
|
|
||||||
*
|
|
||||||
* TODO: Add caching of this value.
|
|
||||||
*
|
|
||||||
* @return Fully qualified cursor spelling
|
|
||||||
*/
|
|
||||||
std::string fully_qualified() const;
|
|
||||||
|
|
||||||
cursor referenced() const;
|
|
||||||
|
|
||||||
cursor semantic_parent() const;
|
|
||||||
|
|
||||||
cursor lexical_parent() const;
|
|
||||||
|
|
||||||
CXCursorKind kind() const;
|
|
||||||
std::string kind_spelling() const;
|
|
||||||
|
|
||||||
cursor definition() const;
|
|
||||||
bool is_definition() const;
|
|
||||||
bool is_declaration() const;
|
|
||||||
bool is_forward_declaration() const;
|
|
||||||
|
|
||||||
bool is_invalid_declaration() const;
|
|
||||||
CXSourceLocation location() const;
|
|
||||||
|
|
||||||
bool is_reference() const;
|
|
||||||
bool is_expression() const;
|
|
||||||
bool is_statement() const;
|
|
||||||
bool is_namespace() const;
|
|
||||||
bool is_attribute() const;
|
|
||||||
bool has_attrs() const;
|
|
||||||
bool is_invalid() const;
|
|
||||||
bool is_translation_unit() const;
|
|
||||||
bool is_preprocessing() const;
|
|
||||||
bool is_method_virtual() const;
|
|
||||||
|
|
||||||
bool is_static() const;
|
|
||||||
|
|
||||||
bool is_method_static() const;
|
|
||||||
bool is_method_const() const;
|
|
||||||
bool is_method_pure_virtual() const;
|
|
||||||
|
|
||||||
bool is_method_defaulted() const;
|
|
||||||
|
|
||||||
bool is_method_parameter() const;
|
|
||||||
CXVisibilityKind visibitity() const;
|
|
||||||
|
|
||||||
CXAvailabilityKind availability() const;
|
|
||||||
|
|
||||||
CX_CXXAccessSpecifier cxxaccess_specifier() const;
|
|
||||||
|
|
||||||
cx::type underlying_type() const;
|
|
||||||
|
|
||||||
int template_argument_count() const;
|
|
||||||
|
|
||||||
CXTemplateArgumentKind template_argument_kind(unsigned i) const;
|
|
||||||
|
|
||||||
cx::type template_argument_type(unsigned i) const;
|
|
||||||
|
|
||||||
long long template_argument_value(unsigned i) const;
|
|
||||||
|
|
||||||
cursor specialized_cursor_template() const;
|
|
||||||
|
|
||||||
CXTranslationUnit translation_unit() const;
|
|
||||||
|
|
||||||
bool is_template_parameter_variadic() const;
|
|
||||||
|
|
||||||
std::string usr() const;
|
|
||||||
CXSourceRange extent() const;
|
|
||||||
std::vector<std::string> tokenize() const;
|
|
||||||
|
|
||||||
std::string default_value() const;
|
|
||||||
|
|
||||||
std::vector<std::string> tokenize_template_parameters() const;
|
|
||||||
|
|
||||||
const CXCursor &get() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CXCursor m_cursor;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> struct fmt::formatter<clanguml::cx::cursor> {
|
|
||||||
template <typename ParseContext> constexpr auto parse(ParseContext &ctx)
|
|
||||||
{
|
|
||||||
return ctx.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FormatContext>
|
|
||||||
auto format(const clanguml::cx::cursor &c, FormatContext &ctx)
|
|
||||||
{
|
|
||||||
return fmt::format_to(ctx.out(),
|
|
||||||
"(cx::cursor spelling={}, display_name={}, kind={}, "
|
|
||||||
"is_expression={}, template_argument_count={})",
|
|
||||||
c.spelling(), c.display_name(), c.kind_spelling(),
|
|
||||||
c.is_expression(), c.template_argument_count()
|
|
||||||
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
208
src/cx/type.cc
208
src/cx/type.cc
@@ -1,208 +0,0 @@
|
|||||||
/**
|
|
||||||
* src/cx/type.cc
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
#include "type.h"
|
|
||||||
#include "cursor.h"
|
|
||||||
|
|
||||||
namespace clanguml {
|
|
||||||
namespace cx {
|
|
||||||
|
|
||||||
type::type(CXType &&t)
|
|
||||||
: m_type{std::move(t)}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string type::spelling() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getTypeSpelling(m_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::operator==(const type &b) const
|
|
||||||
{
|
|
||||||
return clang_equalTypes(m_type, b.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::canonical() const { return {clang_getCanonicalType(m_type)}; }
|
|
||||||
|
|
||||||
bool type::is_unexposed() const { return kind() == CXType_Unexposed; }
|
|
||||||
|
|
||||||
bool type::is_const_qualified() const
|
|
||||||
{
|
|
||||||
return clang_isConstQualifiedType(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_volatile_qualified() const
|
|
||||||
{
|
|
||||||
return clang_isVolatileQualifiedType(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_restricted_qualified() const
|
|
||||||
{
|
|
||||||
return clang_isRestrictQualifiedType(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_invalid() const { return kind() == CXType_Invalid; }
|
|
||||||
|
|
||||||
std::string type::typedef_name() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getTypedefName(m_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::pointee_type() const { return {clang_getPointeeType(m_type)}; }
|
|
||||||
|
|
||||||
CXTypeKind type::kind() const { return m_type.kind; }
|
|
||||||
|
|
||||||
std::string type::kind_spelling() const
|
|
||||||
{
|
|
||||||
return to_string(clang_getTypeKindSpelling(m_type.kind));
|
|
||||||
}
|
|
||||||
|
|
||||||
CXCallingConv type::calling_convention() const
|
|
||||||
{
|
|
||||||
return clang_getFunctionTypeCallingConv(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::result_type() const { return clang_getResultType(m_type); }
|
|
||||||
|
|
||||||
int type::exception_specification_type() const
|
|
||||||
{
|
|
||||||
return clang_getExceptionSpecificationType(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
int type::argument_type_count() const { return clang_getNumArgTypes(m_type); }
|
|
||||||
|
|
||||||
type type::argument_type(int i) const { return {clang_getArgType(m_type, i)}; }
|
|
||||||
|
|
||||||
bool type::is_function_variadic() const
|
|
||||||
{
|
|
||||||
return clang_isFunctionTypeVariadic(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_pod() const { return clang_isPODType(m_type); }
|
|
||||||
|
|
||||||
bool type::is_pointer() const { return kind() == CXType_Pointer; }
|
|
||||||
|
|
||||||
bool type::is_record() const { return kind() == CXType_Record; }
|
|
||||||
|
|
||||||
type type::referenced() const
|
|
||||||
{
|
|
||||||
auto t = *this;
|
|
||||||
while (t.is_pointer() || t.is_reference()) {
|
|
||||||
t = t.pointee_type();
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_reference() const
|
|
||||||
{
|
|
||||||
return (kind() == CXType_LValueReference) ||
|
|
||||||
(kind() == CXType_RValueReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_array() const { return clang_getArraySize(m_type) > -1; }
|
|
||||||
|
|
||||||
type type::array_type() const { return {clang_getArrayElementType(m_type)}; }
|
|
||||||
|
|
||||||
bool type::is_relationship() const
|
|
||||||
{
|
|
||||||
return is_pointer() || is_record() || is_reference() || !is_pod() ||
|
|
||||||
is_array() || is_template() ||
|
|
||||||
(spelling().find("std::array") ==
|
|
||||||
0 /* There must be a better way... */);
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::element_type() const { return clang_getElementType(m_type); }
|
|
||||||
|
|
||||||
long long type::element_count() const { return clang_getNumElements(m_type); }
|
|
||||||
|
|
||||||
type type::array_element_type() const
|
|
||||||
{
|
|
||||||
return clang_getArrayElementType(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::named_type() const { return clang_Type_getNamedType(m_type); }
|
|
||||||
|
|
||||||
CXTypeNullabilityKind type::nullability() const
|
|
||||||
{
|
|
||||||
return clang_Type_getNullability(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::class_type() const { return clang_Type_getClassType(m_type); }
|
|
||||||
|
|
||||||
long long type::size_of() const { return clang_Type_getSizeOf(m_type); }
|
|
||||||
|
|
||||||
type type::modified_type() const { return clang_Type_getModifiedType(m_type); }
|
|
||||||
|
|
||||||
type type::value_type() const { return clang_Type_getValueType(m_type); }
|
|
||||||
|
|
||||||
bool type::is_template() const { return template_arguments_count() > 0; }
|
|
||||||
|
|
||||||
bool type::is_template_parameter() const
|
|
||||||
{
|
|
||||||
return canonical().spelling().find("type-parameter-") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int type::template_arguments_count() const
|
|
||||||
{
|
|
||||||
return clang_Type_getNumTemplateArguments(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
type type::template_argument_type(int i) const
|
|
||||||
{
|
|
||||||
return clang_Type_getTemplateArgumentAsType(m_type, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CXType &type::get() const { return m_type; }
|
|
||||||
|
|
||||||
CXRefQualifierKind type::cxxref_qualifier() const
|
|
||||||
{
|
|
||||||
return clang_Type_getCXXRefQualifier(m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string type::unqualified() const
|
|
||||||
{
|
|
||||||
return clanguml::util::unqualify(spelling());
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor type::type_declaration() const
|
|
||||||
{
|
|
||||||
return {clang_getTypeDeclaration(m_type)};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string type::instantiation_template() const
|
|
||||||
{
|
|
||||||
assert(is_template_instantiation());
|
|
||||||
|
|
||||||
auto s = spelling();
|
|
||||||
auto it = s.find('<');
|
|
||||||
auto template_base_name = s.substr(0, it);
|
|
||||||
|
|
||||||
auto cur = type_declaration();
|
|
||||||
|
|
||||||
return cur.fully_qualified();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool type::is_template_instantiation() const
|
|
||||||
{
|
|
||||||
auto s = spelling();
|
|
||||||
auto it = s.find('<');
|
|
||||||
return it != std::string::npos &&
|
|
||||||
referenced().type_declaration().kind() != CXCursor_ClassTemplate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
142
src/cx/type.h
142
src/cx/type.h
@@ -1,142 +0,0 @@
|
|||||||
/**
|
|
||||||
* src/cx/type.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <clang-c/CXCompilationDatabase.h>
|
|
||||||
#include <clang-c/Index.h>
|
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include "cx/util.h"
|
|
||||||
#include "util/util.h"
|
|
||||||
|
|
||||||
namespace clanguml {
|
|
||||||
namespace cx {
|
|
||||||
|
|
||||||
using util::to_string;
|
|
||||||
|
|
||||||
class cursor;
|
|
||||||
|
|
||||||
class type {
|
|
||||||
public:
|
|
||||||
type(CXType &&t);
|
|
||||||
|
|
||||||
~type() = default;
|
|
||||||
|
|
||||||
std::string spelling() const;
|
|
||||||
|
|
||||||
bool operator==(const type &b) const;
|
|
||||||
|
|
||||||
type canonical() const;
|
|
||||||
bool is_unexposed() const;
|
|
||||||
bool is_const_qualified() const;
|
|
||||||
|
|
||||||
bool is_volatile_qualified() const;
|
|
||||||
|
|
||||||
bool is_restricted_qualified() const;
|
|
||||||
|
|
||||||
bool is_invalid() const;
|
|
||||||
std::string typedef_name() const;
|
|
||||||
|
|
||||||
type pointee_type() const;
|
|
||||||
cursor type_declaration() const;
|
|
||||||
|
|
||||||
CXTypeKind kind() const;
|
|
||||||
std::string kind_spelling() const;
|
|
||||||
|
|
||||||
CXCallingConv calling_convention() const;
|
|
||||||
|
|
||||||
type result_type() const;
|
|
||||||
int exception_specification_type() const;
|
|
||||||
|
|
||||||
int argument_type_count() const;
|
|
||||||
type argument_type(int i) const;
|
|
||||||
bool is_function_variadic() const;
|
|
||||||
|
|
||||||
bool is_pod() const;
|
|
||||||
bool is_pointer() const;
|
|
||||||
bool is_record() const;
|
|
||||||
/**
|
|
||||||
* @brief Return final referenced type.
|
|
||||||
*
|
|
||||||
* This method allows to extract a final type in case a type consists of a
|
|
||||||
* single or multiple pointers or references.
|
|
||||||
*
|
|
||||||
* @return Referenced type.
|
|
||||||
*/
|
|
||||||
type referenced() const;
|
|
||||||
|
|
||||||
bool is_reference() const;
|
|
||||||
|
|
||||||
bool is_array() const;
|
|
||||||
type array_type() const;
|
|
||||||
bool is_relationship() const;
|
|
||||||
|
|
||||||
type element_type() const;
|
|
||||||
long long element_count() const;
|
|
||||||
type array_element_type() const;
|
|
||||||
|
|
||||||
type named_type() const;
|
|
||||||
CXTypeNullabilityKind nullability() const;
|
|
||||||
|
|
||||||
type class_type() const;
|
|
||||||
long long size_of() const;
|
|
||||||
type modified_type() const;
|
|
||||||
type value_type() const;
|
|
||||||
bool is_template() const;
|
|
||||||
bool is_template_parameter() const;
|
|
||||||
|
|
||||||
int template_arguments_count() const;
|
|
||||||
|
|
||||||
type template_argument_type(int i) const;
|
|
||||||
|
|
||||||
const CXType &get() const;
|
|
||||||
CXRefQualifierKind cxxref_qualifier() const;
|
|
||||||
|
|
||||||
bool is_template_instantiation() const;
|
|
||||||
|
|
||||||
std::string instantiation_template() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Remove all qualifiers from field declaration.
|
|
||||||
*
|
|
||||||
* @return Unqualified identifier.
|
|
||||||
*/
|
|
||||||
std::string unqualified() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CXType m_type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> struct fmt::formatter<clanguml::cx::type> {
|
|
||||||
template <typename ParseContext> constexpr auto parse(ParseContext &ctx)
|
|
||||||
{
|
|
||||||
return ctx.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FormatContext>
|
|
||||||
auto format(const clanguml::cx::type &t, FormatContext &ctx)
|
|
||||||
{
|
|
||||||
return fmt::format_to(ctx.out(),
|
|
||||||
"(cx::type spelling={}, kind={}, pointee={}, "
|
|
||||||
"is_pod={}, canonical={}, is_relationship={})",
|
|
||||||
t.spelling(), t.kind_spelling(), t.pointee_type().spelling(),
|
|
||||||
t.is_pod(), t.canonical().spelling(), t.is_relationship());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
2
thirdparty/cppast
vendored
2
thirdparty/cppast
vendored
Submodule thirdparty/cppast updated: 183f49f3e7...11d6c53a19
Reference in New Issue
Block a user