Parse typedefs

This commit is contained in:
Jonathan Müller 2017-02-23 15:45:27 +01:00
commit 0794ff1420
10 changed files with 200 additions and 10 deletions

51
.clang-format Normal file
View file

@ -0,0 +1,51 @@
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4
ColumnLimit: 100
Cpp11BracedListStyle: true
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: true
Language: Cpp
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PenaltyBreakBeforeFirstCallParameter: 19937
PenaltyReturnTypeOnItsOwnLine: 19937
PointerAlignment: Left
ReflowComments: false
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never

BIN
C++ Types.xmind Normal file

Binary file not shown.

11
CMakeLists.txt Normal file
View file

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.6)
project(cppast)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES include/cppast/cpp_entity.hpp include/cppast/cpp_entity_kind.hpp include/cppast/detail/intrusive_list.hpp include/cppast/detail/assert.hpp include/cppast/cpp_entity_container.hpp src/cpp_entity_kind.cpp include/cppast/cpp_file.hpp src/cpp_file.cpp include/cppast/cpp_namespace.hpp include/cppast/cpp_entity_index.hpp include/cppast/cpp_entity_ref.hpp include/cppast/cpp_type.hpp src/cpp_namespace.cpp src/cpp_type.cpp include/cppast/cpp_expression.hpp include/cppast/cpp_array_type.hpp include/cppast/cpp_function_type.hpp include/cppast/cpp_enum.hpp src/cpp_enum.cpp src/cpp_entity.cpp include/cppast/visitor.hpp src/visitor.cpp src/cpp_type_alias.cpp include/cppast/cpp_type_alias.hpp include/cppast/cpp_variable_base.hpp src/cpp_variable.cpp include/cppast/cpp_variable.hpp src/cpp_language_linkage.cpp include/cppast/cpp_language_linkage.hpp src/cpp_function.cpp include/cppast/cpp_function.hpp include/cppast/cpp_storage_specifiers.hpp src/cpp_class.cpp include/cppast/cpp_class.hpp src/cpp_member_variable.cpp include/cppast/cpp_member_variable.hpp src/cpp_member_function.cpp include/cppast/cpp_member_function.hpp src/cpp_template_parameter.cpp include/cppast/cpp_template_parameter.hpp include/cppast/cpp_alias_template.hpp src/cpp_alias_template.cpp include/cppast/cpp_template.hpp src/cpp_function_template.cpp include/cppast/cpp_function_template.hpp src/cpp_class_template.cpp include/cppast/cpp_class_template.hpp src/cpp_variable_template.cpp include/cppast/cpp_variable_template.hpp)
add_library(cppast ${SOURCE_FILES})
target_include_directories(cppast PUBLIC ../type_safe/include ../debug_assert include/)
add_executable(cppast_main main.cpp)
target_link_libraries(cppast_main PUBLIC cppast)

6
TODO.md Normal file
View file

@ -0,0 +1,6 @@
Milestone 0 - Hierachy
* overloaded entity ref
* namespace id stuff
* preprocessor
* translation_unit

77
main.cpp Normal file
View file

@ -0,0 +1,77 @@
// 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 <cassert>
#include <iostream>
#include <cppast/cpp_array_type.hpp>
#include <cppast/cpp_class.hpp>
#include <cppast/cpp_entity_kind.hpp>
#include <cppast/cpp_enum.hpp>
#include <cppast/cpp_file.hpp>
#include <cppast/cpp_function_type.hpp>
#include <cppast/cpp_function.hpp>
#include <cppast/cpp_namespace.hpp>
#include <cppast/cpp_variable.hpp>
#include <cppast/cpp_alias_template.hpp>
#include <cppast/visitor.hpp>
std::unique_ptr<cppast::cpp_file> make_file(const cppast::cpp_entity_index& idx)
{
using namespace cppast;
cpp_file::builder file_builder("main.cpp");
file_builder.add_child(cpp_namespace::builder("foo", false).finish(idx, "foo"_id));
cpp_namespace::builder ns_builder("bar", false);
ns_builder.add_child(cpp_namespace::builder("foo", false).finish(idx, "bar::foo"_id));
file_builder.add_child(ns_builder.finish(idx, "bar"_id));
cpp_enum::builder e_builder("e", true);
e_builder.add_value(cpp_enum_value::build(idx, "e::a"_id, "a", nullptr));
file_builder.add_child(e_builder.finish(idx, "e"_id));
cpp_function::builder f_builder("func", cpp_builtin_type::build("int"));
f_builder.add_parameter(
cpp_function_parameter::build(idx, "param"_id, "param", cpp_builtin_type::build("int")));
f_builder.is_variadic();
file_builder.add_child(f_builder.finish(idx, "func"_id));
cpp_class::builder c_builder("type", cpp_class_kind::class_t, false);
c_builder.access_specifier(cpp_public);
c_builder.add_child(cpp_variable::build(idx, "var"_id, "var", cpp_builtin_type::build("int"),
nullptr, cpp_storage_class_none, false));
file_builder.add_child(c_builder.finish(idx, "type"_id));
cpp_alias_template::builder a_builder(
cpp_type_alias::build("alias", cpp_template_parameter_type::build(
cpp_template_type_parameter_ref("T"_id, "T"))));
a_builder.add_parameter(
cpp_template_type_parameter::build(idx, "T"_id, "T", cpp_template_keyword::keyword_typename,
false, nullptr));
file_builder.add_child(a_builder.finish(idx, "alias"_id));
return file_builder.finish(idx);
}
int main()
{
cppast::cpp_entity_index idx;
auto file = make_file(idx);
auto level = 0;
cppast::visit(*file, [&](const cppast::cpp_entity& e, cppast::visitor_info info) {
if (info == cppast::visitor_info::container_entity_exit)
--level;
else
{
std::cout << std::string(level, ' ') << cppast::to_string(e.kind()) << ' ' << e.name()
<< ' ' << cppast::full_name(e) << '\n';
if (info == cppast::visitor_info::container_entity_enter)
++level;
}
return true;
});
}

View file

@ -35,6 +35,7 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
return parse_cpp_using_declaration(context, cur);
case CXCursor_TypeAliasDecl:
case CXCursor_TypedefDecl:
return parse_cpp_type_alias(context, cur);
default:

View file

@ -414,16 +414,10 @@ catch (parse_error& ex)
std::unique_ptr<cpp_entity> detail::parse_cpp_type_alias(const detail::parse_context& context,
const CXCursor& cur)
{
DEBUG_ASSERT(cur.kind == CXCursor_TypeAliasDecl, detail::assert_handler{});
detail::tokenizer tokenizer(context.tu, context.file, cur);
detail::token_stream stream(tokenizer, cur);
// using <identifier> = ...
detail::skip(stream, "using");
auto& name = stream.get().value();
detail::skip(stream, "=");
DEBUG_ASSERT(cur.kind == CXCursor_TypeAliasDecl || cur.kind == CXCursor_TypedefDecl,
detail::assert_handler{});
auto name = cxstring(clang_getCursorSpelling(cur));
auto type = parse_type(context, clang_getTypedefDeclUnderlyingType(cur));
if (!type)
return nullptr;

0
test.cpp Normal file
View file

View file

@ -154,7 +154,10 @@ bool equal_types(const cpp_entity_index& idx, const cpp_type& parsed, const cpp_
// other test cases don't need that anymore
TEST_CASE("cpp_type_alias")
{
auto code = R"(
const char* code = nullptr;
SECTION("using")
{
code = R"(
// basic
using a = int;
using b = const long double volatile;
@ -192,6 +195,48 @@ using r = void(foo::*)(int,...) const &;
// member data pointers
using s = int(foo::*);
)";
}
SECTION("typedef")
{
code = R"(
// basic
typedef int a;
typedef const long double volatile b;
// pointers
typedef int* c;
typedef const unsigned int* d;
typedef unsigned const * volatile e;
// references
typedef int& f;
typedef const int&& g;
// user-defined types
typedef c h;
typedef const d i;
typedef e* j;
// arrays
typedef int k[42];
typedef float* l[];
typedef char m[3 * 2 + 4 ? 42 : 43];
// function pointers
typedef void(*n)(int);
typedef char*(&o)(const int&,...);
typedef n(*p)(int, o);
struct foo {};
// member function pointers
typedef void(foo::*q)(int);
typedef void(foo::*r)(int,...) const &;
// member data pointers
typedef int(foo::*s);
)";
}
auto add_cv = [](std::unique_ptr<cpp_type> type, cpp_cv cv) {
return cpp_cv_qualified_type::build(std::move(type), cv);

5
test/preprocessor.cpp Normal file
View file

@ -0,0 +1,5 @@
// 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.
#i