This revision was automatically updated to reflect the committed changes.
Closed by commit rL278546: Analyze include order on a per-file basis. (authored 
by zturner).

Changed prior to commit:
  https://reviews.llvm.org/D23434?vs=67777&id=67876#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D23434

Files:
  clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp
  clang-tools-extra/trunk/test/clang-tidy/Inputs/Headers/cross-file-a.h
  clang-tools-extra/trunk/test/clang-tidy/Inputs/Headers/cross-file-b.h
  clang-tools-extra/trunk/test/clang-tidy/Inputs/Headers/cross-file-c.h
  clang-tools-extra/trunk/test/clang-tidy/clang-cl-driver.cpp
  clang-tools-extra/trunk/test/clang-tidy/llvm-include-order.cpp

Index: clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp
===================================================================
--- clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/llvm/IncludeOrderCheck.cpp
@@ -12,6 +12,8 @@
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
 
+#include <map>
+
 namespace clang {
 namespace tidy {
 namespace llvm {
@@ -37,7 +39,9 @@
     bool IsAngled;         ///< true if this was an include with angle brackets
     bool IsMainModule;     ///< true if this was the first include in a file
   };
-  std::vector<IncludeDirective> IncludeDirectives;
+
+  typedef std::vector<IncludeDirective> FileIncludes;
+  std::map<clang::FileID, FileIncludes> IncludeDirectives;
   bool LookForMainModule;
 
   ClangTidyCheck &Check;
@@ -80,7 +84,9 @@
     ID.IsMainModule = true;
     LookForMainModule = false;
   }
-  IncludeDirectives.push_back(std::move(ID));
+
+  // Bucket the include directives by the id of the file they were declared in.
+  IncludeDirectives[SM.getFileID(HashLoc)].push_back(std::move(ID));
 }
 
 void IncludeOrderPPCallbacks::EndOfMainFile() {
@@ -95,69 +101,73 @@
   // FIXME: We should be more careful about sorting below comments as we don't
   // know if the comment refers to the next include or the whole block that
   // follows.
-  std::vector<unsigned> Blocks(1, 0);
-  for (unsigned I = 1, E = IncludeDirectives.size(); I != E; ++I)
-    if (SM.getExpansionLineNumber(IncludeDirectives[I].Loc) !=
-        SM.getExpansionLineNumber(IncludeDirectives[I - 1].Loc) + 1)
-      Blocks.push_back(I);
-  Blocks.push_back(IncludeDirectives.size()); // Sentinel value.
-
-  // Get a vector of indices.
-  std::vector<unsigned> IncludeIndices;
-  for (unsigned I = 0, E = IncludeDirectives.size(); I != E; ++I)
-    IncludeIndices.push_back(I);
-
-  // Sort the includes. We first sort by priority, then lexicographically.
-  for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI)
-    std::sort(IncludeIndices.begin() + Blocks[BI],
-              IncludeIndices.begin() + Blocks[BI + 1],
-              [this](unsigned LHSI, unsigned RHSI) {
-      IncludeDirective &LHS = IncludeDirectives[LHSI];
-      IncludeDirective &RHS = IncludeDirectives[RHSI];
-
-      int PriorityLHS =
-          getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule);
-      int PriorityRHS =
-          getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule);
-
-      return std::tie(PriorityLHS, LHS.Filename) <
-             std::tie(PriorityRHS, RHS.Filename);
-    });
-
-  // Emit a warning for each block and fixits for all changes within that block.
-  for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) {
-    // Find the first include that's not in the right position.
-    unsigned I, E;
-    for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I)
-      if (IncludeIndices[I] != I)
-        break;
-
-    if (I == E)
-      continue;
-
-    // Emit a warning.
-    auto D = Check.diag(IncludeDirectives[I].Loc,
-                        "#includes are not sorted properly");
-
-    // Emit fix-its for all following includes in this block.
-    for (; I != E; ++I) {
-      if (IncludeIndices[I] == I)
-        continue;
-      const IncludeDirective &CopyFrom = IncludeDirectives[IncludeIndices[I]];
-
-      SourceLocation FromLoc = CopyFrom.Range.getBegin();
-      const char *FromData = SM.getCharacterData(FromLoc);
-      unsigned FromLen = std::strcspn(FromData, "\n");
+  for (auto &Bucket : IncludeDirectives) {
+    auto &FileDirectives = Bucket.second;
+    std::vector<unsigned> Blocks(1, 0);
+    for (unsigned I = 1, E = FileDirectives.size(); I != E; ++I)
+      if (SM.getExpansionLineNumber(FileDirectives[I].Loc) !=
+          SM.getExpansionLineNumber(FileDirectives[I - 1].Loc) + 1)
+        Blocks.push_back(I);
+    Blocks.push_back(FileDirectives.size()); // Sentinel value.
+
+    // Get a vector of indices.
+    std::vector<unsigned> IncludeIndices;
+    for (unsigned I = 0, E = FileDirectives.size(); I != E; ++I)
+      IncludeIndices.push_back(I);
+
+    // Sort the includes. We first sort by priority, then lexicographically.
+    for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI)
+      std::sort(IncludeIndices.begin() + Blocks[BI],
+                IncludeIndices.begin() + Blocks[BI + 1],
+                [&FileDirectives](unsigned LHSI, unsigned RHSI) {
+                  IncludeDirective &LHS = FileDirectives[LHSI];
+                  IncludeDirective &RHS = FileDirectives[RHSI];
+
+                  int PriorityLHS =
+                      getPriority(LHS.Filename, LHS.IsAngled, LHS.IsMainModule);
+                  int PriorityRHS =
+                      getPriority(RHS.Filename, RHS.IsAngled, RHS.IsMainModule);
+
+                  return std::tie(PriorityLHS, LHS.Filename) <
+                         std::tie(PriorityRHS, RHS.Filename);
+                });
+
+    // Emit a warning for each block and fixits for all changes within that
+    // block.
+    for (unsigned BI = 0, BE = Blocks.size() - 1; BI != BE; ++BI) {
+      // Find the first include that's not in the right position.
+      unsigned I, E;
+      for (I = Blocks[BI], E = Blocks[BI + 1]; I != E; ++I)
+        if (IncludeIndices[I] != I)
+          break;
 
-      StringRef FixedName(FromData, FromLen);
+      if (I == E)
+        continue;
 
-      SourceLocation ToLoc = IncludeDirectives[I].Range.getBegin();
-      const char *ToData = SM.getCharacterData(ToLoc);
-      unsigned ToLen = std::strcspn(ToData, "\n");
-      auto ToRange =
-          CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen));
+      // Emit a warning.
+      auto D = Check.diag(FileDirectives[I].Loc,
+                          "#includes are not sorted properly");
+
+      // Emit fix-its for all following includes in this block.
+      for (; I != E; ++I) {
+        if (IncludeIndices[I] == I)
+          continue;
+        const IncludeDirective &CopyFrom = FileDirectives[IncludeIndices[I]];
+
+        SourceLocation FromLoc = CopyFrom.Range.getBegin();
+        const char *FromData = SM.getCharacterData(FromLoc);
+        unsigned FromLen = std::strcspn(FromData, "\n");
+
+        StringRef FixedName(FromData, FromLen);
+
+        SourceLocation ToLoc = FileDirectives[I].Range.getBegin();
+        const char *ToData = SM.getCharacterData(ToLoc);
+        unsigned ToLen = std::strcspn(ToData, "\n");
+        auto ToRange =
+            CharSourceRange::getCharRange(ToLoc, ToLoc.getLocWithOffset(ToLen));
 
-      D << FixItHint::CreateReplacement(ToRange, FixedName);
+        D << FixItHint::CreateReplacement(ToRange, FixedName);
+      }
     }
   }
 
