diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7695a3e --- /dev/null +++ b/.clang-format @@ -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 diff --git a/C++ Types.xmind b/C++ Types.xmind new file mode 100644 index 0000000..e23ab57 Binary files /dev/null and b/C++ Types.xmind differ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4db44e4 --- /dev/null +++ b/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..fadbcc0 --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +Milestone 0 - Hierachy + +* overloaded entity ref +* namespace id stuff +* preprocessor +* translation_unit diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..3b4877b --- /dev/null +++ b/main.cpp @@ -0,0 +1,77 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +std::unique_ptr 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; + }); +} diff --git a/src/libclang/parse_functions.cpp b/src/libclang/parse_functions.cpp index 53a487e..01c14a2 100644 --- a/src/libclang/parse_functions.cpp +++ b/src/libclang/parse_functions.cpp @@ -35,6 +35,7 @@ std::unique_ptr 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: diff --git a/src/libclang/type_parser.cpp b/src/libclang/type_parser.cpp index ec89d5b..fa72973 100644 --- a/src/libclang/type_parser.cpp +++ b/src/libclang/type_parser.cpp @@ -414,16 +414,10 @@ catch (parse_error& ex) std::unique_ptr 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 = ... - 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; diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..e69de29 diff --git a/test/cpp_type_alias.cpp b/test/cpp_type_alias.cpp index 6511fd5..17f6b55 100644 --- a/test/cpp_type_alias.cpp +++ b/test/cpp_type_alias.cpp @@ -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 type, cpp_cv cv) { return cpp_cv_qualified_type::build(std::move(type), cv); diff --git a/test/preprocessor.cpp b/test/preprocessor.cpp new file mode 100644 index 0000000..e860755 --- /dev/null +++ b/test/preprocessor.cpp @@ -0,0 +1,5 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#i