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

Reply via email to