diff --git a/clang-tools-extra/clangd/index/remote/Index.proto b/clang-tools-extra/clangd/index/remote/Index.proto --- a/clang-tools-extra/clangd/index/remote/Index.proto +++ b/clang-tools-extra/clangd/index/remote/Index.proto @@ -12,6 +12,7 @@ // Semantics of SymbolIndex match clangd::SymbolIndex with all required // structures corresponding to their clangd::* counterparts. +// NOTE: Enum values are offset by one to detect missing values. service SymbolIndex { rpc Lookup(LookupRequest) returns (stream LookupReply) {} diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp --- a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp +++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp @@ -112,7 +112,7 @@ if (!IDs) return IDs.takeError(); Req.IDs = std::move(*IDs); - Req.Filter = static_cast(Message->filter()); + Req.Filter = static_cast(Message->filter() - 1); if (Message->limit()) Req.Limit = Message->limit(); return Req; @@ -125,7 +125,7 @@ if (!IDs) return IDs.takeError(); Req.Subjects = std::move(*IDs); - Req.Predicate = static_cast(Message->predicate()); + Req.Predicate = static_cast(Message->predicate() - 1); if (Message->limit()) Req.Limit = Message->limit(); return Req; @@ -152,7 +152,7 @@ return Declaration.takeError(); Result.CanonicalDeclaration = *Declaration; Result.References = Message.references(); - Result.Origin = static_cast(Message.origin()); + Result.Origin = static_cast(Message.origin() - 1); Result.Signature = Message.signature(); Result.TemplateSpecializationArgs = Message.template_specialization_args(); Result.CompletionSnippetSuffix = Message.completion_snippet_suffix(); @@ -165,7 +165,7 @@ return SerializedHeader.takeError(); Result.IncludeHeaders.push_back(*SerializedHeader); } - Result.Flags = static_cast(Message.flags()); + Result.Flags = static_cast(Message.flags() - 1); return Result; } @@ -177,7 +177,7 @@ if (!Location) return Location.takeError(); Result.Location = *Location; - Result.Kind = static_cast(Message.kind()); + Result.Kind = static_cast(Message.kind() - 1); return Result; } @@ -226,7 +226,7 @@ RefsRequest RPCRequest; for (const auto &ID : From.IDs) RPCRequest.add_ids(ID.str()); - RPCRequest.set_filter(static_cast(From.Filter)); + RPCRequest.set_filter(static_cast(From.Filter) + 1); if (From.Limit) RPCRequest.set_limit(*From.Limit); return RPCRequest; @@ -236,7 +236,7 @@ RelationsRequest RPCRequest; for (const auto &ID : From.Subjects) RPCRequest.add_subjects(ID.str()); - RPCRequest.set_predicate(static_cast(From.Predicate)); + RPCRequest.set_predicate(static_cast(From.Predicate) + 1); if (From.Limit) RPCRequest.set_limit(*From.Limit); return RPCRequest; @@ -259,7 +259,7 @@ return Declaration.takeError(); *Result.mutable_canonical_declaration() = *Declaration; Result.set_references(From.References); - Result.set_origin(static_cast(From.Origin)); + Result.set_origin(static_cast(From.Origin) + 1); Result.set_signature(From.Signature.str()); Result.set_template_specialization_args( From.TemplateSpecializationArgs.str()); @@ -274,13 +274,13 @@ auto *NextHeader = Result.add_headers(); *NextHeader = *Serialized; } - Result.set_flags(static_cast(From.Flags)); + Result.set_flags(static_cast(From.Flags) + 1); return Result; } llvm::Expected Marshaller::toProtobuf(const clangd::Ref &From) { Ref Result; - Result.set_kind(static_cast(From.Kind)); + Result.set_kind(static_cast(From.Kind) + 1); auto Location = toProtobuf(From.Location); if (!Location) return Location.takeError(); @@ -352,20 +352,24 @@ clang::index::SymbolInfo Marshaller::fromProtobuf(const SymbolInfo &Message) { clang::index::SymbolInfo Result; - Result.Kind = static_cast(Message.kind()); - Result.SubKind = static_cast(Message.subkind()); - Result.Lang = static_cast(Message.language()); + // Enum values are offset by one to detect missing values. + Result.Kind = static_cast(Message.kind() - 1); + Result.SubKind = + static_cast(Message.subkind() - 1); + Result.Lang = + static_cast(Message.language() - 1); Result.Properties = - static_cast(Message.properties()); + static_cast(Message.properties() - 1); return Result; } SymbolInfo Marshaller::toProtobuf(const clang::index::SymbolInfo &Info) { SymbolInfo Result; - Result.set_kind(static_cast(Info.Kind)); - Result.set_subkind(static_cast(Info.SubKind)); - Result.set_language(static_cast(Info.Lang)); - Result.set_properties(static_cast(Info.Properties)); + // Enum values are offset by one to detect missing values. + Result.set_kind(static_cast(Info.Kind) + 1); + Result.set_subkind(static_cast(Info.SubKind) + 1); + Result.set_language(static_cast(Info.Lang) + 1); + Result.set_properties(static_cast(Info.Properties) + 1); return Result; } diff --git a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp --- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp +++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp @@ -377,7 +377,8 @@ EXPECT_EQ(static_cast(Serialized.subjects_size()), Request.Subjects.size()); EXPECT_EQ(Serialized.limit(), Request.Limit); - EXPECT_EQ(static_cast(Serialized.predicate()), + // Serialized enums are offset by one. + EXPECT_EQ(static_cast(Serialized.predicate() - 1), Request.Predicate); auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized); ASSERT_TRUE(bool(Deserialized));