[clang-tools-extra] r322509 - [clangd] Improve const-correctness of Symbol->Detail. NFC
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 15 12:09:09 PST 2018
Author: sammccall
Date: Mon Jan 15 12:09:09 2018
New Revision: 322509
URL: http://llvm.org/viewvc/llvm-project?rev=322509&view=rev
Log:
[clangd] Improve const-correctness of Symbol->Detail. NFC
Summary:
This would have caught a bug I wrote in an early version of D42049, where
an index user could overwrite data internal to the index because the Symbol is
not deep-const.
The YAML traits are now a bit more verbose, but separate concerns a bit more
nicely: ArenaPtr can be reused for other similarly-allocated objects, including
scalars etc.
Reviewers: hokein
Subscribers: klimek, ilya-biryukov, cfe-commits, ioeric
Differential Revision: https://reviews.llvm.org/D42059
Modified:
clang-tools-extra/trunk/clangd/index/Index.cpp
clang-tools-extra/trunk/clangd/index/Index.h
clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
Modified: clang-tools-extra/trunk/clangd/index/Index.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.cpp?rev=322509&r1=322508&r2=322509&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Index.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Index.cpp Mon Jan 15 12:09:09 2018
@@ -64,13 +64,12 @@ static void own(Symbol &S, DenseSet<Stri
if (S.Detail) {
// Copy values of StringRefs into arena.
auto *Detail = Arena.Allocate<Symbol::Details>();
- Detail->Documentation = S.Detail->Documentation;
- Detail->CompletionDetail = S.Detail->CompletionDetail;
- S.Detail = Detail;
-
+ *Detail = *S.Detail;
// Intern the actual strings.
- Intern(S.Detail->Documentation);
- Intern(S.Detail->CompletionDetail);
+ Intern(Detail->Documentation);
+ Intern(Detail->CompletionDetail);
+ // Replace the detail pointer with our copy.
+ S.Detail = Detail;
}
}
Modified: clang-tools-extra/trunk/clangd/index/Index.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=322509&r1=322508&r2=322509&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Index.h (original)
+++ clang-tools-extra/trunk/clangd/index/Index.h Mon Jan 15 12:09:09 2018
@@ -156,7 +156,7 @@ struct Symbol {
};
// Optional details of the symbol.
- Details *Detail = nullptr; // FIXME: should be const
+ const Details *Detail = nullptr;
// FIXME: add definition location of the symbol.
// FIXME: add all occurrences support.
Modified: clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp?rev=322509&r1=322508&r2=322509&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolYAML.cpp Mon Jan 15 12:09:09 2018
@@ -60,27 +60,39 @@ template <> struct MappingTraits<SymbolI
}
};
-template <>
-struct MappingTraits<Symbol::Details *> {
- static void mapping(IO &io, Symbol::Details *&Detail) {
- if (!io.outputting()) {
- assert(io.getContext() && "Expecting an arena (as context) to allocate "
- "data for new symbols.");
- Detail = static_cast<llvm::BumpPtrAllocator *>(io.getContext())
- ->Allocate<Symbol::Details>();
- } else if (!Detail) {
- // Detail is optional in outputting.
- return;
- }
- assert(Detail);
- io.mapOptional("Documentation", Detail->Documentation);
- io.mapOptional("CompletionDetail", Detail->CompletionDetail);
+template <> struct MappingTraits<Symbol::Details> {
+ static void mapping(IO &io, Symbol::Details &Detail) {
+ io.mapOptional("Documentation", Detail.Documentation);
+ io.mapOptional("CompletionDetail", Detail.CompletionDetail);
}
};
+// A YamlIO normalizer for fields of type "const T*" allocated on an arena.
+// Normalizes to Optional<T>, so traits should be provided for T.
+template <typename T> struct ArenaPtr {
+ ArenaPtr(IO &) {}
+ ArenaPtr(IO &, const T *D) {
+ if (D)
+ Opt = *D;
+ }
+
+ const T *denormalize(IO &IO) {
+ assert(IO.getContext() && "Expecting an arena (as context) to allocate "
+ "data for read symbols.");
+ if (!Opt)
+ return nullptr;
+ return new (*static_cast<llvm::BumpPtrAllocator *>(IO.getContext()))
+ T(std::move(*Opt)); // Allocate a copy of Opt on the arena.
+ }
+
+ llvm::Optional<T> Opt;
+};
+
template <> struct MappingTraits<Symbol> {
static void mapping(IO &IO, Symbol &Sym) {
MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, Sym.ID);
+ MappingNormalization<ArenaPtr<Symbol::Details>, const Symbol::Details *>
+ NDetail(IO, Sym.Detail);
IO.mapRequired("ID", NSymbolID->HexString);
IO.mapRequired("Name", Sym.Name);
IO.mapRequired("Scope", Sym.Scope);
@@ -92,8 +104,7 @@ template <> struct MappingTraits<Symbol>
IO.mapOptional("CompletionSnippetInsertText",
Sym.CompletionSnippetInsertText);
- if (!IO.outputting() || Sym.Detail)
- IO.mapOptional("Detail", Sym.Detail);
+ IO.mapOptional("Detail", NDetail->Opt);
}
};
More information about the cfe-commits
mailing list