Index: clang-tools-extra/trunk/test/clang-tidy/clang-cl-driver.cpp
===================================================================
--- clang-tools-extra/trunk/test/clang-tidy/clang-cl-driver.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/clang-cl-driver.cpp
@@ -0,0 +1,17 @@
+// RUN: clang-tidy -checks=-*,modernize-use-nullptr %s -- clang-cl /DTEST1 /DFOO=foo /DBAR=bar | FileCheck -implicit-check-not="{{warning|error}}:" %s
+int *a = 0;
+// CHECK: :[[@LINE-1]]:10: warning: use nullptr
+#ifdef TEST1
+int *b = 0;
+// CHECK: :[[@LINE-1]]:10: warning: use nullptr
+#endif
+#define foo 1
+#define bar 1
+#if FOO
+int *c = 0;
+// CHECK: :[[@LINE-1]]:10: warning: use nullptr
+#endif
+#if BAR
+int *d = 0;
+// CHECK: :[[@LINE-1]]:10: warning: use nullptr
+#endif
\ No newline at end of file
Index: clang-tools-extra/trunk/test/clang-tidy/llvm-include-order.cpp
===================================================================
--- clang-tools-extra/trunk/test/clang-tidy/llvm-include-order.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/llvm-include-order.cpp
@@ -35,3 +35,8 @@
 
 // CHECK-FIXES: #include "a.h"
 // CHECK-FIXES-NEXT: #include "b.h"
+
+// CHECK-MESSAGES-NOT: [[@LINE+1]]:1: warning: #includes are not sorted properly
+#include "cross-file-c.h"
+// This line number should correspond to the position of the #include in cross-file-c.h
+#include "cross-file-a.h"
Index: clang-tools-extra/trunk/test/clang-tidy/Inputs/Headers/cross-file-c.h
===================================================================
--- clang-tools-extra/trunk/test/clang-tidy/Inputs/Headers/cross-file-c.h
+++ clang-tools-extra/trunk/test/clang-tidy/Inputs/Headers/cross-file-c.h
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// The line number of the following include should match the location of the
+// corresponding comment in llvm-include-order.cpp
+#include "cross-file-b.h"
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to