[clang-tools-extra] 2675773 - [include-cleaner] add macro symbols and implicit refs to HTML report

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 17 08:29:48 PST 2022


Author: Sam McCall
Date: 2022-11-17T17:29:41+01:00
New Revision: 267577325876d7e3e2b96c0a577b1b8ce076dfbb

URL: https://github.com/llvm/llvm-project/commit/267577325876d7e3e2b96c0a577b1b8ce076dfbb
DIFF: https://github.com/llvm/llvm-project/commit/267577325876d7e3e2b96c0a577b1b8ce076dfbb.diff

LOG: [include-cleaner] add macro symbols and implicit refs to HTML report

Demo: http://htmlpreview.github.io/?https://gist.githubusercontent.com/sam-mccall/fec9b77c726cfb3cc7c424b197e3f68c/raw/8c5c5ad927b0485db76c34c25250b0ae8f7637f8/ASTTests.html

Differential Revision: https://reviews.llvm.org/D137677

Added: 
    

Modified: 
    clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
    clang-tools-extra/include-cleaner/lib/Analysis.cpp
    clang-tools-extra/include-cleaner/lib/AnalysisInternal.h
    clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
    clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
    clang-tools-extra/include-cleaner/lib/Types.cpp
    clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
    clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
    clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
index 7b8606f4a6ce4..31ae7592ceec0 100644
--- a/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
+++ b/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
@@ -45,7 +45,7 @@ using UsedSymbolCB = llvm::function_ref<void(const SymbolReference &SymRef,
 ///    the headers for any referenced symbol
 void walkUsed(llvm::ArrayRef<Decl *> ASTRoots,
               llvm::ArrayRef<SymbolReference> MacroRefs,
-              const PragmaIncludes &PI, const SourceManager &, UsedSymbolCB CB);
+              const PragmaIncludes *PI, const SourceManager &, UsedSymbolCB CB);
 
 } // namespace include_cleaner
 } // namespace clang

diff  --git a/clang-tools-extra/include-cleaner/lib/Analysis.cpp b/clang-tools-extra/include-cleaner/lib/Analysis.cpp
index 890e5e13fa57f..e2455e115de24 100644
--- a/clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -19,8 +19,9 @@ namespace clang::include_cleaner {
 
 void walkUsed(llvm::ArrayRef<Decl *> ASTRoots,
               llvm::ArrayRef<SymbolReference> MacroRefs,
-              const PragmaIncludes &PI, const SourceManager &SM,
+              const PragmaIncludes *PI, const SourceManager &SM,
               UsedSymbolCB CB) {
+  // This is duplicated in writeHTMLReport, changes should be mirrored there.
   tooling::stdlib::Recognizer Recognizer;
   for (auto *Root : ASTRoots) {
     auto &SM = Root->getASTContext().getSourceManager();

diff  --git a/clang-tools-extra/include-cleaner/lib/AnalysisInternal.h b/clang-tools-extra/include-cleaner/lib/AnalysisInternal.h
index 17c11c1218dde..ec378dca6ec70 100644
--- a/clang-tools-extra/include-cleaner/lib/AnalysisInternal.h
+++ b/clang-tools-extra/include-cleaner/lib/AnalysisInternal.h
@@ -75,18 +75,18 @@ struct SymbolLocation {
   // Order must match Kind enum!
   std::variant<SourceLocation, tooling::stdlib::Symbol> Storage;
 };
-llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Header &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
 
 /// Finds the headers that provide the symbol location.
 // FIXME: expose signals
 llvm::SmallVector<Header> findHeaders(const SymbolLocation &Loc,
                                       const SourceManager &SM,
-                                      const PragmaIncludes &PI);
+                                      const PragmaIncludes *PI);
 
 /// Write an HTML summary of the analysis to the given stream.
-/// FIXME: Once analysis has a public API, this should be public too.
-void writeHTMLReport(FileID File, llvm::ArrayRef<Decl *> Roots, ASTContext &Ctx,
-                     llvm::raw_ostream &OS);
+void writeHTMLReport(FileID File, llvm::ArrayRef<Decl *> Roots,
+                     llvm::ArrayRef<SymbolReference> MacroRefs, ASTContext &Ctx,
+                     PragmaIncludes *PI, llvm::raw_ostream &OS);
 
 } // namespace include_cleaner
 } // namespace clang

