Add attribute convenience functions
This commit is contained in:
parent
756fe351f1
commit
10dd893b91
4 changed files with 124 additions and 37 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <type_safe/optional.hpp>
|
||||
#include <type_safe/optional_ref.hpp>
|
||||
|
||||
#include <cppast/cpp_token.hpp>
|
||||
|
||||
|
|
@ -30,35 +31,6 @@ namespace cppast
|
|||
unknown, //< An unknown attribute.
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
inline const char* get_attribute_name(cpp_attribute_kind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case cpp_attribute_kind::alignas_:
|
||||
return "alignas";
|
||||
case cpp_attribute_kind::carries_dependency:
|
||||
return "carries_dependency";
|
||||
case cpp_attribute_kind::deprecated:
|
||||
return "deprecated";
|
||||
case cpp_attribute_kind::fallthrough:
|
||||
return "fallthrough";
|
||||
case cpp_attribute_kind::maybe_unused:
|
||||
return "maybe_unused";
|
||||
case cpp_attribute_kind::nodiscard:
|
||||
return "nodiscard";
|
||||
case cpp_attribute_kind::noreturn:
|
||||
return "noreturn";
|
||||
|
||||
case cpp_attribute_kind::unknown:
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
return "<error>";
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
/// A C++ attribute, including `alignas` specifiers.
|
||||
///
|
||||
/// It consists of a name, an optional namespace scope and optional arguments.
|
||||
|
|
@ -72,12 +44,7 @@ namespace cppast
|
|||
{
|
||||
public:
|
||||
/// \effects Creates a known attribute, potentially with arguments.
|
||||
cpp_attribute(cpp_attribute_kind kind, type_safe::optional<cpp_token_string> arguments)
|
||||
: cpp_attribute(type_safe::nullopt, detail::get_attribute_name(kind), std::move(arguments),
|
||||
false)
|
||||
{
|
||||
kind_ = kind;
|
||||
}
|
||||
cpp_attribute(cpp_attribute_kind kind, type_safe::optional<cpp_token_string> arguments);
|
||||
|
||||
/// \effects Creates an unknown attribute giving it the optional scope, names, arguments and whether it is variadic.
|
||||
cpp_attribute(type_safe::optional<std::string> scope, std::string name,
|
||||
|
|
@ -129,6 +96,28 @@ namespace cppast
|
|||
|
||||
/// A list of C++ attributes.
|
||||
using cpp_attribute_list = std::vector<cpp_attribute>;
|
||||
|
||||
/// Checks whether an attribute is given.
|
||||
/// \returns `true` if the given attribute list (1-2) / entity (3-4) contain
|
||||
/// an attribute of the given name (1+3) / kind (2+4).
|
||||
/// `false` otherwise.
|
||||
/// \group has_attribute
|
||||
type_safe::optional_ref<const cpp_attribute> has_attribute(const cpp_attribute_list& attributes,
|
||||
const std::string& name);
|
||||
|
||||
/// \group has_attribute
|
||||
type_safe::optional_ref<const cpp_attribute> has_attribute(const cpp_attribute_list& attributes,
|
||||
cpp_attribute_kind kind);
|
||||
|
||||
class cpp_entity;
|
||||
|
||||
/// \group has_attribute
|
||||
type_safe::optional_ref<const cpp_attribute> has_attribute(const cpp_entity& e,
|
||||
const std::string& name);
|
||||
|
||||
/// \group has_attribute
|
||||
type_safe::optional_ref<const cpp_attribute> has_attribute(const cpp_entity& e,
|
||||
cpp_attribute_kind kind);
|
||||
} // namespace cppast
|
||||
|
||||
#endif // CPPAST_CPP_ATTRIBUTE_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ set(header
|
|||
set(source
|
||||
code_generator.cpp
|
||||
cpp_alias_template.cpp
|
||||
cpp_attribute.cpp
|
||||
cpp_class.cpp
|
||||
cpp_class_template.cpp
|
||||
cpp_entity.cpp
|
||||
|
|
@ -79,6 +80,8 @@ set(source
|
|||
visitor.cpp)
|
||||
set(libclang_source
|
||||
libclang/class_parser.cpp
|
||||
libclang/cxtokenizer.cpp
|
||||
libclang/cxtokenizer.hpp
|
||||
libclang/debug_helper.cpp
|
||||
libclang/debug_helper.hpp
|
||||
libclang/enum_parser.cpp
|
||||
|
|
@ -96,8 +99,6 @@ set(libclang_source
|
|||
libclang/preprocessor.hpp
|
||||
libclang/raii_wrapper.hpp
|
||||
libclang/template_parser.cpp
|
||||
libclang/cxtokenizer.cpp
|
||||
libclang/cxtokenizer.hpp
|
||||
libclang/type_parser.cpp
|
||||
libclang/variable_parser.cpp)
|
||||
|
||||
|
|
|
|||
89
src/cpp_attribute.cpp
Normal file
89
src/cpp_attribute.cpp
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.
|
||||
|
||||
#include <cppast/cpp_attribute.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <cppast/cpp_entity.hpp>
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* get_attribute_name(cpp_attribute_kind kind) noexcept
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case cpp_attribute_kind::alignas_:
|
||||
return "alignas";
|
||||
case cpp_attribute_kind::carries_dependency:
|
||||
return "carries_dependency";
|
||||
case cpp_attribute_kind::deprecated:
|
||||
return "deprecated";
|
||||
case cpp_attribute_kind::fallthrough:
|
||||
return "fallthrough";
|
||||
case cpp_attribute_kind::maybe_unused:
|
||||
return "maybe_unused";
|
||||
case cpp_attribute_kind::nodiscard:
|
||||
return "nodiscard";
|
||||
case cpp_attribute_kind::noreturn:
|
||||
return "noreturn";
|
||||
|
||||
case cpp_attribute_kind::unknown:
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
return "<error>";
|
||||
}
|
||||
}
|
||||
|
||||
cpp_attribute::cpp_attribute(cpp_attribute_kind kind,
|
||||
type_safe::optional<cpp_token_string> arguments)
|
||||
: cpp_attribute(type_safe::nullopt, get_attribute_name(kind), std::move(arguments), false)
|
||||
{
|
||||
kind_ = kind;
|
||||
}
|
||||
|
||||
type_safe::optional_ref<const cpp_attribute> cppast::has_attribute(
|
||||
const cpp_attribute_list& attributes, const std::string& name)
|
||||
{
|
||||
auto iter =
|
||||
std::find_if(attributes.begin(), attributes.end(), [&](const cpp_attribute& attribute) {
|
||||
if (attribute.scope())
|
||||
return attribute.scope().value() + "::" + attribute.name() == name;
|
||||
else
|
||||
return attribute.name() == name;
|
||||
});
|
||||
|
||||
if (iter == attributes.end())
|
||||
return nullptr;
|
||||
else
|
||||
return type_safe::ref(*iter);
|
||||
}
|
||||
|
||||
type_safe::optional_ref<const cpp_attribute> cppast::has_attribute(
|
||||
const cpp_attribute_list& attributes, cpp_attribute_kind kind)
|
||||
{
|
||||
auto iter =
|
||||
std::find_if(attributes.begin(), attributes.end(),
|
||||
[&](const cpp_attribute& attribute) { return attribute.kind() == kind; });
|
||||
|
||||
if (iter == attributes.end())
|
||||
return nullptr;
|
||||
else
|
||||
return type_safe::ref(*iter);
|
||||
}
|
||||
|
||||
type_safe::optional_ref<const cpp_attribute> cppast::has_attribute(const cpp_entity& e,
|
||||
const std::string& name)
|
||||
{
|
||||
return has_attribute(e.attributes(), name);
|
||||
}
|
||||
|
||||
type_safe::optional_ref<const cpp_attribute> cppast::has_attribute(const cpp_entity& e,
|
||||
cpp_attribute_kind kind)
|
||||
{
|
||||
return has_attribute(e.attributes(), kind);
|
||||
}
|
||||
|
|
@ -68,6 +68,8 @@ alignas(type) int var;
|
|||
if (e.name() == "a" || e.name() == "b")
|
||||
{
|
||||
REQUIRE(attributes.size() == 2u);
|
||||
REQUIRE(has_attribute(e, "attribute1"));
|
||||
REQUIRE(has_attribute(e, "attribute2"));
|
||||
check_attribute(attr, "attribute1", type_safe::nullopt,
|
||||
false);
|
||||
check_attribute(attributes[1u], "attribute2",
|
||||
|
|
@ -77,7 +79,10 @@ alignas(type) int var;
|
|||
check_attribute(attr, "variadic", type_safe::nullopt,
|
||||
true);
|
||||
else if (e.name() == "d")
|
||||
{
|
||||
REQUIRE(has_attribute(e, "ns::attribute"));
|
||||
check_attribute(attr, "attribute", "ns", false);
|
||||
}
|
||||
else if (e.name() == "e")
|
||||
check_attribute(attr, "attribute", type_safe::nullopt,
|
||||
false, R"(arg1,arg2,+(){},42,"Hello!")");
|
||||
|
|
@ -89,8 +94,11 @@ alignas(type) int var;
|
|||
type_safe::nullopt, false);
|
||||
}
|
||||
else if (e.name() == "g")
|
||||
{
|
||||
REQUIRE(has_attribute(e, cpp_attribute_kind::deprecated));
|
||||
check_attribute(attr, "deprecated", type_safe::nullopt,
|
||||
false, "", cpp_attribute_kind::deprecated);
|
||||
}
|
||||
else if (e.name() == "h")
|
||||
check_attribute(attr, "maybe_unused", type_safe::nullopt,
|
||||
false, "",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue