kbobyrev created this revision.
kbobyrev added a reviewer: sammccall.
Herald added subscribers: usaxena95, kadircet, arphaman.
kbobyrev requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112209

Files:
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

Index: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -103,6 +103,34 @@
           "struct ^X { enum ^Language { ^CXX = 42, Python = 9000}; };",
           "int Lang = X::CXX;",
       },
+      {
+          "enum class Color;",
+          "enum class Color {};",
+      },
+      {
+          "enum class ^Color : int;",
+          "enum class Color : int {};",
+      },
+      {
+          "enum class Color : int {};",
+          "enum class Color : int;",
+      },
+      {
+          "enum class Color;",
+          "enum class Color {}; Color c;",
+      },
+      {
+          "enum class ^Color : char;",
+          "Color c;",
+      },
+      {
+          "enum class ^Color : char {};",
+          "Color c;",
+      },
+      {
+          "enum class ^Color;",
+          "Color c;",
+      },
       {
           // When a type is resolved via a using declaration, the
           // UsingShadowDecl is not referenced in the AST.
Index: clang-tools-extra/clangd/IncludeCleaner.cpp
===================================================================
--- clang-tools-extra/clangd/IncludeCleaner.cpp
+++ clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -35,6 +35,16 @@
   }
 
   bool VisitTagType(TagType *TT) {
+    // For enumerations we will require only the definition if it's present and
+    // the underlying type is not specified.
+    if (TT->isEnumeralType()) {
+      const auto *Enum = llvm::dyn_cast<EnumDecl>(TT->getDecl());
+      assert(Enum);
+      if (!Enum->getIntegerTypeSourceInfo() && TT->getDecl()->getDefinition()) {
+        Result.insert(TT->getDecl()->getDefinition()->getLocation());
+        return true;
+      }
+    }
     add(TT->getDecl());
     return true;
   }
@@ -67,29 +77,35 @@
   }
 
   bool TraverseType(QualType T) {
-    if (isNew(T.getTypePtrOrNull())) { // don't care about quals
+    if (isNew(T.getTypePtrOrNull())) // don't care about quals
       Base::TraverseType(T);
-    }
     return true;
   }
 
   bool VisitUsingDecl(UsingDecl *D) {
-    for (const auto *Shadow : D->shadows()) {
+    for (const auto *Shadow : D->shadows())
       add(Shadow->getTargetDecl());
-    }
     return true;
   }
 
+  // Require redeclarations only for definitions and only when the underlying
+  // type is specified.
+  bool VisitEnumDecl(EnumDecl *D) {
+    if (D != D->getDefinition() || !D->getIntegerTypeSourceInfo())
+      return false;
+    for (const auto *Redecl : D->redecls())
+      Result.insert(Redecl->getLocation());
+    return false;
+  }
+
 private:
   using Base = RecursiveASTVisitor<ReferencedLocationCrawler>;
 
   void add(const Decl *D) {
-    if (!D || !isNew(D->getCanonicalDecl())) {
+    if (!D || !isNew(D->getCanonicalDecl()))
       return;
-    }
-    for (const Decl *Redecl : D->redecls()) {
+    for (const Decl *Redecl : D->redecls())
       Result.insert(Redecl->getLocation());
-    }
   }
 
   bool isNew(const void *P) { return P && Visited.insert(P).second; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to