diff  --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
index 093cba8b769a9..c782ff89755cb 100644
--- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
+++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
@@ -14,7 +14,7 @@ namespace clang::include_cleaner {
 
 llvm::SmallVector<Header> findHeaders(const SymbolLocation &Loc,
                                       const SourceManager &SM,
-                                      const PragmaIncludes &PI) {
+                                      const PragmaIncludes *PI) {
   llvm::SmallVector<Header> Results;
   switch (Loc.kind()) {
   case SymbolLocation::Physical: {
@@ -25,18 +25,21 @@ llvm::SmallVector<Header> findHeaders(const SymbolLocation &Loc,
     if (!FE)
       return {};
 
-    // We treat the spelling header in the IWYU pragma as the final public
-    // header.
-    // FIXME: look for exporters if the public header is exported by another
-    // header.
-    llvm::StringRef VerbatimSpelling = PI.getPublic(FE);
-    if (!VerbatimSpelling.empty())
-      return {Header(VerbatimSpelling)};
-
     Results = {Header(FE)};
-    // FIXME: compute transitive exporter headers.
-    for (const auto *Export : PI.getExporters(FE, SM.getFileManager()))
-      Results.push_back(Export);
+    if (PI) {
+      // We treat the spelling header in the IWYU pragma as the final public
+      // header.
+      // FIXME: look for exporters if the public header is exported by another
+      // header.
+      llvm::StringRef VerbatimSpelling = PI->getPublic(FE);
+      if (!VerbatimSpelling.empty())
+        return {Header(VerbatimSpelling)};
+
+      // FIXME: compute transitive exporter headers.
+      for (const auto *Export : PI->getExporters(FE, SM.getFileManager()))
+        Results.push_back(Export);
+    }
+
     return Results;
   }
   case SymbolLocation::Standard: {

diff  --git a/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp b/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
index f54b4f4da8267..b1c9f6d548662 100644
--- a/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
+++ b/clang-tools-extra/include-cleaner/lib/HTMLReport.cpp
@@ -14,12 +14,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "AnalysisInternal.h"
-#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Types.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Inclusions/StandardLibrary.h"
+#include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang::include_cleaner {
@@ -38,16 +39,24 @@ constexpr llvm::StringLiteral CSS = R"css(
   }
   .ref { text-decoration: underline; color: #008; }
   .sel { position: relative; cursor: pointer; }
+  .ref.implicit { background-color: #ff8; }
   #hover {
-    background-color: #aaccff; border: 1px solid black;
+    color: black;
+    background-color: #aaccff; border: 1px solid #444;
     z-index: 1;
     position: absolute; top: 100%; left: 0;
     font-family: sans-serif;
     padding: 0.5em;
   }
   #hover p, #hover pre { margin: 0; }
-  #hover section header { font-weight: bold; }
-  #hover section:not(:first-child) { margin-top: 1em; }
+  #hover .target.implicit { background-color: #bbb; }
+  #hover .target.ambiguous { background-color: #caf; }
+  #hover th { color: #008; text-align: right; padding-right: 0.5em; }
+  #hover .target:not(:first-child) {
+    margin-top: 1em;
+    padding-top: 1em;
+    border-top: 1px solid #444;
+  }
 )css";
 
 constexpr llvm::StringLiteral JS = R"js(
@@ -74,49 +83,95 @@ constexpr llvm::StringLiteral JS = R"js(
   }
 )js";
 
-// Print the declaration tersely, but enough to identify e.g. which overload.
-std::string printDecl(const NamedDecl &ND) {
-  std::string S;
-  llvm::raw_string_ostream OS(S);
-  PrintingPolicy PP = ND.getASTContext().getPrintingPolicy();
-  PP.FullyQualifiedName = true;
-  PP.TerseOutput = true;
-  PP.SuppressInitializers = true;
-  ND.print(OS, PP);
-  llvm::erase_value(S, '\n');
-  return S;
+// Categorize the symbol, like FunctionDecl or Macro
+llvm::StringRef describeSymbol(const Symbol &Sym) {
+  switch (Sym.kind()) {
+  case Symbol::Declaration:
+    return Sym.declaration().getDeclKindName();
+  case Symbol::Macro:
+    return "Macro";
+  }
+  llvm_unreachable("unhandled symbol kind");
+}
+
+llvm::StringRef refType(RefType T) {
+  switch (T) {
+  case RefType::Explicit:
+    return "explicit";
+  case RefType::Implicit:
+    return "implicit";
+  case RefType::Ambiguous:
+    return "ambiguous";
+  }
 }
 
 class Reporter {
   llvm::raw_ostream &OS;
   const ASTContext &Ctx;
   const SourceManager &SM;
+  const PragmaIncludes *PI;
   FileID File;
 
-  // Symbols that are referenced from the main file.
+  // References to symbols from the main file.
+  // FIXME: should we deduplicate these?
   struct Target {
-    const NamedDecl *D;
+    Symbol Sym;
+    RefType Type;
+    SmallVector<SymbolLocation> Locations;
+    SmallVector<Header> Headers;
   };
   std::vector<Target> Targets;
   // Points within the main file that reference a Target.
-  std::vector<std::pair</*Offset*/ unsigned, /*TargetIndex*/ unsigned>> Refs;
+  // Implicit refs will be marked with a symbol just before the token.
+  struct Ref {
+    unsigned Offset;
+    bool Implicit;
+    size_t TargetIndex;
+    bool operator<(const Ref &Other) const {
+      return std::forward_as_tuple(Offset, !Implicit, TargetIndex) <
+             std::forward_as_tuple(Other.Offset, !Other.Implicit, TargetIndex);
+    }
+  };
+  std::vector<Ref> Refs;
+
+  Target makeTarget(const SymbolReference &SR) {
+    Target T{SR.Target, SR.RT, {}, {}};
+
+    // Duplicates logic from walkUsed(), which doesn't expose SymbolLocations.
+    // FIXME: use locateDecl and friends once implemented.
+    // This doesn't use stdlib::Recognizer, but locateDecl will soon do that.
+    switch (SR.Target.kind()) {
+    case Symbol::Declaration:
+      T.Locations.push_back(SR.Target.declaration().getLocation());
+      break;
+    case Symbol::Macro:
+      T.Locations.push_back(SR.Target.macro().Definition);
+      break;
+    }
+
+    for (const auto &Loc : T.Locations)
+      T.Headers = findHeaders(Loc, SM, PI);
+
+    return T;
+  }
 
 public:
-  Reporter(llvm::raw_ostream &OS, ASTContext &Ctx, FileID File)
-      : OS(OS), Ctx(Ctx), SM(Ctx.getSourceManager()), File(File) {}
+  Reporter(llvm::raw_ostream &OS, ASTContext &Ctx, const PragmaIncludes *PI,
+           FileID File)
+      : OS(OS), Ctx(Ctx), SM(Ctx.getSourceManager()), PI(PI), File(File) {}
 
-  void addRef(SourceLocation Loc, const NamedDecl &D) {
-    auto [File, Offset] = SM.getDecomposedLoc(SM.getFileLoc(Loc));
+  void addRef(const SymbolReference &SR) {
+    auto [File, Offset] = SM.getDecomposedLoc(SM.getFileLoc(SR.RefLocation));
     if (File != this->File) {
       // Can get here e.g. if there's an #include inside a root Decl.
       // FIXME: do something more useful than this.
-      llvm::errs() << "Ref location outside file! "
-                   << D.getQualifiedNameAsString() << " at "
-                   << Loc.printToString(SM) << "\n";
+      llvm::errs() << "Ref location outside file! " << SR.Target << " at "
+                   << SR.RefLocation.printToString(SM) << "\n";
       return;
     }
-    Targets.push_back({&D});
-    Refs.push_back({Offset, Targets.size() - 1});
+
+    Refs.push_back({Offset, SR.RT == RefType::Implicit, Targets.size()});
+    Targets.push_back(makeTarget(SR));
   }
 
   void write() {
@@ -126,9 +181,9 @@ class Reporter {
     OS << "<style>" << CSS << "</style>\n";
     OS << "<script>" << JS << "</script>\n";
     for (unsigned I = 0; I < Targets.size(); ++I) {
-      OS << "<template id='t" << I << "'><section>";
+      OS << "<template id='t" << I << "'>";
       writeTarget(Targets[I]);
-      OS << "</section></template>\n";
+      OS << "</template>\n";
     }
     OS << "</head>\n";
     OS << "<body>\n";
@@ -156,16 +211,84 @@ class Reporter {
       escapeChar(C);
   }
 
+  // Abbreviate a path ('path/to/Foo.h') to just the filename ('Foo.h').
+  // The full path is available on hover.
+  void printFilename(llvm::StringRef Path) {
+    llvm::StringRef File = llvm::sys::path::filename(Path);
+    if (File == Path)
+      return escapeString(Path);
+    OS << "<span title='";
+    escapeString(Path);
+    OS << "'>";
+    escapeString(File);
+    OS << "</span>";
+  }
+
+  // Print a source location in compact style.
+  void printSourceLocation(SourceLocation Loc) {
+    if (Loc.isInvalid())
+      return escapeString("<invalid>");
+    if (!Loc.isMacroID())
+      return printFilename(Loc.printToString(SM));
+
+    // Replicating printToString() is a bit simpler than parsing/reformatting.
+    printFilename(SM.getExpansionLoc(Loc).printToString(SM));
+    OS << " <Spelling=";
+    printFilename(SM.getSpellingLoc(Loc).printToString(SM));
+    OS << ">";
+  }
+
   void writeTarget(const Target &T) {
-    OS << "<header>" << T.D->getDeclKindName() << " ";
-    escapeString(T.D->getQualifiedNameAsString());
-    OS << "</header>";
+    OS << "<table class='target " << refType(T.Type) << "'>";
+
+    OS << "<tr><th>Symbol</th><td>";
+    OS << describeSymbol(T.Sym) << " <code>";
+    escapeString(llvm::to_string(T.Sym));
+    OS << "</code></td></tr>\n";
+
+    if (T.Sym.kind() == Symbol::Declaration) {
+      // Print the declaration of the symbol, e.g. to disambiguate overloads.
+      const auto &D = T.Sym.declaration();
+      PrintingPolicy PP = D.getASTContext().getPrintingPolicy();
+      PP.FullyQualifiedName = true;
+      PP.TerseOutput = true;
+      PP.SuppressInitializers = true;
+      std::string S;
+      llvm::raw_string_ostream SS(S);
+      D.print(SS, PP);
+
+      OS << "<tr><td></td><td><code>";
+      escapeString(S);
+      OS << "</code></td></tr>\n";
+    }
+
+    for (const auto &Loc : T.Locations) {
+      OS << "<tr><th>Location</th><td>";
+      if (Loc.kind() == SymbolLocation::Physical) // needs SM to print properly.
+        printSourceLocation(Loc.physical());
+      else
+        escapeString(llvm::to_string(Loc));
+      OS << "</td></tr>\n";
+    }
+
+    for (const auto &H : T.Headers) {
+      OS << "<tr><th>Header</th><td>";
+      switch (H.kind()) {
+      case Header::Physical:
+        printFilename(H.physical()->getName());
+        break;
+      case Header::Standard:
+        OS << "stdlib " << H.standard().name();
+        break;
+      case Header::Verbatim:
+        OS << "verbatim ";
+        escapeString(H.verbatim());
+        break;
+      }
+      OS << "</td></tr>\n";
+    }
 
-    OS << "<p>declared at ";
-    escapeString(SM.getFileLoc(T.D->getLocation()).printToString(SM));
-    OS << "</p><pre>";
-    escapeString(printDecl(*T.D));
-    OS << "</pre>";
+    OS << "</table>";
   }
 
   void writeCode() {
@@ -182,14 +305,23 @@ class Reporter {
         OS << "</span>";
         End = 0;
       }
+      // Handle implicit refs, which are rendered *before* the token.
+      while (!Rest.empty() && Rest.front().Offset == I &&
+             Rest.front().Implicit) {
+        const Ref &R = Rest.front();
+        OS << "<span class='ref sel implicit' data-hover='t" << R.TargetIndex
+           << "'>◊</span>";
+        Rest = Rest.drop_front();
+      };
+      // Accumulate all explicit refs that appear on the same token.
       std::string TargetList;
-      Rest = Rest.drop_while([&](auto &R) {
-        if (R.first != I)
+      Rest = Rest.drop_while([&](const Ref &R) {
+        if (R.Offset != I)
           return false;
         if (!TargetList.empty())
           TargetList.push_back(',');
         TargetList.push_back('t');
-        TargetList.append(std::to_string(R.second));
+        TargetList.append(std::to_string(R.TargetIndex));
         return true;
       });
       if (!TargetList.empty()) {
@@ -209,13 +341,16 @@ class Reporter {
 
 } // namespace
 
-void writeHTMLReport(FileID File, llvm::ArrayRef<Decl *> Roots, ASTContext &Ctx,
-                     llvm::raw_ostream &OS) {
-  Reporter R(OS, Ctx, File);
+void writeHTMLReport(FileID File, llvm::ArrayRef<Decl *> Roots,
+                     llvm::ArrayRef<SymbolReference> MacroRefs, ASTContext &Ctx,
+                     PragmaIncludes *PI, llvm::raw_ostream &OS) {
+  Reporter R(OS, Ctx, PI, File);
   for (Decl *Root : Roots)
-    walkAST(*Root, [&](SourceLocation Loc, const NamedDecl &D, RefType) {
-      R.addRef(Loc, D);
+    walkAST(*Root, [&](SourceLocation Loc, const NamedDecl &D, RefType T) {
+      R.addRef(SymbolReference{Loc, D, T});
     });
+  for (const SymbolReference &Ref : MacroRefs)
+    R.addRef(Ref);
   R.write();
 }
 

diff  --git a/clang-tools-extra/include-cleaner/lib/Types.cpp b/clang-tools-extra/include-cleaner/lib/Types.cpp
index 08c9b5980060b..0aa527946bb0d 100644
--- a/clang-tools-extra/include-cleaner/lib/Types.cpp
+++ b/clang-tools-extra/include-cleaner/lib/Types.cpp
@@ -18,10 +18,10 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
   switch (S.kind()) {
   case Symbol::Declaration:
     if (const auto *ND = llvm::dyn_cast<NamedDecl>(&S.declaration()))
-      return OS << ND->getNameAsString();
+      return OS << ND->getQualifiedNameAsString();
     return OS << S.declaration().getDeclKindName();
   case Symbol::Macro:
-    return OS << S.macro().Name;
+    return OS << S.macro().Name->getName();
   }
   llvm_unreachable("Unhandled Symbol kind");
 }

diff  --git a/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp b/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
index 6d545c5e08734..957dd9c6aab93 100644
--- a/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
+++ b/clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp
@@ -47,6 +47,15 @@ cl::opt<std::string> HTMLReportPath{
 
 class HTMLReportAction : public clang::ASTFrontendAction {
   RecordedAST AST;
+  RecordedPP PP;
+  PragmaIncludes PI;
+
+  void ExecuteAction() override {
+    auto &P = getCompilerInstance().getPreprocessor();
+    P.addPPCallbacks(PP.record(P));
+    PI.record(getCompilerInstance());
+    ASTFrontendAction::ExecuteAction();
+  }
 
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef File) override {
@@ -62,7 +71,7 @@ class HTMLReportAction : public clang::ASTFrontendAction {
       exit(1);
     }
     writeHTMLReport(AST.Ctx->getSourceManager().getMainFileID(), AST.Roots,
-                    *AST.Ctx, OS);
+                    PP.MacroReferences, *AST.Ctx, &PI, OS);
   }
 };
 

diff  --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
index 6d9237c6b7d79..5e3866469862c 100644
--- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -72,7 +72,7 @@ TEST(WalkUsed, Basic) {
 
   auto &SM = AST.sourceManager();
   llvm::DenseMap<size_t, std::vector<Header>> OffsetToProviders;
-  walkUsed(TopLevelDecls, /*MacroRefs=*/{}, PI, SM,
+  walkUsed(TopLevelDecls, /*MacroRefs=*/{}, &PI, SM,
            [&](const SymbolReference &Ref, llvm::ArrayRef<Header> Providers) {
              auto [FID, Offset] = SM.getDecomposedLoc(Ref.RefLocation);
              EXPECT_EQ(FID, SM.getMainFileID());
@@ -113,11 +113,10 @@ TEST(WalkUsed, MacroRefs) {
   Symbol Answer =
       Macro{&Idents.get("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
   llvm::DenseMap<size_t, std::vector<Header>> OffsetToProviders;
-  PragmaIncludes PI;
   walkUsed(/*ASTRoots=*/{}, /*MacroRefs=*/
            {SymbolReference{SM.getComposedLoc(SM.getMainFileID(), Main.point()),
                             Answer, RefType::Explicit}},
-           PI, SM,
+           /*PI=*/nullptr, SM,
            [&](const SymbolReference &Ref, llvm::ArrayRef<Header> Providers) {
              auto [FID, Offset] = SM.getDecomposedLoc(Ref.RefLocation);
              EXPECT_EQ(FID, SM.getMainFileID());

diff  --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
index 02854e65fbcbe..c0da609907408 100644
--- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -61,17 +61,17 @@ TEST(FindIncludeHeaders, IWYU) {
                                    /*Line=*/1, /*Col=*/1);
   };
 
-  EXPECT_THAT(findHeaders(SourceLocFromFile("header1.h"), SM, PI),
+  EXPECT_THAT(findHeaders(SourceLocFromFile("header1.h"), SM, &PI),
               UnorderedElementsAre(Header("\"path/public.h\"")));
 
-  EXPECT_THAT(findHeaders(SourceLocFromFile("detail1.h"), SM, PI),
+  EXPECT_THAT(findHeaders(SourceLocFromFile("detail1.h"), SM, &PI),
               UnorderedElementsAre(Header(FM.getFile("header2.h").get()),
                                    Header(FM.getFile("detail1.h").get())));
-  EXPECT_THAT(findHeaders(SourceLocFromFile("detail2.h"), SM, PI),
+  EXPECT_THAT(findHeaders(SourceLocFromFile("detail2.h"), SM, &PI),
               UnorderedElementsAre(Header(FM.getFile("header2.h").get()),
                                    Header(FM.getFile("detail2.h").get())));
 
-  EXPECT_THAT(findHeaders(SourceLocFromFile("normal.h"), SM, PI),
+  EXPECT_THAT(findHeaders(SourceLocFromFile("normal.h"), SM, &PI),
               UnorderedElementsAre(Header(FM.getFile("normal.h").get())));
 }
 


        


More information about the cfe-commits mailing list