dgoldman created this revision. dgoldman added a reviewer: kadircet. Herald added subscribers: wenlei, usaxena95, arphaman. Herald added a project: All. dgoldman requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang-tools-extra.
The IncludeType contains both Include (the current behavior) and Import, which we can use in the future to provide #import suggestions for Objective-C files/symbols. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D128457 Files: clang-tools-extra/clangd/index/Merge.cpp clang-tools-extra/clangd/index/Serialization.cpp clang-tools-extra/clangd/index/Symbol.h clang-tools-extra/clangd/index/SymbolCollector.cpp clang-tools-extra/clangd/index/YAMLSerialization.cpp clang-tools-extra/clangd/index/remote/Index.proto clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h clang-tools-extra/clangd/test/index-serialization/Inputs/sample.idx clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp clang-tools-extra/clangd/unittests/IndexTests.cpp clang-tools-extra/clangd/unittests/SerializationTests.cpp
Index: clang-tools-extra/clangd/unittests/SerializationTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/SerializationTests.cpp +++ clang-tools-extra/clangd/unittests/SerializationTests.cpp @@ -53,8 +53,10 @@ IncludeHeaders: - Header: 'include1' References: 7 + Type: Include - Header: 'include2' References: 3 + Type: Import ... --- !Symbol @@ -114,8 +116,10 @@ MATCHER_P(id, I, "") { return arg.ID == cantFail(SymbolID::fromStr(I)); } MATCHER_P(qName, Name, "") { return (arg.Scope + arg.Name).str() == Name; } -MATCHER_P2(IncludeHeaderWithRef, IncludeHeader, References, "") { - return (arg.IncludeHeader == IncludeHeader) && (arg.References == References); +MATCHER_P3(IncludeHeaderWithRefAndType, IncludeHeader, References, IncludeType, + "") { + return (arg.IncludeHeader == IncludeHeader) && + (arg.References == References) && (arg.IncludeType == IncludeType); } auto readIndexFile(llvm::StringRef Text) { @@ -149,8 +153,9 @@ EXPECT_TRUE(Sym1.Flags & Symbol::IndexedForCodeCompletion); EXPECT_FALSE(Sym1.Flags & Symbol::Deprecated); EXPECT_THAT(Sym1.IncludeHeaders, - UnorderedElementsAre(IncludeHeaderWithRef("include1", 7u), - IncludeHeaderWithRef("include2", 3u))); + UnorderedElementsAre( + IncludeHeaderWithRefAndType("include1", 7u, Symbol::Include), + IncludeHeaderWithRefAndType("include2", 3u, Symbol::Import))); EXPECT_THAT(Sym2, qName("clang::Foo2")); EXPECT_EQ(Sym2.Signature, "-sig"); Index: clang-tools-extra/clangd/unittests/IndexTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/IndexTests.cpp +++ clang-tools-extra/clangd/unittests/IndexTests.cpp @@ -567,9 +567,9 @@ L.Name = "left"; R.Name = "right"; L.ID = R.ID = SymbolID("hello"); - L.IncludeHeaders.emplace_back("common", 1); - R.IncludeHeaders.emplace_back("common", 1); - R.IncludeHeaders.emplace_back("new", 1); + L.IncludeHeaders.emplace_back("common", 1, Symbol::Include); + R.IncludeHeaders.emplace_back("common", 1, Symbol::Include); + R.IncludeHeaders.emplace_back("new", 1, Symbol::Include); // Both have no definition. Symbol M = mergeSymbol(L, R); @@ -615,7 +615,7 @@ std::move(DynData), DynSize); SymbolSlab::Builder StaticB; - S.IncludeHeaders.push_back({"<header>", 0}); + S.IncludeHeaders.push_back({"<header>", 0, Symbol::Include}); StaticB.insert(S); auto StaticIndex = MemIndex::build(std::move(StaticB).build(), RefSlab(), RelationSlab()); Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -1069,7 +1069,7 @@ Sym.Flags |= Symbol::IndexedForCodeCompletion; Sym.CanonicalDeclaration.FileURI = S.DeclaringFile.c_str(); Sym.Definition.FileURI = S.DeclaringFile.c_str(); - Sym.IncludeHeaders.emplace_back(S.IncludeHeader, 1); + Sym.IncludeHeaders.emplace_back(S.IncludeHeader, 1, Symbol::Include); Slab.insert(Sym); } return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab()); @@ -1127,7 +1127,7 @@ Symbol Sym = enm("X"); Sym.Flags |= Symbol::IndexedForCodeCompletion; Sym.CanonicalDeclaration.FileURI = Sym.Definition.FileURI = "unittest:///x.h"; - Sym.IncludeHeaders.emplace_back("\"x.h\"", 1); + Sym.IncludeHeaders.emplace_back("\"x.h\"", 1, Symbol::Include); SymbolSlab::Builder Slab; Slab.insert(Sym); auto Index = @@ -1170,7 +1170,7 @@ Sym.Flags |= Symbol::IndexedForCodeCompletion; Sym.CanonicalDeclaration.FileURI = "unittest:///x.h"; Sym.Definition.FileURI = "unittest:///x.cc"; - Sym.IncludeHeaders.emplace_back("\"x.h\"", 1); + Sym.IncludeHeaders.emplace_back("\"x.h\"", 1, Symbol::Include); SymbolSlab::Builder Slab; Slab.insert(Sym); @@ -1491,7 +1491,7 @@ Symbol Sym = func("foo"); Sym.Flags |= Symbol::IndexedForCodeCompletion; Sym.CanonicalDeclaration.FileURI = "unittest:///foo.h"; - Sym.IncludeHeaders.emplace_back("\"foo.h\"", 1); + Sym.IncludeHeaders.emplace_back("\"foo.h\"", 1, Symbol::Include); SymbolSlab::Builder Slab; Slab.insert(Sym); Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -750,7 +750,7 @@ Symbol Sym = cls("ns::X"); Sym.CanonicalDeclaration.FileURI = BarURI.c_str(); - Sym.IncludeHeaders.emplace_back(BarURI, 1); + Sym.IncludeHeaders.emplace_back(BarURI, 1, Symbol::Include); // Shorten include path based on search directory and insert. Annotations Test("int main() { ns::^ }"); TU.Code = Test.code().str(); @@ -781,8 +781,8 @@ auto BarURI = URI::create(BarHeader).toString(); SymX.CanonicalDeclaration.FileURI = BarURI.c_str(); SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); - SymX.IncludeHeaders.emplace_back("<bar>", 1); - SymY.IncludeHeaders.emplace_back("<bar>", 1); + SymX.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include); + SymY.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include); // Shorten include path based on search directory and insert. auto Results = completions(R"cpp( namespace ns { @@ -1766,7 +1766,7 @@ // Differences in header-to-insert suppress bundling. std::string DeclFile = URI::create(testPath("foo")).toString(); NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str(); - NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1); + NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1, Symbol::Include); EXPECT_THAT( completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions, UnorderedElementsAre(AllOf(named("GFuncC"), insertInclude("<foo>")), @@ -1800,8 +1800,8 @@ SymX.CanonicalDeclaration.FileURI = BarURI.c_str(); SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); // The include header is different, but really it's the same file. - SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1); - SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1); + SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1, Symbol::Include); + SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1, Symbol::Include); auto Results = completions("void f() { ::ns::^ }", {SymX, SymY}, Opts); // Expect both results are bundled, despite the different-but-same @@ -2597,8 +2597,8 @@ std::string DeclFile = URI::create(testPath("foo")).toString(); Symbol Sym = func("Func"); Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); - Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); - Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); + Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include); + Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include); auto Results = completions("Fun^", {Sym}).Completions; assert(!Results.empty()); @@ -2617,8 +2617,8 @@ std::string DeclFile = URI::create(testPath("foo")).toString(); Symbol Sym = func("Func"); Sym.CanonicalDeclaration.FileURI = DeclFile.c_str(); - Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2); - Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); + Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include); + Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include); EXPECT_THAT(completions(TU, Test.point(), {Sym}).Completions, UnorderedElementsAre(AllOf(named("Func"), hasInclude("\"foo.h\""), Index: clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h =================================================================== --- clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h +++ clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h @@ -85,6 +85,9 @@ fromProtobuf(const SymbolLocation &Message); llvm::Expected<SymbolLocation> toProtobuf(const clangd::SymbolLocation &Location); + llvm::Expected<clangd::Symbol::IncludeType> + fromProtobuf(const IncludeType &Message); + IncludeType toProtobuf(const clangd::Symbol::IncludeType &IncludeType); llvm::Expected<HeaderWithReferences> toProtobuf(const clangd::Symbol::IncludeHeaderWithReferences &IncludeHeader); llvm::Expected<clangd::Symbol::IncludeHeaderWithReferences> Index: clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp =================================================================== --- clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp +++ clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp @@ -402,10 +402,36 @@ return Result; } +llvm::Expected<clangd::Symbol::IncludeType> +Marshaller::fromProtobuf(const IncludeType &Message) { + switch (Message) { + case IncludeType::INCLUDE_TYPE_UNKNOWN: + case IncludeType::INCLUDE_TYPE_INCLUDE: + return clangd::Symbol::IncludeType::Include; + case IncludeType::INCLUDE_TYPE_IMPORT: + return clangd::Symbol::IncludeType::Import; + default: + return error("unknown include type {0}", static_cast<int>(Message)); + } +} + +IncludeType +Marshaller::toProtobuf(const clangd::Symbol::IncludeType &IncludeType) { + switch (IncludeType) { + case clang::clangd::Symbol::IncludeType::Include: + return IncludeType::INCLUDE_TYPE_INCLUDE; + case clang::clangd::Symbol::IncludeType::Import: + return IncludeType::INCLUDE_TYPE_IMPORT; + default: + return IncludeType::INCLUDE_TYPE_INCLUDE; + } +} + llvm::Expected<HeaderWithReferences> Marshaller::toProtobuf( const clangd::Symbol::IncludeHeaderWithReferences &IncludeHeader) { HeaderWithReferences Result; Result.set_references(IncludeHeader.References); + Result.set_include_type(toProtobuf(IncludeHeader.IncludeType)); const std::string Header = IncludeHeader.IncludeHeader.str(); if (isLiteralInclude(Header)) { Result.set_header(Header); @@ -427,8 +453,11 @@ return URIString.takeError(); Header = *URIString; } - return clangd::Symbol::IncludeHeaderWithReferences{Strings.save(Header), - Message.references()}; + auto IncludeType = fromProtobuf(Message.include_type()); + if (!IncludeType) + return IncludeType.takeError(); + return clangd::Symbol::IncludeHeaderWithReferences{ + Strings.save(Header), Message.references(), *IncludeType}; } } // namespace remote Index: clang-tools-extra/clangd/index/remote/Index.proto =================================================================== --- clang-tools-extra/clangd/index/remote/Index.proto +++ clang-tools-extra/clangd/index/remote/Index.proto @@ -104,9 +104,16 @@ optional uint32 column = 2; } +enum IncludeType { + INCLUDE_TYPE_UNKNOWN = 0; + INCLUDE_TYPE_INCLUDE = 1; + INCLUDE_TYPE_IMPORT = 2; +} + message HeaderWithReferences { optional string header = 1; optional uint32 references = 2; + optional IncludeType include_type = 3; } message RelationsRequest { Index: clang-tools-extra/clangd/index/YAMLSerialization.cpp =================================================================== --- clang-tools-extra/clangd/index/YAMLSerialization.cpp +++ clang-tools-extra/clangd/index/YAMLSerialization.cpp @@ -165,12 +165,21 @@ } }; +template <> struct ScalarEnumerationTraits<clang::clangd::Symbol::IncludeType> { + static void enumeration(IO &IO, clang::clangd::Symbol::IncludeType &Value) { + IO.enumCase(Value, "Include", clang::clangd::Symbol::IncludeType::Include); + IO.enumCase(Value, "Import", clang::clangd::Symbol::IncludeType::Import); + } +}; + template <> struct MappingTraits<clang::clangd::Symbol::IncludeHeaderWithReferences> { static void mapping(IO &IO, clang::clangd::Symbol::IncludeHeaderWithReferences &Inc) { IO.mapRequired("Header", Inc.IncludeHeader); IO.mapRequired("References", Inc.References); + IO.mapOptional("Type", Inc.IncludeType, + clang::clangd::Symbol::IncludeType::Include); } }; Index: clang-tools-extra/clangd/index/SymbolCollector.cpp =================================================================== --- clang-tools-extra/clangd/index/SymbolCollector.cpp +++ clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -860,7 +860,7 @@ // Symbols in slabs aren't mutable, insert() has to walk all the strings if (!IncludeHeader.empty()) { Symbol NewSym = *S; - NewSym.IncludeHeaders.push_back({IncludeHeader, 1}); + NewSym.IncludeHeaders.push_back({IncludeHeader, 1, Symbol::Include}); Symbols.insert(NewSym); } } Index: clang-tools-extra/clangd/index/Symbol.h =================================================================== --- clang-tools-extra/clangd/index/Symbol.h +++ clang-tools-extra/clangd/index/Symbol.h @@ -84,12 +84,20 @@ /// Only set when the symbol is indexed for completion. llvm::StringRef Type; + enum IncludeType : uint8_t { + /// `#include "header.h"` + Include = 0, + /// `#import "header.h"` + Import = 1, + }; + struct IncludeHeaderWithReferences { IncludeHeaderWithReferences() = default; IncludeHeaderWithReferences(llvm::StringRef IncludeHeader, - unsigned References) - : IncludeHeader(IncludeHeader), References(References) {} + unsigned References, IncludeType IncludeType) + : IncludeHeader(IncludeHeader), References(References), + IncludeType(IncludeType) {} /// This can be either a URI of the header to be #include'd /// for this symbol, or a literal header quoted with <> or "" that is @@ -102,6 +110,8 @@ /// The number of translation units that reference this symbol and include /// this header. This number is only meaningful if aggregated in an index. unsigned References = 0; + /// Type of include to use when including this header, #include or #import. + IncludeType IncludeType = IncludeType::Include; }; /// One Symbol can potentially be included via different headers. /// - If we haven't seen a definition, this covers all declarations. Index: clang-tools-extra/clangd/index/Serialization.cpp =================================================================== --- clang-tools-extra/clangd/index/Serialization.cpp +++ clang-tools-extra/clangd/index/Serialization.cpp @@ -330,6 +330,7 @@ auto WriteInclude = [&](const Symbol::IncludeHeaderWithReferences &Include) { writeVar(Strings.index(Include.IncludeHeader), OS); writeVar(Include.References, OS); + OS.write(static_cast<uint8_t>(Include.IncludeType)); }; writeVar(Sym.IncludeHeaders.size(), OS); for (const auto &Include : Sym.IncludeHeaders) @@ -360,6 +361,7 @@ for (auto &I : Sym.IncludeHeaders) { I.IncludeHeader = Data.consumeString(Strings); I.References = Data.consumeVar(); + I.IncludeType = static_cast<Symbol::IncludeType>(Data.consume8()); } return Sym; } @@ -453,7 +455,7 @@ // The current versioning scheme is simple - non-current versions are rejected. // If you make a breaking change, bump this version number to invalidate stored // data. Later we may want to support some backward compatibility. -constexpr static uint32_t Version = 17; +constexpr static uint32_t Version = 18; llvm::Expected<IndexFileIn> readRIFF(llvm::StringRef Data, SymbolOrigin Origin) { Index: clang-tools-extra/clangd/index/Merge.cpp =================================================================== --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -246,14 +246,16 @@ for (const auto &OI : O.IncludeHeaders) { bool Found = false; for (auto &SI : S.IncludeHeaders) { - if (SI.IncludeHeader == OI.IncludeHeader) { + if (SI.IncludeHeader == OI.IncludeHeader && + SI.IncludeType == OI.IncludeType) { Found = true; SI.References += OI.References; break; } } if (!Found && MergeIncludes) - S.IncludeHeaders.emplace_back(OI.IncludeHeader, OI.References); + S.IncludeHeaders.emplace_back(OI.IncludeHeader, OI.References, + OI.IncludeType); } S.Origin |= O.Origin | SymbolOrigin::Merge;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits