[clang-tools-extra] r296446 - [include-fixer] Add usage count to find-all-symbols.
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 28 00:13:16 PST 2017
Author: sammccall
Date: Tue Feb 28 02:13:15 2017
New Revision: 296446
URL: http://llvm.org/viewvc/llvm-project?rev=296446&view=rev
Log:
[include-fixer] Add usage count to find-all-symbols.
Summary:
Add usage count to find-all-symbols.
FindAllSymbols now finds (most!) main-file usages of the discovered symbols.
The per-TU map output has NumUses=0 or 1 (only one use per file is counted).
The reducer aggregates these to find the number of files that use a symbol.
The NumOccurrences is now set to 1 in the mapper rather than being inferred by
the reducer, for consistency.
The idea here is to use NumUses for ranking: intuitively number of files that
use a symbol is more meaningful than number of files that include the header.
Reviewers: hokein, bkramer
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D30210
Modified:
clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.cpp
clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.h
clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
clang-tools-extra/trunk/include-fixer/SymbolIndex.h
clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp
clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.cpp
clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.h
clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.cpp
clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.h
clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.cpp
clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.h
clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.cpp
clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolReporter.h
clang-tools-extra/trunk/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml
clang-tools-extra/trunk/test/include-fixer/Inputs/merge/a.yaml
clang-tools-extra/trunk/test/include-fixer/Inputs/merge/b.yaml
clang-tools-extra/trunk/test/include-fixer/merge.test
clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp
clang-tools-extra/trunk/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
Modified: clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.cpp Tue Feb 28 02:13:15 2017
@@ -9,18 +9,18 @@
#include "InMemorySymbolIndex.h"
-using clang::find_all_symbols::SymbolInfo;
+using clang::find_all_symbols::SymbolAndSignals;
namespace clang {
namespace include_fixer {
InMemorySymbolIndex::InMemorySymbolIndex(
- const std::vector<SymbolInfo> &Symbols) {
+ const std::vector<SymbolAndSignals> &Symbols) {
for (const auto &Symbol : Symbols)
- LookupTable[Symbol.getName()].push_back(Symbol);
+ LookupTable[Symbol.Symbol.getName()].push_back(Symbol);
}
-std::vector<SymbolInfo>
+std::vector<SymbolAndSignals>
InMemorySymbolIndex::search(llvm::StringRef Identifier) {
auto I = LookupTable.find(Identifier);
if (I != LookupTable.end())
Modified: clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.h (original)
+++ clang-tools-extra/trunk/include-fixer/InMemorySymbolIndex.h Tue Feb 28 02:13:15 2017
@@ -21,13 +21,14 @@ namespace include_fixer {
/// Xref database with fixed content.
class InMemorySymbolIndex : public SymbolIndex {
public:
- InMemorySymbolIndex(const std::vector<find_all_symbols::SymbolInfo> &Symbols);
+ InMemorySymbolIndex(
+ const std::vector<find_all_symbols::SymbolAndSignals> &Symbols);
- std::vector<clang::find_all_symbols::SymbolInfo>
+ std::vector<find_all_symbols::SymbolAndSignals>
search(llvm::StringRef Identifier) override;
private:
- std::map<std::string, std::vector<clang::find_all_symbols::SymbolInfo>>
+ std::map<std::string, std::vector<find_all_symbols::SymbolAndSignals>>
LookupTable;
};
Modified: clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp Tue Feb 28 02:13:15 2017
@@ -334,8 +334,7 @@ IncludeFixerContext IncludeFixerSemaSour
SourceManager, HeaderSearch);
SymbolCandidates.emplace_back(Symbol.getName(), Symbol.getSymbolKind(),
MinimizedFilePath, Symbol.getLineNumber(),
- Symbol.getContexts(),
- Symbol.getNumOccurrences());
+ Symbol.getContexts());
}
return IncludeFixerContext(FilePath, QuerySymbolInfos, SymbolCandidates);
}
Modified: clang-tools-extra/trunk/include-fixer/SymbolIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/SymbolIndex.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/SymbolIndex.h (original)
+++ clang-tools-extra/trunk/include-fixer/SymbolIndex.h Tue Feb 28 02:13:15 2017
@@ -28,7 +28,7 @@ public:
/// \returns A list of `SymbolInfo` candidates.
// FIXME: Expose the type name so we can also insert using declarations (or
// fix the usage)
- virtual std::vector<clang::find_all_symbols::SymbolInfo>
+ virtual std::vector<find_all_symbols::SymbolAndSignals>
search(llvm::StringRef Identifier) = 0;
};
Modified: clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp Tue Feb 28 02:13:15 2017
@@ -19,7 +19,8 @@
namespace clang {
namespace include_fixer {
-using clang::find_all_symbols::SymbolInfo;
+using find_all_symbols::SymbolInfo;
+using find_all_symbols::SymbolAndSignals;
// Calculate a score based on whether we think the given header is closely
// related to the given source file.
@@ -45,26 +46,26 @@ static double similarityScore(llvm::Stri
return MaxSegments;
}
-static void rank(std::vector<SymbolInfo> &Symbols,
+static void rank(std::vector<SymbolAndSignals> &Symbols,
llvm::StringRef FileName) {
llvm::DenseMap<llvm::StringRef, double> Score;
- for (const SymbolInfo &Symbol : Symbols) {
+ for (const auto &Symbol : Symbols) {
// Calculate a score from the similarity of the header the symbol is in
// with the current file and the popularity of the symbol.
- double NewScore = similarityScore(FileName, Symbol.getFilePath()) *
- (1.0 + std::log2(1 + Symbol.getNumOccurrences()));
- double &S = Score[Symbol.getFilePath()];
+ double NewScore = similarityScore(FileName, Symbol.Symbol.getFilePath()) *
+ (1.0 + std::log2(1 + Symbol.Signals.Seen));
+ double &S = Score[Symbol.Symbol.getFilePath()];
S = std::max(S, NewScore);
}
// Sort by the gathered scores. Use file name as a tie breaker so we can
// deduplicate.
std::sort(Symbols.begin(), Symbols.end(),
- [&](const SymbolInfo &A, const SymbolInfo &B) {
- auto AS = Score[A.getFilePath()];
- auto BS = Score[B.getFilePath()];
+ [&](const SymbolAndSignals &A, const SymbolAndSignals &B) {
+ auto AS = Score[A.Symbol.getFilePath()];
+ auto BS = Score[B.Symbol.getFilePath()];
if (AS != BS)
return AS > BS;
- return A.getFilePath() < B.getFilePath();
+ return A.Symbol.getFilePath() < B.Symbol.getFilePath();
});
}
@@ -88,9 +89,9 @@ SymbolIndexManager::search(llvm::StringR
// Eventually we will either hit a class (namespaces aren't in the database
// either) and can report that result.
bool TookPrefix = false;
- std::vector<clang::find_all_symbols::SymbolInfo> MatchedSymbols;
+ std::vector<SymbolAndSignals> MatchedSymbols;
do {
- std::vector<clang::find_all_symbols::SymbolInfo> Symbols;
+ std::vector<SymbolAndSignals> Symbols;
for (const auto &DB : SymbolIndices) {
auto Res = DB.get()->search(Names.back());
Symbols.insert(Symbols.end(), Res.begin(), Res.end());
@@ -99,7 +100,8 @@ SymbolIndexManager::search(llvm::StringR
DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got "
<< Symbols.size() << " results...\n");
- for (const auto &Symbol : Symbols) {
+ for (auto &SymAndSig : Symbols) {
+ const SymbolInfo &Symbol = SymAndSig.Symbol;
// Match the identifier name without qualifier.
if (Symbol.getName() == Names.back()) {
bool IsMatched = true;
@@ -139,7 +141,7 @@ SymbolIndexManager::search(llvm::StringR
Symbol.getSymbolKind() == SymbolInfo::SymbolKind::Macro))
continue;
- MatchedSymbols.push_back(Symbol);
+ MatchedSymbols.push_back(std::move(SymAndSig));
}
}
}
@@ -148,7 +150,11 @@ SymbolIndexManager::search(llvm::StringR
} while (MatchedSymbols.empty() && !Names.empty() && IsNestedSearch);
rank(MatchedSymbols, FileName);
- return MatchedSymbols;
+ // Strip signals, they are no longer needed.
+ std::vector<SymbolInfo> Res;
+ for (const auto &SymAndSig : MatchedSymbols)
+ Res.push_back(std::move(SymAndSig.Symbol));
+ return Res;
}
} // namespace include_fixer
Modified: clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.cpp Tue Feb 28 02:13:15 2017
@@ -17,6 +17,7 @@
#include <vector>
using clang::find_all_symbols::SymbolInfo;
+using clang::find_all_symbols::SymbolAndSignals;
namespace clang {
namespace include_fixer {
@@ -27,9 +28,8 @@ YamlSymbolIndex::createFromFile(llvm::St
if (!Buffer)
return Buffer.getError();
- return std::unique_ptr<YamlSymbolIndex>(
- new YamlSymbolIndex(clang::find_all_symbols::ReadSymbolInfosFromYAML(
- Buffer.get()->getBuffer())));
+ return std::unique_ptr<YamlSymbolIndex>(new YamlSymbolIndex(
+ find_all_symbols::ReadSymbolInfosFromYAML(Buffer.get()->getBuffer())));
}
llvm::ErrorOr<std::unique_ptr<YamlSymbolIndex>>
@@ -47,10 +47,11 @@ YamlSymbolIndex::createFromDirectory(llv
return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
}
-std::vector<SymbolInfo> YamlSymbolIndex::search(llvm::StringRef Identifier) {
- std::vector<SymbolInfo> Results;
+std::vector<SymbolAndSignals>
+YamlSymbolIndex::search(llvm::StringRef Identifier) {
+ std::vector<SymbolAndSignals> Results;
for (const auto &Symbol : Symbols) {
- if (Symbol.getName() == Identifier)
+ if (Symbol.Symbol.getName() == Identifier)
Results.push_back(Symbol);
}
return Results;
Modified: clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.h (original)
+++ clang-tools-extra/trunk/include-fixer/YamlSymbolIndex.h Tue Feb 28 02:13:15 2017
@@ -29,15 +29,15 @@ public:
static llvm::ErrorOr<std::unique_ptr<YamlSymbolIndex>>
createFromDirectory(llvm::StringRef Directory, llvm::StringRef Name);
- std::vector<clang::find_all_symbols::SymbolInfo>
+ std::vector<find_all_symbols::SymbolAndSignals>
search(llvm::StringRef Identifier) override;
private:
explicit YamlSymbolIndex(
- std::vector<clang::find_all_symbols::SymbolInfo> Symbols)
+ std::vector<find_all_symbols::SymbolAndSignals> Symbols)
: Symbols(std::move(Symbols)) {}
- std::vector<clang::find_all_symbols::SymbolInfo> Symbols;
+ std::vector<find_all_symbols::SymbolAndSignals> Symbols;
};
} // namespace include_fixer
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.cpp Tue Feb 28 02:13:15 2017
@@ -13,24 +13,58 @@
#include "SymbolInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Token.h"
#include "llvm/Support/Path.h"
namespace clang {
namespace find_all_symbols {
+llvm::Optional<SymbolInfo>
+FindAllMacros::CreateMacroSymbol(const Token &MacroNameTok,
+ const MacroInfo *info) {
+ std::string FilePath =
+ getIncludePath(*SM, info->getDefinitionLoc(), Collector);
+ if (FilePath.empty())
+ return llvm::None;
+ return SymbolInfo(MacroNameTok.getIdentifierInfo()->getName(),
+ SymbolInfo::SymbolKind::Macro, FilePath,
+ SM->getSpellingLineNumber(info->getDefinitionLoc()), {});
+}
+
void FindAllMacros::MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) {
- SourceLocation Loc = SM->getExpansionLoc(MacroNameTok.getLocation());
- std::string FilePath = getIncludePath(*SM, Loc, Collector);
- if (FilePath.empty()) return;
+ if (auto Symbol = CreateMacroSymbol(MacroNameTok, MD->getMacroInfo()))
+ ++FileSymbols[*Symbol].Seen;
+}
- SymbolInfo Symbol(MacroNameTok.getIdentifierInfo()->getName(),
- SymbolInfo::SymbolKind::Macro, FilePath,
- SM->getSpellingLineNumber(Loc), {});
+void FindAllMacros::MacroUsed(const Token &Name, const MacroDefinition &MD) {
+ if (!MD || !SM->isInMainFile(SM->getExpansionLoc(Name.getLocation())))
+ return;
+ if (auto Symbol = CreateMacroSymbol(Name, MD.getMacroInfo()))
+ ++FileSymbols[*Symbol].Used;
+}
+
+void FindAllMacros::MacroExpands(const Token &MacroNameTok,
+ const MacroDefinition &MD, SourceRange Range,
+ const MacroArgs *Args) {
+ MacroUsed(MacroNameTok, MD);
+}
+
+void FindAllMacros::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDefinition &MD) {
+ MacroUsed(MacroNameTok, MD);
+}
+
+void FindAllMacros::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDefinition &MD) {
+ MacroUsed(MacroNameTok, MD);
+}
- Reporter->reportSymbol(SM->getFileEntryForID(SM->getMainFileID())->getName(),
- Symbol);
+void FindAllMacros::EndOfMainFile() {
+ Reporter->reportSymbols(SM->getFileEntryForID(SM->getMainFileID())->getName(),
+ FileSymbols);
+ FileSymbols.clear();
}
} // namespace find_all_symbols
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.h (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllMacros.h Tue Feb 28 02:13:15 2017
@@ -16,6 +16,7 @@
#include "clang/Lex/PPCallbacks.h"
namespace clang {
+class MacroInfo;
namespace find_all_symbols {
class HeaderMapCollector;
@@ -32,7 +33,24 @@ public:
void MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) override;
+ void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
+ SourceRange Range, const MacroArgs *Args) override;
+
+ void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDefinition &MD) override;
+
+ void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+ const MacroDefinition &MD) override;
+
+ void EndOfMainFile() override;
+
private:
+ llvm::Optional<SymbolInfo> CreateMacroSymbol(const Token &MacroNameTok,
+ const MacroInfo *MD);
+ // Not a callback, just a common path for all usage types.
+ void MacroUsed(const Token &Name, const MacroDefinition &MD);
+
+ SymbolInfo::SignalMap FileSymbols;
// Reporter for SymbolInfo.
SymbolReporter *const Reporter;
SourceManager *const SM;
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.cpp Tue Feb 28 02:13:15 2017
@@ -154,64 +154,84 @@ void FindAllSymbols::registerMatchers(Ma
// The float parameter of the function pointer has an empty name, and its
// declaration context is an anonymous namespace; therefore, it won't be
// filtered out by our matchers above.
- MatchFinder->addMatcher(varDecl(CommonFilter,
- anyOf(ExternCMatcher, CCMatcher),
- unless(parmVarDecl()))
- .bind("decl"),
- this);
+ auto Vars = varDecl(CommonFilter, anyOf(ExternCMatcher, CCMatcher),
+ unless(parmVarDecl()));
// Matchers for C-style record declarations in extern "C" {...}.
- MatchFinder->addMatcher(
- recordDecl(CommonFilter, ExternCMatcher, isDefinition()).bind("decl"),
- this);
-
+ auto CRecords = recordDecl(CommonFilter, ExternCMatcher, isDefinition());
// Matchers for C++ record declarations.
- auto CxxRecordDecl =
- cxxRecordDecl(CommonFilter, CCMatcher, isDefinition());
- MatchFinder->addMatcher(CxxRecordDecl.bind("decl"), this);
+ auto CXXRecords = cxxRecordDecl(CommonFilter, CCMatcher, isDefinition());
// Matchers for function declarations.
// We want to exclude friend declaration, but the `DeclContext` of a friend
// function declaration is not the class in which it is declared, so we need
// to explicitly check if the parent is a `friendDecl`.
- MatchFinder->addMatcher(functionDecl(CommonFilter,
- unless(hasParent(friendDecl())),
- anyOf(ExternCMatcher, CCMatcher))
- .bind("decl"),
- this);
+ auto Functions = functionDecl(CommonFilter, unless(hasParent(friendDecl())),
+ anyOf(ExternCMatcher, CCMatcher));
// Matcher for typedef and type alias declarations.
//
- // typedef and type alias can come from C-style headers and C++ heaeders.
- // For C-style header, `DeclContxet` can be either `TranslationUnitDecl`
+ // typedef and type alias can come from C-style headers and C++ headers.
+ // For C-style headers, `DeclContxet` can be either `TranslationUnitDecl`
// or `LinkageSpecDecl`.
- // For C++ header, `DeclContext ` can be one of `TranslationUnitDecl`,
- // `NamespaceDecl`.
+ // For C++ headers, `DeclContext ` can be either `TranslationUnitDecl`
+ // or `NamespaceDecl`.
// With the following context matcher, we can match `typedefNameDecl` from
- // both C-style header and C++ header (except for those in classes).
+ // both C-style headers and C++ headers (except for those in classes).
// "cc_matchers" are not included since template-related matchers are not
// applicable on `TypedefNameDecl`.
- MatchFinder->addMatcher(
+ auto Typedefs =
typedefNameDecl(CommonFilter, anyOf(HasNSOrTUCtxMatcher,
- hasDeclContext(linkageSpecDecl())))
- .bind("decl"),
- this);
+ hasDeclContext(linkageSpecDecl())));
// Matchers for enum declarations.
- MatchFinder->addMatcher(enumDecl(CommonFilter, isDefinition(),
- anyOf(HasNSOrTUCtxMatcher, ExternCMatcher))
- .bind("decl"),
- this);
+ auto Enums = enumDecl(CommonFilter, isDefinition(),
+ anyOf(HasNSOrTUCtxMatcher, ExternCMatcher));
// Matchers for enum constant declarations.
// We only match the enum constants in non-scoped enum declarations which are
// inside toplevel translation unit or a namespace.
+ auto EnumConstants = enumConstantDecl(
+ CommonFilter, unless(isInScopedEnum()),
+ anyOf(hasDeclContext(enumDecl(HasNSOrTUCtxMatcher)), ExternCMatcher));
+
+ // Most of the time we care about all matchable decls, or all types.
+ auto Types = namedDecl(anyOf(CRecords, CXXRecords, Enums, Typedefs));
+ auto Decls = namedDecl(anyOf(CRecords, CXXRecords, Enums, Typedefs, Vars,
+ EnumConstants, Functions));
+
+ // We want eligible decls bound to "decl"...
+ MatchFinder->addMatcher(Decls.bind("decl"), this);
+
+ // ... and all uses of them bound to "use". These have many cases:
+ // Uses of values/functions: these generate a declRefExpr.
+ MatchFinder->addMatcher(
+ declRefExpr(isExpansionInMainFile(), to(Decls.bind("use"))), this);
+ // Uses of function templates:
MatchFinder->addMatcher(
- enumConstantDecl(
- CommonFilter,
- unless(isInScopedEnum()),
- anyOf(hasDeclContext(enumDecl(HasNSOrTUCtxMatcher)), ExternCMatcher))
- .bind("decl"),
+ declRefExpr(isExpansionInMainFile(),
+ to(functionDecl(hasParent(
+ functionTemplateDecl(has(Functions.bind("use"))))))),
+ this);
+
+ // Uses of most types: just look at what the typeLoc refers to.
+ MatchFinder->addMatcher(
+ typeLoc(isExpansionInMainFile(),
+ loc(qualType(hasDeclaration(Types.bind("use"))))),
+ this);
+ // Uses of typedefs: these are transparent to hasDeclaration, so we need to
+ // handle them explicitly.
+ MatchFinder->addMatcher(
+ typeLoc(isExpansionInMainFile(),
+ loc(typedefType(hasDeclaration(Typedefs.bind("use"))))),
+ this);
+ // Uses of class templates:
+ // The typeLoc names the templateSpecializationType. Its declaration is the
+ // ClassTemplateDecl, which contains the CXXRecordDecl we want.
+ MatchFinder->addMatcher(
+ typeLoc(isExpansionInMainFile(),
+ loc(templateSpecializationType(hasDeclaration(
+ classTemplateDecl(has(CXXRecords.bind("use"))))))),
this);
}
@@ -221,15 +241,28 @@ void FindAllSymbols::run(const MatchFind
return;
}
- const auto *ND = Result.Nodes.getNodeAs<NamedDecl>("decl");
- assert(ND && "Matched declaration must be a NamedDecl!");
+ SymbolInfo::Signals Signals;
+ const NamedDecl *ND;
+ if ((ND = Result.Nodes.getNodeAs<NamedDecl>("use")))
+ Signals.Used = 1;
+ else if ((ND = Result.Nodes.getNodeAs<NamedDecl>("decl")))
+ Signals.Seen = 1;
+ else
+ assert(false && "Must match a NamedDecl!");
+
const SourceManager *SM = Result.SourceManager;
+ if (auto Symbol = CreateSymbolInfo(ND, *SM, Collector)) {
+ Filename = SM->getFileEntryForID(SM->getMainFileID())->getName();
+ FileSymbols[*Symbol] += Signals;
+ }
+}
- llvm::Optional<SymbolInfo> Symbol =
- CreateSymbolInfo(ND, *SM, Collector);
- if (Symbol)
- Reporter->reportSymbol(
- SM->getFileEntryForID(SM->getMainFileID())->getName(), *Symbol);
+void FindAllSymbols::onEndOfTranslationUnit() {
+ if (Filename != "") {
+ Reporter->reportSymbols(Filename, FileSymbols);
+ FileSymbols.clear();
+ Filename = "";
+ }
}
} // namespace find_all_symbols
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.h (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbols.h Tue Feb 28 02:13:15 2017
@@ -32,18 +32,24 @@ class HeaderMapCollector;
/// through the class. #include fixer only needs the class name to find
/// headers.
///
-class FindAllSymbols : public clang::ast_matchers::MatchFinder::MatchCallback {
+class FindAllSymbols : public ast_matchers::MatchFinder::MatchCallback {
public:
explicit FindAllSymbols(SymbolReporter *Reporter,
HeaderMapCollector *Collector = nullptr)
: Reporter(Reporter), Collector(Collector) {}
- void registerMatchers(clang::ast_matchers::MatchFinder *MatchFinder);
+ void registerMatchers(ast_matchers::MatchFinder *MatchFinder);
- void
- run(const clang::ast_matchers::MatchFinder::MatchResult &result) override;
+ void run(const ast_matchers::MatchFinder::MatchResult &result) override;
+
+protected:
+ void onEndOfTranslationUnit() override;
private:
+ // Current source file being processed, filled by first symbol found.
+ std::string Filename;
+ // Findings for the current source file, flushed on onEndOfTranslationUnit.
+ SymbolInfo::SignalMap FileSymbols;
// Reporter for SymbolInfo.
SymbolReporter *const Reporter;
// A remapping header file collector allowing clients include a different
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp Tue Feb 28 02:13:15 2017
@@ -24,8 +24,8 @@ FindAllSymbolsAction::FindAllSymbolsActi
Matcher.registerMatchers(&MatchFinder);
}
-std::unique_ptr<clang::ASTConsumer>
-FindAllSymbolsAction::CreateASTConsumer(clang::CompilerInstance &Compiler,
+std::unique_ptr<ASTConsumer>
+FindAllSymbolsAction::CreateASTConsumer(CompilerInstance &Compiler,
StringRef InFile) {
Compiler.getPreprocessor().addCommentHandler(&Handler);
Compiler.getPreprocessor().addPPCallbacks(llvm::make_unique<FindAllMacros>(
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.cpp Tue Feb 28 02:13:15 2017
@@ -18,22 +18,24 @@ using llvm::yaml::IO;
using llvm::yaml::Input;
using ContextType = clang::find_all_symbols::SymbolInfo::ContextType;
using clang::find_all_symbols::SymbolInfo;
+using clang::find_all_symbols::SymbolAndSignals;
using SymbolKind = clang::find_all_symbols::SymbolInfo::SymbolKind;
-LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(SymbolInfo)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(SymbolAndSignals)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
LLVM_YAML_IS_SEQUENCE_VECTOR(SymbolInfo::Context)
namespace llvm {
namespace yaml {
-template <> struct MappingTraits<SymbolInfo> {
- static void mapping(IO &io, SymbolInfo &Symbol) {
- io.mapRequired("Name", Symbol.Name);
- io.mapRequired("Contexts", Symbol.Contexts);
- io.mapRequired("FilePath", Symbol.FilePath);
- io.mapRequired("LineNumber", Symbol.LineNumber);
- io.mapRequired("Type", Symbol.Type);
- io.mapRequired("NumOccurrences", Symbol.NumOccurrences);
+template <> struct MappingTraits<SymbolAndSignals> {
+ static void mapping(IO &io, SymbolAndSignals &Symbol) {
+ io.mapRequired("Name", Symbol.Symbol.Name);
+ io.mapRequired("Contexts", Symbol.Symbol.Contexts);
+ io.mapRequired("FilePath", Symbol.Symbol.FilePath);
+ io.mapRequired("LineNumber", Symbol.Symbol.LineNumber);
+ io.mapRequired("Type", Symbol.Symbol.Type);
+ io.mapRequired("Seen", Symbol.Signals.Seen);
+ io.mapRequired("Used", Symbol.Signals.Used);
}
};
@@ -73,10 +75,9 @@ namespace find_all_symbols {
SymbolInfo::SymbolInfo(llvm::StringRef Name, SymbolKind Type,
llvm::StringRef FilePath, int LineNumber,
- const std::vector<Context> &Contexts,
- unsigned NumOccurrences)
+ const std::vector<Context> &Contexts)
: Name(Name), Type(Type), FilePath(FilePath), Contexts(Contexts),
- LineNumber(LineNumber), NumOccurrences(NumOccurrences) {}
+ LineNumber(LineNumber) {}
bool SymbolInfo::operator==(const SymbolInfo &Symbol) const {
return std::tie(Name, Type, FilePath, LineNumber, Contexts) ==
@@ -100,16 +101,30 @@ std::string SymbolInfo::getQualifiedName
return QualifiedName;
}
+SymbolInfo::Signals &SymbolInfo::Signals::operator+=(const Signals &RHS) {
+ Seen += RHS.Seen;
+ Used += RHS.Used;
+ return *this;
+}
+
+SymbolInfo::Signals SymbolInfo::Signals::operator+(const Signals &RHS) const {
+ Signals Result = *this;
+ Result += RHS;
+ return Result;
+}
+
bool WriteSymbolInfosToStream(llvm::raw_ostream &OS,
- const std::set<SymbolInfo> &Symbols) {
+ const SymbolInfo::SignalMap &Symbols) {
llvm::yaml::Output yout(OS);
- for (auto Symbol : Symbols)
- yout << Symbol;
+ for (const auto &Symbol : Symbols) {
+ SymbolAndSignals S{Symbol.first, Symbol.second};
+ yout << S;
+ }
return true;
}
-std::vector<SymbolInfo> ReadSymbolInfosFromYAML(llvm::StringRef Yaml) {
- std::vector<SymbolInfo> Symbols;
+std::vector<SymbolAndSignals> ReadSymbolInfosFromYAML(llvm::StringRef Yaml) {
+ std::vector<SymbolAndSignals> Symbols;
llvm::yaml::Input yin(Yaml);
yin >> Symbols;
return Symbols;
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolInfo.h Tue Feb 28 02:13:15 2017
@@ -20,7 +20,6 @@
namespace clang {
namespace find_all_symbols {
-
/// \brief Contains all information for a Symbol.
class SymbolInfo {
public:
@@ -46,13 +45,30 @@ public:
/// \brief A pair of <ContextType, ContextName>.
typedef std::pair<ContextType, std::string> Context;
+ // \brief Signals are signals gathered by observing how a symbol is used.
+ // These are used to rank results.
+ struct Signals {
+ Signals() {}
+ Signals(unsigned Seen, unsigned Used) : Seen(Seen), Used(Used) {}
+
+ // Number of times this symbol was visible to a TU.
+ unsigned Seen = 0;
+
+ // Number of times this symbol was referenced a TU's main file.
+ unsigned Used = 0;
+
+ Signals &operator+=(const Signals &RHS);
+ Signals operator+(const Signals &RHS) const;
+ };
+
+ using SignalMap = std::map<SymbolInfo, Signals>;
+
// The default constructor is required by YAML traits in
// LLVM_YAML_IS_DOCUMENT_LIST_VECTOR.
SymbolInfo() : Type(SymbolKind::Unknown), LineNumber(-1) {}
SymbolInfo(llvm::StringRef Name, SymbolKind Type, llvm::StringRef FilePath,
- int LineNumber, const std::vector<Context> &Contexts,
- unsigned NumOccurrences = 0);
+ int LineNumber, const std::vector<Context> &Contexts);
void SetFilePath(llvm::StringRef Path) { FilePath = Path; }
@@ -76,15 +92,12 @@ public:
/// \brief Get a 1-based line number of the symbol's declaration.
int getLineNumber() const { return LineNumber; }
- /// \brief The number of times this symbol was found during an indexing run.
- unsigned getNumOccurrences() const { return NumOccurrences; }
-
bool operator<(const SymbolInfo &Symbol) const;
bool operator==(const SymbolInfo &Symbol) const;
private:
- friend struct llvm::yaml::MappingTraits<SymbolInfo>;
+ friend struct llvm::yaml::MappingTraits<struct SymbolAndSignals>;
/// \brief Identifier name.
std::string Name;
@@ -110,18 +123,19 @@ private:
/// \brief The 1-based line number of of the symbol's declaration.
int LineNumber;
+};
- /// \brief The number of times this symbol was found during an indexing
- /// run. Populated by the reducer and used to rank results.
- unsigned NumOccurrences;
+struct SymbolAndSignals {
+ SymbolInfo Symbol;
+ SymbolInfo::Signals Signals;
};
/// \brief Write SymbolInfos to a stream (YAML format).
bool WriteSymbolInfosToStream(llvm::raw_ostream &OS,
- const std::set<SymbolInfo> &Symbols);
+ const SymbolInfo::SignalMap &Symbols);
/// \brief Read SymbolInfos from a YAML document.
-std::vector<SymbolInfo> ReadSymbolInfosFromYAML(llvm::StringRef Yaml);
+std::vector<SymbolAndSignals> ReadSymbolInfosFromYAML(llvm::StringRef Yaml);
} // namespace find_all_symbols
} // namespace clang
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolReporter.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolReporter.h?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolReporter.h (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/SymbolReporter.h Tue Feb 28 02:13:15 2017
@@ -20,8 +20,8 @@ class SymbolReporter {
public:
virtual ~SymbolReporter() = default;
- virtual void reportSymbol(llvm::StringRef FileName,
- const SymbolInfo &Symbol) = 0;
+ virtual void reportSymbols(llvm::StringRef FileName,
+ const SymbolInfo::SignalMap &Symbols) = 0;
};
} // namespace find_all_symbols
Modified: clang-tools-extra/trunk/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp Tue Feb 28 02:13:15 2017
@@ -62,38 +62,30 @@ The directory for merging symbols.)"),
namespace clang {
namespace find_all_symbols {
-class YamlReporter : public clang::find_all_symbols::SymbolReporter {
+class YamlReporter : public SymbolReporter {
public:
- ~YamlReporter() override {
- for (const auto &Symbol : Symbols) {
- int FD;
- SmallString<128> ResultPath;
- llvm::sys::fs::createUniqueFile(
- OutputDir + "/" + llvm::sys::path::filename(Symbol.first) +
- "-%%%%%%.yaml",
- FD, ResultPath);
- llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
- WriteSymbolInfosToStream(OS, Symbol.second);
- }
- }
-
- void reportSymbol(StringRef FileName, const SymbolInfo &Symbol) override {
- Symbols[FileName].insert(Symbol);
+ void reportSymbols(StringRef FileName,
+ const SymbolInfo::SignalMap &Symbols) override {
+ int FD;
+ SmallString<128> ResultPath;
+ llvm::sys::fs::createUniqueFile(
+ OutputDir + "/" + llvm::sys::path::filename(FileName) + "-%%%%%%.yaml",
+ FD, ResultPath);
+ llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
+ WriteSymbolInfosToStream(OS, Symbols);
}
-
-private:
- std::map<std::string, std::set<SymbolInfo>> Symbols;
};
bool Merge(llvm::StringRef MergeDir, llvm::StringRef OutputFile) {
std::error_code EC;
- std::map<SymbolInfo, int> SymbolToNumOccurrences;
+ SymbolInfo::SignalMap Symbols;
std::mutex SymbolMutex;
- auto AddSymbols = [&](ArrayRef<SymbolInfo> Symbols) {
+ auto AddSymbols = [&](ArrayRef<SymbolAndSignals> NewSymbols) {
// Synchronize set accesses.
std::unique_lock<std::mutex> LockGuard(SymbolMutex);
- for (const auto &Symbol : Symbols)
- ++SymbolToNumOccurrences[Symbol];
+ for (const auto &Symbol : NewSymbols) {
+ Symbols[Symbol.Symbol] += Symbol.Signals;
+ }
};
// Load all symbol files in MergeDir.
@@ -109,8 +101,13 @@ bool Merge(llvm::StringRef MergeDir, llv
llvm::errs() << "Can't open " << Path << "\n";
return;
}
- std::vector<SymbolInfo> Symbols =
+ std::vector<SymbolAndSignals> Symbols =
ReadSymbolInfosFromYAML(Buffer.get()->getBuffer());
+ for (auto &Symbol : Symbols) {
+ // Only count one occurrence per file, to avoid spam.
+ Symbol.Signals.Seen = std::min(Symbol.Signals.Seen, 1u);
+ Symbol.Signals.Used = std::min(Symbol.Signals.Used, 1u);
+ }
// FIXME: Merge without creating such a heavy contention point.
AddSymbols(Symbols);
},
@@ -124,14 +121,7 @@ bool Merge(llvm::StringRef MergeDir, llv
<< '\n';
return false;
}
- std::set<SymbolInfo> Result;
- for (const auto &Entry : SymbolToNumOccurrences) {
- const auto &Symbol = Entry.first;
- Result.insert(SymbolInfo(Symbol.getName(), Symbol.getSymbolKind(),
- Symbol.getFilePath(), Symbol.getLineNumber(),
- Symbol.getContexts(), Entry.second));
- }
- WriteSymbolInfosToStream(OS, Result);
+ WriteSymbolInfosToStream(OS, Symbols);
return true;
}
Modified: clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp Tue Feb 28 02:13:15 2017
@@ -158,6 +158,8 @@ cl::opt<std::string>
std::unique_ptr<include_fixer::SymbolIndexManager>
createSymbolIndexManager(StringRef FilePath) {
+ using find_all_symbols::SymbolInfo;
+
auto SymbolIndexMgr = llvm::make_unique<include_fixer::SymbolIndexManager>();
switch (DatabaseFormat) {
case fixed: {
@@ -167,17 +169,19 @@ createSymbolIndexManager(StringRef FileP
std::map<std::string, std::vector<std::string>> SymbolsMap;
SmallVector<StringRef, 4> SemicolonSplits;
StringRef(Input).split(SemicolonSplits, ";");
- std::vector<find_all_symbols::SymbolInfo> Symbols;
+ std::vector<find_all_symbols::SymbolAndSignals> Symbols;
for (StringRef Pair : SemicolonSplits) {
auto Split = Pair.split('=');
std::vector<std::string> Headers;
SmallVector<StringRef, 4> CommaSplits;
Split.second.split(CommaSplits, ",");
for (size_t I = 0, E = CommaSplits.size(); I != E; ++I)
- Symbols.push_back(find_all_symbols::SymbolInfo(
- Split.first.trim(),
- find_all_symbols::SymbolInfo::SymbolKind::Unknown,
- CommaSplits[I].trim(), 1, {}, /*NumOccurrences=*/E - I));
+ Symbols.push_back(
+ {SymbolInfo(Split.first.trim(), SymbolInfo::SymbolKind::Unknown,
+ CommaSplits[I].trim(), 1, {}),
+ // Use fake "seen" signal for tests, so first header wins.
+ SymbolInfo::Signals(/*Seen=*/static_cast<unsigned>(E - I),
+ /*Used=*/0)});
}
SymbolIndexMgr->addSymbolIndex([=]() {
return llvm::make_unique<include_fixer::InMemorySymbolIndex>(Symbols);
Modified: clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml (original)
+++ clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml Tue Feb 28 02:13:15 2017
@@ -8,7 +8,8 @@ Contexts:
FilePath: foo.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 0
---
Name: bar
Contexts:
@@ -19,7 +20,8 @@ Contexts:
FilePath: ../include/bar.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 0
---
Name: bar
Contexts:
@@ -30,7 +32,8 @@ Contexts:
FilePath: ../include/bar.h
LineNumber: 2
Type: Class
-NumOccurrences: 3
+Seen: 3
+Used: 0
---
Name: bar
Contexts:
@@ -41,14 +44,16 @@ Contexts:
FilePath: ../include/zbar.h
LineNumber: 1
Type: Class
-NumOccurrences: 3
+Seen: 3
+Used: 0
---
Name: b
Contexts:
FilePath: var.h
LineNumber: 1
Type: Variable
-NumOccurrences: 1
+Seen: 1
+Used: 0
---
Name: bar
Contexts:
@@ -57,4 +62,5 @@ Contexts:
FilePath: test/include-fixer/baz.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 0
Modified: clang-tools-extra/trunk/test/include-fixer/Inputs/merge/a.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/Inputs/merge/a.yaml?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/Inputs/merge/a.yaml (original)
+++ clang-tools-extra/trunk/test/include-fixer/Inputs/merge/a.yaml Tue Feb 28 02:13:15 2017
@@ -6,7 +6,8 @@ Contexts:
FilePath: foo.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 1
...
---
Name: bar
@@ -16,5 +17,6 @@ Contexts:
FilePath: ../include/bar.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 2
...
Modified: clang-tools-extra/trunk/test/include-fixer/Inputs/merge/b.yaml
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/Inputs/merge/b.yaml?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/Inputs/merge/b.yaml (original)
+++ clang-tools-extra/trunk/test/include-fixer/Inputs/merge/b.yaml Tue Feb 28 02:13:15 2017
@@ -6,7 +6,8 @@ Contexts:
FilePath: foo.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 2
...
---
Name: bar
@@ -16,5 +17,6 @@ Contexts:
FilePath: ../include/barbar.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 0
...
Modified: clang-tools-extra/trunk/test/include-fixer/merge.test
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/include-fixer/merge.test?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/include-fixer/merge.test (original)
+++ clang-tools-extra/trunk/test/include-fixer/merge.test Tue Feb 28 02:13:15 2017
@@ -9,7 +9,8 @@ Contexts:
FilePath: ../include/bar.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 1
...
---
Name: bar
@@ -19,7 +20,8 @@ Contexts:
FilePath: ../include/barbar.h
LineNumber: 1
Type: Class
-NumOccurrences: 1
+Seen: 1
+Used: 0
...
---
Name: foo
@@ -29,5 +31,6 @@ Contexts:
FilePath: foo.h
LineNumber: 1
Type: Class
-NumOccurrences: 2
+Seen: 2
+Used: 2
...
Modified: clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp Tue Feb 28 02:13:15 2017
@@ -19,6 +19,7 @@ namespace include_fixer {
namespace {
using find_all_symbols::SymbolInfo;
+using find_all_symbols::SymbolAndSignals;
static bool runOnCode(tooling::ToolAction *ToolAction, StringRef Code,
StringRef FileName,
@@ -52,42 +53,49 @@ static bool runOnCode(tooling::ToolActio
static std::string runIncludeFixer(
StringRef Code,
const std::vector<std::string> &ExtraArgs = std::vector<std::string>()) {
- std::vector<SymbolInfo> Symbols = {
- SymbolInfo("string", SymbolInfo::SymbolKind::Class, "<string>", 1,
- {{SymbolInfo::ContextType::Namespace, "std"}}),
- SymbolInfo("sting", SymbolInfo::SymbolKind::Class, "\"sting\"", 1,
- {{SymbolInfo::ContextType::Namespace, "std"}}),
- SymbolInfo("foo", SymbolInfo::SymbolKind::Class, "\"dir/otherdir/qux.h\"",
- 1, {{SymbolInfo::ContextType::Namespace, "b"},
- {SymbolInfo::ContextType::Namespace, "a"}}),
- SymbolInfo("bar", SymbolInfo::SymbolKind::Class, "\"bar.h\"", 1,
- {{SymbolInfo::ContextType::Namespace, "b"},
- {SymbolInfo::ContextType::Namespace, "a"}}),
- SymbolInfo("bar", SymbolInfo::SymbolKind::Class, "\"bar2.h\"", 1,
- {{SymbolInfo::ContextType::Namespace, "c"},
- {SymbolInfo::ContextType::Namespace, "a"}}),
- SymbolInfo("Green", SymbolInfo::SymbolKind::Class, "\"color.h\"", 1,
- {{SymbolInfo::ContextType::EnumDecl, "Color"},
- {SymbolInfo::ContextType::Namespace, "b"},
- {SymbolInfo::ContextType::Namespace, "a"}}),
- SymbolInfo("Vector", SymbolInfo::SymbolKind::Class, "\"Vector.h\"", 1,
- {{SymbolInfo::ContextType::Namespace, "__a"},
- {SymbolInfo::ContextType::Namespace, "a"}},
- /*num_occurrences=*/2),
- SymbolInfo("Vector", SymbolInfo::SymbolKind::Class, "\"Vector.h\"", 2,
- {{SymbolInfo::ContextType::Namespace, "a"}},
- /*num_occurrences=*/1),
- SymbolInfo("StrCat", SymbolInfo::SymbolKind::Class, "\"strcat.h\"",
- 1, {{SymbolInfo::ContextType::Namespace, "str"}}),
- SymbolInfo("str", SymbolInfo::SymbolKind::Class, "\"str.h\"",
- 1, {}),
- SymbolInfo("foo2", SymbolInfo::SymbolKind::Class, "\"foo2.h\"",
- 1, {}),
+ std::vector<SymbolAndSignals> Symbols = {
+ {SymbolInfo("string", SymbolInfo::SymbolKind::Class, "<string>", 1,
+ {{SymbolInfo::ContextType::Namespace, "std"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("sting", SymbolInfo::SymbolKind::Class, "\"sting\"", 1,
+ {{SymbolInfo::ContextType::Namespace, "std"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("foo", SymbolInfo::SymbolKind::Class,
+ "\"dir/otherdir/qux.h\"", 1,
+ {{SymbolInfo::ContextType::Namespace, "b"},
+ {SymbolInfo::ContextType::Namespace, "a"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("bar", SymbolInfo::SymbolKind::Class, "\"bar.h\"", 1,
+ {{SymbolInfo::ContextType::Namespace, "b"},
+ {SymbolInfo::ContextType::Namespace, "a"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("bar", SymbolInfo::SymbolKind::Class, "\"bar2.h\"", 1,
+ {{SymbolInfo::ContextType::Namespace, "c"},
+ {SymbolInfo::ContextType::Namespace, "a"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("Green", SymbolInfo::SymbolKind::Class, "\"color.h\"", 1,
+ {{SymbolInfo::ContextType::EnumDecl, "Color"},
+ {SymbolInfo::ContextType::Namespace, "b"},
+ {SymbolInfo::ContextType::Namespace, "a"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("Vector", SymbolInfo::SymbolKind::Class, "\"Vector.h\"", 1,
+ {{SymbolInfo::ContextType::Namespace, "__a"},
+ {SymbolInfo::ContextType::Namespace, "a"}}),
+ SymbolInfo::Signals{/*Seen=*/2, 0}},
+ {SymbolInfo("Vector", SymbolInfo::SymbolKind::Class, "\"Vector.h\"", 2,
+ {{SymbolInfo::ContextType::Namespace, "a"}}),
+ SymbolInfo::Signals{/*Seen=*/2, 0}},
+ {SymbolInfo("StrCat", SymbolInfo::SymbolKind::Class, "\"strcat.h\"", 1,
+ {{SymbolInfo::ContextType::Namespace, "str"}}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("str", SymbolInfo::SymbolKind::Class, "\"str.h\"", 1, {}),
+ SymbolInfo::Signals{}},
+ {SymbolInfo("foo2", SymbolInfo::SymbolKind::Class, "\"foo2.h\"", 1, {}),
+ SymbolInfo::Signals{}},
};
- auto SymbolIndexMgr = llvm::make_unique<include_fixer::SymbolIndexManager>();
- SymbolIndexMgr->addSymbolIndex([=]() {
- return llvm::make_unique<include_fixer::InMemorySymbolIndex>(Symbols);
- });
+ auto SymbolIndexMgr = llvm::make_unique<SymbolIndexManager>();
+ SymbolIndexMgr->addSymbolIndex(
+ [=]() { return llvm::make_unique<InMemorySymbolIndex>(Symbols); });
std::vector<IncludeFixerContext> FixerContexts;
IncludeFixerActionFactory Factory(*SymbolIndexMgr, FixerContexts, "llvm");
@@ -96,15 +104,14 @@ static std::string runIncludeFixer(
assert(FixerContexts.size() == 1);
if (FixerContexts.front().getHeaderInfos().empty())
return Code;
- auto Replaces = clang::include_fixer::createIncludeFixerReplacements(
- Code, FixerContexts.front());
+ auto Replaces = createIncludeFixerReplacements(Code, FixerContexts.front());
EXPECT_TRUE(static_cast<bool>(Replaces))
<< llvm::toString(Replaces.takeError()) << "\n";
if (!Replaces)
return "";
- clang::RewriterTestContext Context;
- clang::FileID ID = Context.createInMemoryFile(FakeFileName, Code);
- clang::tooling::applyAllReplacements(*Replaces, Context.Rewrite);
+ RewriterTestContext Context;
+ FileID ID = Context.createInMemoryFile(FakeFileName, Code);
+ tooling::applyAllReplacements(*Replaces, Context.Rewrite);
return Context.getRewrittenText(ID);
}
Modified: clang-tools-extra/trunk/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp?rev=296446&r1=296445&r2=296446&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp Tue Feb 28 02:13:15 2017
@@ -19,6 +19,7 @@
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"
@@ -31,25 +32,28 @@ namespace find_all_symbols {
static const char HeaderName[] = "symbols.h";
-class TestSymbolReporter : public clang::find_all_symbols::SymbolReporter {
+class TestSymbolReporter : public SymbolReporter {
public:
~TestSymbolReporter() override {}
- void reportSymbol(llvm::StringRef FileName,
- const SymbolInfo &Symbol) override {
- Symbols.push_back(Symbol);
+ void reportSymbols(llvm::StringRef FileName,
+ const SymbolInfo::SignalMap &NewSymbols) override {
+ for (const auto &Entry : NewSymbols)
+ Symbols[Entry.first] += Entry.second;
}
bool hasSymbol(const SymbolInfo &Symbol) const {
- for (const auto &S : Symbols) {
- if (S == Symbol)
- return true;
- }
- return false;
+ auto it = Symbols.find(Symbol);
+ return it != Symbols.end() && it->second.Seen > 0;
+ }
+
+ bool hasUse(const SymbolInfo &Symbol) const {
+ auto it = Symbols.find(Symbol);
+ return it != Symbols.end() && it->second.Used > 0;
}
private:
- std::vector<SymbolInfo> Symbols;
+ SymbolInfo::SignalMap Symbols;
};
class FindAllSymbolsTest : public ::testing::Test {
@@ -58,7 +62,9 @@ public:
return Reporter.hasSymbol(Symbol);
}
- bool runFindAllSymbols(StringRef Code) {
+ bool hasUse(const SymbolInfo &Symbol) { return Reporter.hasUse(Symbol); }
+
+ bool runFindAllSymbols(StringRef HeaderCode, StringRef MainCode) {
llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
new vfs::InMemoryFileSystem);
llvm::IntrusiveRefCntPtr<FileManager> Files(
@@ -88,7 +94,7 @@ public:
InMemoryFileSystem->addFile(InternalHeader, 0,
llvm::MemoryBuffer::getMemBuffer(InternalCode));
- std::unique_ptr<clang::tooling::FrontendActionFactory> Factory(
+ std::unique_ptr<tooling::FrontendActionFactory> Factory(
new FindAllSymbolsActionFactory(&Reporter, &RegexMap));
tooling::ToolInvocation Invocation(
@@ -98,7 +104,7 @@ public:
std::make_shared<PCHContainerOperations>());
InMemoryFileSystem->addFile(HeaderName, 0,
- llvm::MemoryBuffer::getMemBuffer(Code));
+ llvm::MemoryBuffer::getMemBuffer(HeaderCode));
std::string Content = "#include\"" + std::string(HeaderName) +
"\"\n"
@@ -118,6 +124,7 @@ public:
SymbolInfo DirtySymbol("ExtraInternal", SymbolInfo::SymbolKind::Class,
CleanHeader, 2, {});
#endif // _MSC_VER && __MINGW32__
+ Content += "\n" + MainCode.str();
InMemoryFileSystem->addFile(FileName, 0,
llvm::MemoryBuffer::getMemBuffer(Content));
Invocation.run();
@@ -135,49 +142,64 @@ protected:
};
TEST_F(FindAllSymbolsTest, VariableSymbols) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
extern int xargc;
namespace na {
static bool SSSS = false;
namespace nb { const long long *XXXX; }
})";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ auto y = &na::nb::XXXX;
+ int main() { if (na::SSSS) return xargc; }
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("xargc", SymbolInfo::SymbolKind::Variable, HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("SSSS", SymbolInfo::SymbolKind::Variable, HeaderName, 4,
{{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("XXXX", SymbolInfo::SymbolKind::Variable, HeaderName, 5,
{{SymbolInfo::ContextType::Namespace, "nb"},
{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, ExternCSymbols) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
extern "C" {
int C_Func() { return 0; }
struct C_struct {
int Member;
};
})";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ C_struct q() {
+ int(*ptr)() = C_Func;
+ return {0};
+ }
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("C_Func", SymbolInfo::SymbolKind::Function, HeaderName, 3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol =
SymbolInfo("C_struct", SymbolInfo::SymbolKind::Class, HeaderName, 4, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, CXXRecordSymbols) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
struct Glob {};
struct A; // Not a defintion, ignored.
class NOP; // Not a defintion, ignored
@@ -190,26 +212,33 @@ TEST_F(FindAllSymbolsTest, CXXRecordSymb
};
}; //
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ static Glob glob;
+ static na::A::AAAA* a;
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("Glob", SymbolInfo::SymbolKind::Class, HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("A", SymbolInfo::SymbolKind::Class, HeaderName, 6,
{{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("AAA", SymbolInfo::SymbolKind::Class, HeaderName, 7,
{{SymbolInfo::ContextType::Record, "A"},
{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_FALSE(hasSymbol(Symbol));
+ EXPECT_FALSE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, CXXRecordSymbolsTemplate) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
template <typename T>
- class T_TEMP {
+ struct T_TEMP {
template <typename _Tp1>
struct rebind { typedef T_TEMP<_Tp1> other; };
};
@@ -222,11 +251,15 @@ TEST_F(FindAllSymbolsTest, CXXRecordSymb
// Ignore specialization.
template <> class Observer<int> {};
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ extern T_TEMP<int>::rebind<char> weirdo;
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("T_TEMP", SymbolInfo::SymbolKind::Class, HeaderName, 3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, DontIgnoreTemplatePartialSpecialization) {
@@ -239,7 +272,7 @@ TEST_F(FindAllSymbolsTest, DontIgnoreTem
template<class T> void f() {};
template<> void f<int>() {};
)";
- runFindAllSymbols(Code);
+ runFindAllSymbols(Code, "");
SymbolInfo Symbol =
SymbolInfo("Class", SymbolInfo::SymbolKind::Class, HeaderName, 4, {});
EXPECT_TRUE(hasSymbol(Symbol));
@@ -252,7 +285,7 @@ TEST_F(FindAllSymbolsTest, DontIgnoreTem
}
TEST_F(FindAllSymbolsTest, FunctionSymbols) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
namespace na {
int gg(int);
int f(const int &a) { int Local; static int StaticLocal; return 0; }
@@ -265,91 +298,127 @@ TEST_F(FindAllSymbolsTest, FunctionSymbo
} // namespace nb
} // namespace na";
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ int(*gg)(int) = &na::gg;
+ int main() {
+ (void)na::SSSFFF;
+ na::nb::fun(0);
+ return na::f(gg(0));
+ }
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("gg", SymbolInfo::SymbolKind::Function, HeaderName, 3,
{{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("f", SymbolInfo::SymbolKind::Function, HeaderName, 4,
{{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("SSSFFF", SymbolInfo::SymbolKind::Function, HeaderName, 5,
{{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("fun", SymbolInfo::SymbolKind::Function, HeaderName, 10,
{{SymbolInfo::ContextType::Namespace, "nb"},
{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, NamespaceTest) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
int X1;
namespace { int X2; }
namespace { namespace { int X3; } }
namespace { namespace nb { int X4; } }
namespace na { inline namespace __1 { int X5; } }
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ using namespace nb;
+ int main() {
+ X1 = X2;
+ X3 = X4;
+ (void)na::X5;
+ }
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("X1", SymbolInfo::SymbolKind::Variable, HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("X2", SymbolInfo::SymbolKind::Variable, HeaderName, 3,
{{SymbolInfo::ContextType::Namespace, ""}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("X3", SymbolInfo::SymbolKind::Variable, HeaderName, 4,
{{SymbolInfo::ContextType::Namespace, ""},
{SymbolInfo::ContextType::Namespace, ""}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("X4", SymbolInfo::SymbolKind::Variable, HeaderName, 5,
{{SymbolInfo::ContextType::Namespace, "nb"},
{SymbolInfo::ContextType::Namespace, ""}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("X5", SymbolInfo::SymbolKind::Variable, HeaderName, 6,
{{SymbolInfo::ContextType::Namespace, "na"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, DecayedTypeTest) {
- static const char Code[] = "void DecayedFunc(int x[], int y[10]) {}";
- runFindAllSymbols(Code);
+ static const char Header[] = "void DecayedFunc(int x[], int y[10]) {}";
+ static const char Main[] = R"(int main() { DecayedFunc(nullptr, nullptr); })";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol = SymbolInfo(
"DecayedFunc", SymbolInfo::SymbolKind::Function, HeaderName, 1, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, CTypedefTest) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
typedef unsigned size_t_;
typedef struct { int x; } X;
using XX = X;
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ size_t_ f;
+ template<typename T> struct vector{};
+ vector<X> list;
+ void foo(const XX&){}
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol = SymbolInfo("size_t_", SymbolInfo::SymbolKind::TypedefName,
HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol =
SymbolInfo("X", SymbolInfo::SymbolKind::TypedefName, HeaderName, 3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol =
SymbolInfo("XX", SymbolInfo::SymbolKind::TypedefName, HeaderName, 4, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, EnumTest) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
enum Glob_E { G1, G2 };
enum class Altitude { high='h', low='l'};
enum { A1, A2 };
@@ -359,42 +428,58 @@ TEST_F(FindAllSymbolsTest, EnumTest) {
};
enum DECL : int;
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ static auto flags = G1 | G2;
+ static auto alt = Altitude::high;
+ static auto nested = A::X1;
+ extern DECL whatever;
+ static auto flags2 = A1 | A2;
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("Glob_E", SymbolInfo::SymbolKind::EnumDecl, HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_FALSE(hasUse(Symbol));
Symbol =
SymbolInfo("G1", SymbolInfo::SymbolKind::EnumConstantDecl, HeaderName, 2,
{{SymbolInfo::ContextType::EnumDecl, "Glob_E"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol =
SymbolInfo("G2", SymbolInfo::SymbolKind::EnumConstantDecl, HeaderName, 2,
{{SymbolInfo::ContextType::EnumDecl, "Glob_E"}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("Altitude", SymbolInfo::SymbolKind::EnumDecl, HeaderName,
3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol =
SymbolInfo("high", SymbolInfo::SymbolKind::EnumConstantDecl, HeaderName,
3, {{SymbolInfo::ContextType::EnumDecl, "Altitude"}});
EXPECT_FALSE(hasSymbol(Symbol));
+ EXPECT_FALSE(hasUse(Symbol));
Symbol = SymbolInfo("A1", SymbolInfo::SymbolKind::EnumConstantDecl,
HeaderName, 4, {{SymbolInfo::ContextType::EnumDecl, ""}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("A2", SymbolInfo::SymbolKind::EnumConstantDecl,
HeaderName, 4, {{SymbolInfo::ContextType::EnumDecl, ""}});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("", SymbolInfo::SymbolKind::EnumDecl, HeaderName, 4, {});
EXPECT_FALSE(hasSymbol(Symbol));
+ EXPECT_FALSE(hasUse(Symbol));
Symbol = SymbolInfo("A_ENUM", SymbolInfo::SymbolKind::EnumDecl, HeaderName, 7,
{{SymbolInfo::ContextType::Record, "A"}});
EXPECT_FALSE(hasSymbol(Symbol));
+ EXPECT_FALSE(hasUse(Symbol));
Symbol = SymbolInfo("X1", SymbolInfo::SymbolKind::EnumDecl, HeaderName, 7,
{{SymbolInfo::ContextType::EnumDecl, "A_ENUM"},
@@ -407,63 +492,83 @@ TEST_F(FindAllSymbolsTest, EnumTest) {
}
TEST_F(FindAllSymbolsTest, IWYUPrivatePragmaTest) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
// IWYU pragma: private, include "bar.h"
struct Bar {
};
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ Bar bar;
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("Bar", SymbolInfo::SymbolKind::Class, "bar.h", 3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, MacroTest) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
#define X
#define Y 1
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ #ifdef X
+ int main() { return MAX(0,Y); }
+ #endif
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("X", SymbolInfo::SymbolKind::Macro, HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("Y", SymbolInfo::SymbolKind::Macro, HeaderName, 3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("MAX", SymbolInfo::SymbolKind::Macro, HeaderName, 4, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, MacroTestWithIWYU) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
// IWYU pragma: private, include "bar.h"
- #define X
+ #define X 1
#define Y 1
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
)";
- runFindAllSymbols(Code);
+ static const char Main[] = R"(
+ #ifdef X
+ int main() { return MAX(0,Y); }
+ #endif
+ )";
+ runFindAllSymbols(Header, Main);
SymbolInfo Symbol =
SymbolInfo("X", SymbolInfo::SymbolKind::Macro, "bar.h", 3, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("Y", SymbolInfo::SymbolKind::Macro, "bar.h", 4, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
Symbol = SymbolInfo("MAX", SymbolInfo::SymbolKind::Macro, "bar.h", 5, {});
EXPECT_TRUE(hasSymbol(Symbol));
+ EXPECT_TRUE(hasUse(Symbol));
}
TEST_F(FindAllSymbolsTest, NoFriendTest) {
- static const char Code[] = R"(
+ static const char Header[] = R"(
class WorstFriend {
friend void Friend();
friend class BestFriend;
};
)";
- runFindAllSymbols(Code);
+ runFindAllSymbols(Header, "");
SymbolInfo Symbol = SymbolInfo("WorstFriend", SymbolInfo::SymbolKind::Class,
HeaderName, 2, {});
EXPECT_TRUE(hasSymbol(Symbol));
More information about the cfe-commits
mailing list