diff --git a/index_tests/class_forward_declaration.cc b/index_tests/class_forward_declaration.cc index a90ce125..fd80cefb 100644 --- a/index_tests/class_forward_declaration.cc +++ b/index_tests/class_forward_declaration.cc @@ -17,7 +17,7 @@ OUTPUT: "kind": 5, "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "3:7-3:10|0|1|2", - "extent": "1:1-1:10|0|1|0", + "extent": "3:1-3:13|0|1|0", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/constructors/invalid_reference.cc b/index_tests/constructors/invalid_reference.cc index c68bc86e..7f17706c 100644 --- a/index_tests/constructors/invalid_reference.cc +++ b/index_tests/constructors/invalid_reference.cc @@ -20,7 +20,7 @@ OUTPUT: "kind": 9, "storage": 0, "declarations": [], - "spell": "4:6-4:9|0|1|514", + "spell": "4:6-4:9|15041163540773201510|2|514", "extent": "4:1-4:11|0|1|0", "declaring_type": 0, "bases": [], diff --git a/index_tests/constructors/make_functions.cc b/index_tests/constructors/make_functions.cc index 5a74373a..ecce8489 100644 --- a/index_tests/constructors/make_functions.cc +++ b/index_tests/constructors/make_functions.cc @@ -132,7 +132,10 @@ OUTPUT: make_functions.h } OUTPUT: make_functions.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&make_functions.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 2532818908869373467, diff --git a/index_tests/declaration_vs_definition/class.cc b/index_tests/declaration_vs_definition/class.cc index e8aa0e94..42a44a88 100644 --- a/index_tests/declaration_vs_definition/class.cc +++ b/index_tests/declaration_vs_definition/class.cc @@ -19,7 +19,7 @@ OUTPUT: "kind": 5, "declarations": ["1:7-1:10|0|1|1", "2:7-2:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "3:7-3:10|0|1|2", - "extent": "1:1-1:10|0|1|0", + "extent": "3:1-3:13|0|1|0", "alias_of": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/class_member_static.cc b/index_tests/declaration_vs_definition/class_member_static.cc index 5c522d44..24570fcb 100644 --- a/index_tests/declaration_vs_definition/class_member_static.cc +++ b/index_tests/declaration_vs_definition/class_member_static.cc @@ -64,7 +64,7 @@ OUTPUT: "short_name": "foo", "declarations": ["2:14-2:17|15041163540773201510|2|513"], "spell": "5:10-5:13|15041163540773201510|2|514", - "extent": "2:3-2:17|15041163540773201510|2|0", + "extent": "5:1-5:13|0|1|0", "type": 53, "uses": [], "kind": 13, diff --git a/index_tests/declaration_vs_definition/func.cc b/index_tests/declaration_vs_definition/func.cc index eb24139c..10f53f1e 100644 --- a/index_tests/declaration_vs_definition/func.cc +++ b/index_tests/declaration_vs_definition/func.cc @@ -18,7 +18,7 @@ OUTPUT: "storage": 0, "declarations": ["1:6-1:9|0|1|1", "2:6-2:9|0|1|1", "4:6-4:9|0|1|1"], "spell": "3:6-3:9|0|1|2", - "extent": "1:1-1:11|0|1|0", + "extent": "3:1-3:14|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/func_associated_function_params.cc b/index_tests/declaration_vs_definition/func_associated_function_params.cc index 74ddc593..eb8071c0 100644 --- a/index_tests/declaration_vs_definition/func_associated_function_params.cc +++ b/index_tests/declaration_vs_definition/func_associated_function_params.cc @@ -18,7 +18,7 @@ OUTPUT: "storage": 0, "declarations": ["1:5-1:8|0|1|1", "2:5-2:8|0|1|1", "4:5-4:8|0|1|1"], "spell": "5:5-5:8|0|1|2", - "extent": "1:1-1:18|0|1|0", + "extent": "5:1-5:36|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/declaration_vs_definition/method.cc b/index_tests/declaration_vs_definition/method.cc index 94011284..3b323d76 100644 --- a/index_tests/declaration_vs_definition/method.cc +++ b/index_tests/declaration_vs_definition/method.cc @@ -48,7 +48,7 @@ OUTPUT: "storage": 0, "declarations": ["4:8-4:11|15041163540773201510|2|513"], "spell": "7:11-7:14|15041163540773201510|2|514", - "extent": "4:3-4:13|15041163540773201510|2|0", + "extent": "7:1-7:19|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/enums/enum_class_decl.cc b/index_tests/enums/enum_class_decl.cc index 3518fbee..b417eb0b 100644 --- a/index_tests/enums/enum_class_decl.cc +++ b/index_tests/enums/enum_class_decl.cc @@ -77,7 +77,6 @@ OUTPUT: "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20 = 20", "declarations": [], "spell": "4:3-4:4|16985894625255407295|2|514", "extent": "4:3-4:9|16985894625255407295|2|0", diff --git a/index_tests/enums/enum_decl.cc b/index_tests/enums/enum_decl.cc index ae283d35..5719a261 100644 --- a/index_tests/enums/enum_decl.cc +++ b/index_tests/enums/enum_decl.cc @@ -59,7 +59,6 @@ OUTPUT: "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "B = 20 = 20", "declarations": [], "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", diff --git a/index_tests/enums/enum_inherit.cc b/index_tests/enums/enum_inherit.cc index fab7c3d3..d0535609 100644 --- a/index_tests/enums/enum_inherit.cc +++ b/index_tests/enums/enum_inherit.cc @@ -114,7 +114,6 @@ OUTPUT: "detailed_name": "B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "B = 20 = 20", "declarations": [], "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", @@ -140,7 +139,6 @@ OUTPUT: "detailed_name": "E::E20 = 20", "qual_name_offset": 0, "short_name": "E20", - "hover": "E::E20 = 20 = 20", "declarations": [], "spell": "10:3-10:6|2986879766914123941|2|514", "extent": "10:3-10:11|2986879766914123941|2|0", diff --git a/index_tests/enums/enum_usage.cc b/index_tests/enums/enum_usage.cc index b3c24b4a..1ea1d3bd 100644 --- a/index_tests/enums/enum_usage.cc +++ b/index_tests/enums/enum_usage.cc @@ -74,7 +74,6 @@ OUTPUT: "detailed_name": "Foo::B = 20", "qual_name_offset": 0, "short_name": "B", - "hover": "Foo::B = 20 = 20", "declarations": [], "spell": "3:3-3:4|16985894625255407295|2|514", "extent": "3:3-3:9|16985894625255407295|2|0", diff --git a/index_tests/function_declaration_definition.cc b/index_tests/function_declaration_definition.cc index 8a934cae..67bbfe77 100644 --- a/index_tests/function_declaration_definition.cc +++ b/index_tests/function_declaration_definition.cc @@ -16,7 +16,7 @@ OUTPUT: "storage": 0, "declarations": ["1:6-1:9|0|1|1"], "spell": "3:6-3:9|0|1|2", - "extent": "1:1-1:11|0|1|0", + "extent": "3:1-3:14|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/method_definition.cc b/index_tests/method_definition.cc index 28caf615..8fb481a6 100644 --- a/index_tests/method_definition.cc +++ b/index_tests/method_definition.cc @@ -18,7 +18,7 @@ OUTPUT: "storage": 0, "declarations": ["2:8-2:11|15041163540773201510|2|513"], "spell": "5:11-5:14|15041163540773201510|2|514", - "extent": "2:3-2:19|15041163540773201510|2|0", + "extent": "5:1-5:25|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/multi_file/funky_enum.cc b/index_tests/multi_file/funky_enum.cc index ea291468..29963edf 100644 --- a/index_tests/multi_file/funky_enum.cc +++ b/index_tests/multi_file/funky_enum.cc @@ -87,7 +87,10 @@ OUTPUT: funky_enum.h } OUTPUT: funky_enum.cc { - "includes": [], + "includes": [{ + "line": 1, + "resolved_path": "&funky_enum.h" + }], "skipped_ranges": [], "usr2func": [], "usr2type": [{ diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index a978e97e..48cbb17a 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -208,7 +208,10 @@ OUTPUT: header.h } OUTPUT: impl.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&header.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 5817708529036841195, diff --git a/index_tests/multi_file/simple_impl.cc b/index_tests/multi_file/simple_impl.cc index 639d0f69..1e6e9519 100644 --- a/index_tests/multi_file/simple_impl.cc +++ b/index_tests/multi_file/simple_impl.cc @@ -29,7 +29,10 @@ OUTPUT: simple_header.h } OUTPUT: simple_impl.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&simple_header.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 3373269392705484958, diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 5a607e6a..c7dcd941 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -44,7 +44,10 @@ OUTPUT: static.h } OUTPUT: static.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&static.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, @@ -55,7 +58,7 @@ OUTPUT: static.cc "storage": 0, "declarations": [], "spell": "3:14-3:32|9411323049603567600|2|514", - "extent": "4:3-4:35|9411323049603567600|2|0", + "extent": "3:1-3:37|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/namespaces/method_definition.cc b/index_tests/namespaces/method_definition.cc index 12efc78b..ed61dfe2 100644 --- a/index_tests/namespaces/method_definition.cc +++ b/index_tests/namespaces/method_definition.cc @@ -20,7 +20,7 @@ OUTPUT: "storage": 0, "declarations": ["3:8-3:11|4508214972876735896|2|513"], "spell": "6:11-6:14|4508214972876735896|2|514", - "extent": "3:3-3:13|4508214972876735896|2|0", + "extent": "6:1-6:19|2029211996748007610|2|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index f17ccd16..74a75735 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -78,7 +78,10 @@ OUTPUT: static_function_in_type.h } OUTPUT: static_function_in_type.cc { - "includes": [], + "includes": [{ + "line": 0, + "resolved_path": "&static_function_in_type.h" + }], "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, @@ -89,7 +92,7 @@ OUTPUT: static_function_in_type.cc "storage": 0, "declarations": [], "spell": "5:11-5:19|17262466801709381811|2|514", - "extent": "6:3-6:33|17262466801709381811|2|0", + "extent": "5:1-6:2|11072669167287398027|2|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index ab8af6b3..400b610f 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -21,7 +21,7 @@ OUTPUT: "storage": 0, "declarations": ["5:8-5:11|15041163540773201510|2|513"], "spell": "8:11-8:14|15041163540773201510|2|514", - "extent": "5:3-5:30|15041163540773201510|2|0", + "extent": "8:1-8:36|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/templates/implicit_variable_instantiation.cc b/index_tests/templates/implicit_variable_instantiation.cc index 7ec48af7..0c356b62 100644 --- a/index_tests/templates/implicit_variable_instantiation.cc +++ b/index_tests/templates/implicit_variable_instantiation.cc @@ -121,9 +121,9 @@ OUTPUT: "hover": "static constexpr ns::VarType ns::Holder::static_var = (ns::VarType)0", "declarations": ["6:30-6:40|12688716854043726585|2|513"], "spell": "10:37-10:47|12688716854043726585|2|514", - "extent": "6:5-6:55|12688716854043726585|2|0", + "extent": "9:3-10:47|11072669167287398027|2|0", "type": 1532099849728741556, - "uses": ["13:26-13:36|12688716854043726585|2|12", "14:27-14:37|12688716854043726585|2|12"], + "uses": ["13:26-13:36|11072669167287398027|2|12", "14:27-14:37|11072669167287398027|2|12"], "kind": 13, "storage": 2 }, { diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 9e0fe0cb..94b33653 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -31,7 +31,7 @@ OUTPUT: "storage": 0, "declarations": [], "spell": "10:22-10:25|17649312483543982122|2|514", - "extent": "3:3-3:13|17649312483543982122|2|0", + "extent": "9:1-10:30|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -47,7 +47,7 @@ OUTPUT: "storage": 0, "declarations": ["3:8-3:11|17107291254533526269|2|513"], "spell": "7:19-7:22|17107291254533526269|2|514", - "extent": "3:3-3:13|17107291254533526269|2|0", + "extent": "6:1-7:24|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/func_called_from_constructor.cc b/index_tests/usage/func_called_from_constructor.cc index d109e087..9757455b 100644 --- a/index_tests/usage/func_called_from_constructor.cc +++ b/index_tests/usage/func_called_from_constructor.cc @@ -38,7 +38,7 @@ OUTPUT: "storage": 0, "declarations": ["4:3-4:6|15041163540773201510|2|513"], "spell": "7:6-7:9|15041163540773201510|2|514", - "extent": "4:3-4:8|15041163540773201510|2|0", + "extent": "7:1-9:2|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index 615d36a2..76c28471 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -124,7 +124,7 @@ OUTPUT: "storage": 0, "declarations": ["65:23-65:26|15041163540773201510|2|513"], "spell": "79:26-79:29|15041163540773201510|2|514", - "extent": "65:3-65:28|15041163540773201510|2|0", + "extent": "79:1-79:51|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_declare_param_prototype.cc b/index_tests/usage/type_usage_declare_param_prototype.cc index 36e88a1a..3326f28e 100644 --- a/index_tests/usage/type_usage_declare_param_prototype.cc +++ b/index_tests/usage/type_usage_declare_param_prototype.cc @@ -22,7 +22,7 @@ OUTPUT: "storage": 0, "declarations": ["3:6-3:9|0|1|1"], "spell": "4:6-4:9|0|1|2", - "extent": "3:1-3:23|0|1|0", + "extent": "4:1-4:26|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_on_return_type.cc b/index_tests/usage/type_usage_on_return_type.cc index 3669d942..35377779 100644 --- a/index_tests/usage/type_usage_on_return_type.cc +++ b/index_tests/usage/type_usage_on_return_type.cc @@ -31,7 +31,7 @@ OUTPUT: "storage": 0, "declarations": ["9:8-9:13|15041163540773201510|2|513"], "spell": "13:11-13:16|15041163540773201510|2|514", - "extent": "9:3-9:15|15041163540773201510|2|0", + "extent": "13:1-13:21|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -47,7 +47,7 @@ OUTPUT: "storage": 0, "declarations": ["3:7-3:10|0|1|1", "4:7-4:10|0|1|1"], "spell": "5:7-5:10|0|1|2", - "extent": "3:1-3:12|0|1|0", + "extent": "5:1-5:32|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -77,7 +77,7 @@ OUTPUT: "storage": 0, "declarations": ["8:9-8:12|15041163540773201510|2|513"], "spell": "12:12-12:15|15041163540773201510|2|514", - "extent": "8:3-8:17|15041163540773201510|2|0", + "extent": "12:1-12:40|0|1|0", "declaring_type": 0, "bases": [], "derived": [], @@ -93,7 +93,7 @@ OUTPUT: "storage": 0, "declarations": ["17:14-17:17|0|1|1"], "spell": "18:14-18:17|0|1|2", - "extent": "17:1-17:19|0|1|0", + "extent": "18:1-18:39|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/type_usage_various.cc b/index_tests/usage/type_usage_various.cc index 93302743..5e6e6ac2 100644 --- a/index_tests/usage/type_usage_various.cc +++ b/index_tests/usage/type_usage_various.cc @@ -23,7 +23,7 @@ OUTPUT: "storage": 0, "declarations": ["2:8-2:12|15041163540773201510|2|513"], "spell": "5:11-5:15|15041163540773201510|2|514", - "extent": "2:3-2:14|15041163540773201510|2|0", + "extent": "5:1-8:2|0|1|0", "declaring_type": 0, "bases": [], "derived": [], diff --git a/index_tests/usage/usage_inside_of_call.cc b/index_tests/usage/usage_inside_of_call.cc index 412d94c1..15c45125 100644 --- a/index_tests/usage/usage_inside_of_call.cc +++ b/index_tests/usage/usage_inside_of_call.cc @@ -147,9 +147,9 @@ OUTPUT: "hover": "int Foo::static_var = 0", "declarations": ["6:14-6:24|15041163540773201510|2|513"], "spell": "10:10-10:20|15041163540773201510|2|514", - "extent": "6:3-6:24|15041163540773201510|2|0", + "extent": "10:1-10:24|0|1|0", "type": 53, - "uses": ["14:45-14:55|15041163540773201510|2|12"], + "uses": ["14:45-14:55|0|1|12"], "kind": 13, "storage": 2 }] diff --git a/index_tests/usage/var_usage_cstyle_cast.cc b/index_tests/usage/var_usage_cstyle_cast.cc index 18372325..91299674 100644 --- a/index_tests/usage/var_usage_cstyle_cast.cc +++ b/index_tests/usage/var_usage_cstyle_cast.cc @@ -70,7 +70,7 @@ OUTPUT: "hover": "static constexpr VarType Holder::static_var = (VarType)0", "declarations": ["4:28-4:38|10028537921178202800|2|513"], "spell": "7:23-7:33|10028537921178202800|2|514", - "extent": "4:3-4:53|10028537921178202800|2|0", + "extent": "7:1-7:33|0|1|0", "type": 5792006888140599735, "uses": [], "kind": 13, diff --git a/index_tests/vars/class_static_member.cc b/index_tests/vars/class_static_member.cc index 3e6689ce..0c94d4a7 100644 --- a/index_tests/vars/class_static_member.cc +++ b/index_tests/vars/class_static_member.cc @@ -49,7 +49,7 @@ OUTPUT: "hover": "Foo *Foo::member = nullptr", "declarations": ["2:15-2:21|15041163540773201510|2|513"], "spell": "4:11-4:17|15041163540773201510|2|514", - "extent": "2:3-2:21|15041163540773201510|2|0", + "extent": "4:1-4:27|0|1|0", "type": 15041163540773201510, "uses": [], "kind": 13, diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 928d36b5..4f272606 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -80,7 +80,7 @@ bool VFS::Stamp(const std::string& file, int64_t ts) { void VFS::ResetLocked(const std::string& file) { State& st = state[file]; - if (st.owner == g_thread_id) + if (st.owner == 0 || st.owner == g_thread_id) st.stage = 0; } diff --git a/src/file_consumer.h b/src/file_consumer.h index 5fb8e260..a2ec0129 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -7,9 +7,8 @@ #include #include -#include -#include #include +#include #include struct IndexFile; @@ -43,6 +42,17 @@ struct VFS { void Reset(const std::string& file); }; +namespace std { +template <> +struct hash { + std::size_t operator()(llvm::sys::fs::UniqueID ID) const { + size_t ret = ID.getDevice(); + hash_combine(ret, ID.getFile()); + return ret; + } +}; +} + // FileConsumer is used by the indexer. When it encouters a file, it tries to // take ownership over it. If the indexer has ownership over a file, it will // produce an index, otherwise, it will emit nothing for that declarations @@ -66,7 +76,7 @@ struct FileConsumer { std::vector> TakeLocalState(); private: - std::map> local_; + std::unordered_map> local_; VFS* vfs_; std::string parse_file_; int thread_id_; diff --git a/src/indexer.cc b/src/indexer.cc index 90512fa5..944de9e6 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -14,8 +14,8 @@ using ccls::Intern; #include #include #include -#include #include +#include using namespace clang; using llvm::Timer; @@ -35,19 +35,10 @@ struct IndexParam { std::unordered_map file2write_time; llvm::DenseMap Decl2usr; - // Only use this when strictly needed (ie, primary translation unit is - // needed). Most logic should get the IndexFile instance via - // |file_consumer|. - // - // This can be null if we're not generating an index for the primary - // translation unit. - IndexFile* primary_file = nullptr; - ASTUnit& Unit; ASTContext* Ctx; FileConsumer* file_consumer = nullptr; - NamespaceHelper ns; IndexParam(ASTUnit& Unit, FileConsumer* file_consumer) : Unit(Unit), file_consumer(file_consumer) {} @@ -455,7 +446,7 @@ public: #endif SourceLocation Spell = SM.getSpellingLoc(Loc); Loc = SM.getFileLoc(Loc); - Range loc = FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Loc, Loc)); + Range loc = FromTokenRange(SM, Lang, SourceRange(Loc, Loc)); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc)); if (!FE) { // TODO @@ -465,7 +456,7 @@ public: FE = SM.getFileEntryForID(SM.getFileID(P.first)); #else auto R = SM.getExpansionRange(Loc); - loc = FromTokenRange(SM, Ctx->getLangOpts(), R.getAsRange()); + loc = FromTokenRange(SM, Lang, R.getAsRange()); FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); #endif if (!FE) @@ -475,11 +466,9 @@ public: if (!db) return true; - const DeclContext *SemDC = D->getDeclContext(); - const DeclContext *LexDC = D->getLexicalDeclContext(); - (void)SemDC; - (void)LexDC; - Range extent = FromTokenRange(SM, Lang, D->getSourceRange()); + const Decl* OrigD = ASTNode.OrigD; + const DeclContext *SemDC = OrigD->getDeclContext(); + const DeclContext *LexDC = OrigD->getLexicalDeclContext(); Role role = static_cast(Roles); bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); @@ -501,13 +490,14 @@ public: auto do_def_decl = [&](auto *entity) { if (!entity->def.detailed_name[0]) { SetName(D, short_name, qualified, entity->def); - if (g_config->index.comments) + if (entity->def.comments[0] == '\0' && g_config->index.comments) entity->def.comments = Intern(GetComment(D)); } if (is_def) { - entity->def.spell = GetUse(db, loc, LexDC, role); - // extent may come from a declaration. - entity->def.extent = GetUse(db, extent, LexDC, Role::None); + entity->def.spell = GetUse(db, loc, SemDC, role); + entity->def.extent = + GetUse(db, FromTokenRange(SM, Lang, OrigD->getSourceRange()), LexDC, + Role::None); } else if (is_decl) { entity->declarations.push_back(GetUse(db, loc, LexDC, role)); } else { @@ -734,7 +724,8 @@ public: break; case Decl::EnumConstant: var->def.kind = lsSymbolKind::EnumMember; - if (is_def) { + // TODO Pretty printer may print = + if (is_def && strchr(var->def.detailed_name, '=') == nullptr) { auto *ECD = cast(D); const auto &Val = ECD->getInitVal(); std::string init = @@ -764,6 +755,26 @@ class IndexPPCallbacks : public PPCallbacks { public: IndexPPCallbacks(SourceManager& SM, IndexParam& param) : SM(SM), param(param) {} + void InclusionDirective(SourceLocation HashLoc, const Token &Tok, + StringRef Included, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, + StringRef SearchPath, StringRef RelativePath, + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { + if (!File) + return; + llvm::sys::fs::UniqueID UniqueID; + SourceRange R = FilenameRange.getAsRange(); + auto spell = FromCharRange(SM, param.Ctx->getLangOpts(), R, &UniqueID); + const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(R.getBegin())); + if (!FE) + return; + if (IndexFile *db = param.ConsumeFile(*FE)) { + std::string file_name = FileName(*File); + if (file_name.size()) + db->includes.push_back({spell.start.line, std::move(file_name)}); + } + } void MacroDefined(const Token &Tok, const MacroDirective *MD) override { llvm::sys::fs::UniqueID UniqueID; SourceLocation L = MD->getLocation(); @@ -803,8 +814,10 @@ public: } void MacroUndefined(const Token &Tok, const MacroDefinition &MD, const MacroDirective *UD) override { - SourceLocation L = UD->getLocation(); - MacroExpands(Tok, MD, {L, L}, nullptr); + if (UD) { + SourceLocation L = UD->getLocation(); + MacroExpands(Tok, MD, {L, L}, nullptr); + } } void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override { llvm::sys::fs::UniqueID UniqueID; @@ -879,20 +892,27 @@ void Uniquify(std::vector& uses) { uses.resize(n); } -std::vector> ClangIndexer::Index( + +namespace ccls::idx { +void IndexInit() { + // This calls llvm::InitializeAllTargets() ... for us, we would otherwise link + // all target libraries. + CXIndex CXIdx = clang_createIndex(0, 0); + clang_disposeIndex(CXIdx); +} + +std::vector> Index( VFS* vfs, - std::string file, + const std::string& opt_wdir, + const std::string& file, const std::vector& args, const std::vector& file_contents) { if (!g_config->index.enabled) return {}; - file = NormalizePath(file); - std::vector Args; for (auto& arg: args) Args.push_back(arg.c_str()); - Args.push_back("-fno-spell-checking"); auto PCHCO = std::make_shared(); IntrusiveRefCntPtr Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); @@ -900,8 +920,12 @@ std::vector> ClangIndexer::Index( createInvocationFromCommandLine(Args, Diags); if (!CI) return {}; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; + // -fparse-all-comments enables documentation in the indexer and in + // code completion. + CI->getLangOpts()->CommentOpts.ParseAllComments = + g_config->index.comments > 1; CI->getLangOpts()->RetainCommentsFromSystemHeaders = true; + CI->getLangOpts()->SpellChecking = false; std::vector> BufOwner; for (auto &c : file_contents) { @@ -927,31 +951,42 @@ std::vector> ClangIndexer::Index( std::unique_ptr IndexAction = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); - llvm::CrashRecoveryContextCleanupRegistrar IndexActionCleanup( - IndexAction.get()); DiagnosticErrorTrap DiagTrap(*Diags); - bool Success = ASTUnit::LoadFromCompilerInvocationAction( - std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), - /*Persistent=*/true, "/home/maskray/Dev/llvm/release/lib/clang/7.0.0", - /*OnlyLocalDecls=*/true, - /*CaptureDiagnostics=*/true, 0, false, false, true); + bool success = false; + llvm::CrashRecoveryContext CRC; + { + auto compile = [&]() { + success = ASTUnit::LoadFromCompilerInvocationAction( + std::move(CI), PCHCO, Diags, IndexAction.get(), Unit.get(), + /*Persistent=*/true, /*ResourceDir=*/"", + /*OnlyLocalDecls=*/true, + /*CaptureDiagnostics=*/true, 0, false, false, true); + }; + const char *env = getenv("CCLS_CRASH_RECOVERY"); + if (env && strcmp(env, "0") == 0) + compile(); + else + CRC.RunSafely(compile); + } + if (!Unit) { LOG_S(ERROR) << "failed to index " << file; return {}; } - if (!Success) + if (!success) { + LOG_S(ERROR) << "clang crashed for " << file; return {}; + } // ClangCursor(clang_getTranslationUnitCursor(tu->cx_tu)) // .VisitChildren(&VisitMacroDefinitionAndExpansions, ¶m); const SourceManager& SM = Unit->getSourceManager(); const FileEntry* FE = SM.getFileEntryForID(SM.getMainFileID()); - param.primary_file = param.ConsumeFile(*FE); + IndexFile* main_file = param.ConsumeFile(*FE); std::unordered_map inc_to_line; - // TODO - if (param.primary_file) - for (auto& inc : param.primary_file->includes) + if (main_file) + for (auto& inc : main_file->includes) inc_to_line[inc.resolved_path] = inc.line; auto result = param.file_consumer->TakeLocalState(); @@ -972,7 +1007,7 @@ std::vector> ClangIndexer::Index( for (auto& it : entry->usr2var) Uniquify(it.second.uses); - if (param.primary_file) { + if (main_file) { // If there are errors, show at least one at the include position. auto it = inc_to_line.find(entry->path); if (it != inc_to_line.end()) { @@ -982,7 +1017,7 @@ std::vector> ClangIndexer::Index( continue; ls_diagnostic.range = lsRange{lsPosition{line, 10}, lsPosition{line, 10}}; - param.primary_file->diagnostics_.push_back(ls_diagnostic); + main_file->diagnostics_.push_back(ls_diagnostic); break; } } @@ -1000,11 +1035,6 @@ std::vector> ClangIndexer::Index( return result; } - -void IndexInit() { - // InitLLVM - CXIndex CXIdx = clang_createIndex(0, 0); - clang_disposeIndex(CXIdx); } // |SymbolRef| is serialized this way. diff --git a/src/indexer.h b/src/indexer.h index 9deae62d..681d2436 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -285,22 +285,11 @@ struct IndexFile { std::string ToString(); }; -struct NamespaceHelper { - std::unordered_map usr2qualified_name; - - std::tuple QualifiedName( - const CXIdxContainerInfo* container, - std::string_view unqualified_name); -}; - -bool ConcatTypeAndName(std::string& type, const std::string& name); - +namespace ccls::idx { void IndexInit(); -struct ClangIndexer { - std::vector> Index( - VFS* vfs, - std::string file, - const std::vector& args, - const std::vector& file_contents); -}; +std::vector> +Index(VFS *vfs, const std::string &opt_wdir, const std::string &file, + const std::vector &args, + const std::vector &file_contents); +} diff --git a/src/main.cc b/src/main.cc index 6f85f630..495f8c47 100644 --- a/src/main.cc +++ b/src/main.cc @@ -59,7 +59,7 @@ int main(int argc, char** argv) { } pipeline::Init(); - IndexInit(); + idx::IndexInit(); bool language_server = true; diff --git a/src/pipeline.cc b/src/pipeline.cc index 3d960b9e..2105bc1d 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -152,8 +152,7 @@ std::unique_ptr RawCacheLoad( bool Indexer_Parse(DiagnosticsPublisher* diag_pub, WorkingFiles* working_files, Project* project, - VFS* vfs, - ClangIndexer* indexer) { + VFS* vfs) { std::optional opt_request = index_request->TryPopFront(); if (!opt_request) return false; @@ -235,7 +234,7 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub, LOG_S(INFO) << "parse " << path_to_index; - auto indexes = indexer->Index(vfs, path_to_index, entry.args, {}); + auto indexes = idx::Index(vfs, entry.directory, path_to_index, entry.args, {}); if (indexes.empty()) { if (g_config->index.enabled && request.id.Valid()) { @@ -309,11 +308,8 @@ void Indexer_Main(DiagnosticsPublisher* diag_pub, VFS* vfs, Project* project, WorkingFiles* working_files) { - // Build one index per-indexer, as building the index acquires a global lock. - ClangIndexer indexer; - while (true) - if (!Indexer_Parse(diag_pub, working_files, project, vfs, &indexer)) + if (!Indexer_Parse(diag_pub, working_files, project, vfs)) indexer_waiter->Wait(index_request); } diff --git a/src/project.cc b/src/project.cc index db65eb68..202e7510 100644 --- a/src/project.cc +++ b/src/project.cc @@ -186,11 +186,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( // what ccls uses. Make sure we do not emit warnings for mismatched options. args.push_back("-Wno-unknown-warning-option"); - // Using -fparse-all-comments enables documentation in the indexer and in - // code completion. - if (g_config->index.comments > 1) - args.push_back("-fparse-all-comments"); - + result.directory = entry.directory; result.args = std::move(args); return result; } diff --git a/src/project.h b/src/project.h index f56f4b55..acb55495 100644 --- a/src/project.h +++ b/src/project.h @@ -13,6 +13,7 @@ struct WorkingFiles; struct Project { struct Entry { + std::string directory; std::string filename; std::vector args; // If true, this entry is inferred and was not read from disk. diff --git a/src/test.cc b/src/test.cc index c5c940a3..0c89f688 100644 --- a/src/test.cc +++ b/src/test.cc @@ -246,7 +246,6 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { bool update_all = false; // FIXME: show diagnostics in STL/headers when running tests. At the moment // this can be done by constructing ClangIndex index(1, 1); - ClangIndexer index; GetFilesInFolder( "index_tests", true /*recursive*/, true /*add_folder_to_path*/, [&](const std::string& path) { @@ -290,7 +289,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) { // Run test. g_config = new Config; VFS vfs; - auto dbs = index.Index(&vfs, path, flags, {}); + auto dbs = ccls::idx::Index(&vfs, "", path, flags, {}); for (const auto& entry : all_expected_output) { const std::string& expected_path = entry.first;