Skip to content

Commit

Permalink
[find-all-symbols] Added hardcode header mapping from header postfix …
Browse files Browse the repository at this point in the history
…to header name for STL symbols.

Summary: [find-all-symbols] Added hardcode header mapping from header postfix to header name for STL symbols.

Reviewers: klimek, bkramer

Subscribers: cfe-commits, hokein

Differential Revision: http://reviews.llvm.org/D20566

llvm-svn: 270566
  • Loading branch information
Eric Liu committed May 24, 2016
1 parent 7175c2c commit a7d1941
Show file tree
Hide file tree
Showing 12 changed files with 569 additions and 99 deletions.
Expand Up @@ -4,7 +4,9 @@ set(LLVM_LINK_COMPONENTS

add_clang_library(findAllSymbols
FindAllSymbols.cpp
FindAllSymbolsAction.cpp
FindAllMacros.cpp
HeaderMapCollector.cpp
PragmaCommentHandler.cpp
SymbolInfo.cpp

Expand Down
Expand Up @@ -28,11 +28,7 @@ void FindAllMacros::MacroDefined(const Token &MacroNameTok,
return;

// If Collector is not nullptr, check pragma remapping header.
if (Collector) {
auto Iter = Collector->getHeaderMappingTable().find(FilePath);
if (Iter != Collector->getHeaderMappingTable().end())
FilePath = Iter->second;
}
FilePath = Collector ? Collector->getMappedHeader(FilePath) : FilePath;

SymbolInfo Symbol(MacroNameTok.getIdentifierInfo()->getName(),
SymbolInfo::SymbolKind::Macro, FilePath.str(),
Expand Down
Expand Up @@ -97,11 +97,7 @@ CreateSymbolInfo(const NamedDecl *ND, const SourceManager &SM,
return llvm::None;

// If Collector is not nullptr, check pragma remapping header.
if (Collector) {
auto Iter = Collector->getHeaderMappingTable().find(FilePath);
if (Iter != Collector->getHeaderMappingTable().end())
FilePath = Iter->second;
}
FilePath = Collector ? Collector->getMappedHeader(FilePath) : FilePath;

return SymbolInfo(ND->getNameAsString(), Type, FilePath.str(),
SM.getExpansionLineNumber(Loc), GetContexts(ND));
Expand Down
@@ -0,0 +1,32 @@
//===-- FindAllSymbolsAction.cpp - find all symbols action --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "FindAllSymbolsAction.h"

namespace clang {
namespace find_all_symbols {

FindAllSymbolsAction::FindAllSymbolsAction(
SymbolReporter *Reporter, const HeaderMapCollector::HeaderMap *PostfixMap)
: Reporter(Reporter), Collector(PostfixMap), Handler(&Collector),
Matcher(Reporter, &Collector) {
Matcher.registerMatchers(&MatchFinder);
}

std::unique_ptr<clang::ASTConsumer>
FindAllSymbolsAction::CreateASTConsumer(clang::CompilerInstance &Compiler,
StringRef InFile) {
Compiler.getPreprocessor().addCommentHandler(&Handler);
Compiler.getPreprocessor().addPPCallbacks(llvm::make_unique<FindAllMacros>(
Reporter, &Compiler.getSourceManager(), &Collector));
return MatchFinder.newASTConsumer();
}

} // namespace find_all_symbols
} // namespace clang
@@ -0,0 +1,61 @@
//===-- FindAllSymbolsAction.h - find all symbols action --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_FIND_ALL_SYMBOLS_FIND_ALL_SYMBOLS_ACTION_H
#define LLVM_CLANG_TOOLS_EXTRA_FIND_ALL_SYMBOLS_FIND_ALL_SYMBOLS_ACTION_H

#include "FindAllMacros.h"
#include "FindAllSymbols.h"
#include "HeaderMapCollector.h"
#include "PragmaCommentHandler.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/Tooling.h"

namespace clang {
namespace find_all_symbols {

class FindAllSymbolsAction : public clang::ASTFrontendAction {
public:
explicit FindAllSymbolsAction(
SymbolReporter *Reporter,
const HeaderMapCollector::HeaderMap *PostfixMap = nullptr);

std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler,
StringRef InFile) override;

private:
SymbolReporter *const Reporter;
clang::ast_matchers::MatchFinder MatchFinder;
HeaderMapCollector Collector;
PragmaCommentHandler Handler;
FindAllSymbols Matcher;
};

class FindAllSymbolsActionFactory : public tooling::FrontendActionFactory {
public:
FindAllSymbolsActionFactory(
SymbolReporter *Reporter,
const HeaderMapCollector::HeaderMap *PostfixMap = nullptr)
: Reporter(Reporter), PostfixMap(PostfixMap) {}

virtual clang::FrontendAction *create() override {
return new FindAllSymbolsAction(Reporter, PostfixMap);
}

private:
SymbolReporter *const Reporter;
const HeaderMapCollector::HeaderMap *const PostfixMap;
};

} // namespace find_all_symbols
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_FIND_ALL_SYMBOLS_FIND_ALL_SYMBOLS_ACTION_H
@@ -0,0 +1,34 @@
//===-- HeaderMapCoolector.h - find all symbols------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "HeaderMapCollector.h"

namespace clang {
namespace find_all_symbols {

llvm::StringRef
HeaderMapCollector::getMappedHeader(llvm::StringRef Header) const {
auto Iter = HeaderMappingTable.find(Header);
if (Iter != HeaderMappingTable.end())
return Iter->second;
// If there is no complete header name mapping for this header, check the
// postfix mapping.
// FIXME: this is not very efficient. Change PostfixMappingTable to use
// postfix tree if necessary.
if (PostfixMappingTable) {
for (const auto &Entry : *PostfixMappingTable) {
if (Header.endswith(Entry.first()))
return Entry.second;
}
}
return Header;
}

} // namespace find_all_symbols
} // namespace clang
Expand Up @@ -16,20 +16,36 @@
namespace clang {
namespace find_all_symbols {

/// \brief HeaderMappCollector collects all remapping header files.
/// \brief HeaderMappCollector collects all remapping header files. This maps
/// complete header names or postfixes of header names to header names.
class HeaderMapCollector {
public:
typedef llvm::StringMap<std::string> HeaderMap;

HeaderMapCollector() : PostfixMappingTable(nullptr) {}

explicit HeaderMapCollector(const HeaderMap *PostfixMap)
: PostfixMappingTable(PostfixMap) {}

void addHeaderMapping(llvm::StringRef OrignalHeaderPath,
llvm::StringRef MappingHeaderPath) {
HeaderMappingTable[OrignalHeaderPath] = MappingHeaderPath;
};
const HeaderMap &getHeaderMappingTable() const { return HeaderMappingTable; };

/// Check if there is a mapping from \p Header or its postfix to another
/// header name.
/// \param Header A header name.
/// \return \p Header itself if there is no mapping for it; otherwise, return
/// a mapped header name.
llvm::StringRef getMappedHeader(llvm::StringRef Header) const;

private:
/// A string-to-string map saving the mapping relationship.
HeaderMap HeaderMappingTable;

// A postfix-to-header name map.
// This is a reference to a hard-coded map.
const HeaderMap *const PostfixMappingTable;
};

} // namespace find_all_symbols
Expand Down
@@ -1,6 +1,9 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)

add_clang_executable(find-all-symbols FindAllSymbolsMain.cpp)
add_clang_executable(find-all-symbols
FindAllSymbolsMain.cpp
STLPostfixHeaderMap.cpp
)
target_link_libraries(find-all-symbols

clangAST
Expand Down
Expand Up @@ -7,10 +7,8 @@
//
//===----------------------------------------------------------------------===//

#include "FindAllMacros.h"
#include "FindAllSymbols.h"
#include "HeaderMapCollector.h"
#include "PragmaCommentHandler.h"
#include "FindAllSymbolsAction.h"
#include "STLPostfixHeaderMap.h"
#include "SymbolInfo.h"
#include "SymbolReporter.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
Expand Down Expand Up @@ -61,60 +59,32 @@ static cl::opt<std::string> MergeDir("merge-dir", cl::desc(R"(
The directory for merging symbols.)"),
cl::init(""),
cl::cat(FindAllSymbolsCategory));

namespace clang {
namespace find_all_symbols {

class YamlReporter : public clang::find_all_symbols::SymbolReporter {
public:
~YamlReporter() override {}

void reportSymbol(StringRef FileName, const SymbolInfo &Symbol) override {
Symbols[FileName].insert(Symbol);
}

void Write(const std::string &Dir) {
~YamlReporter() override {
for (const auto &Symbol : Symbols) {
int FD;
SmallString<128> ResultPath;
llvm::sys::fs::createUniqueFile(
Dir + "/" + llvm::sys::path::filename(Symbol.first) + "-%%%%%%.yaml",
OutputDir + "/" + llvm::sys::path::filename(Symbol.first) +
"-%%%%%%.yaml",
FD, ResultPath);
llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true);
WriteSymbolInfosToStream(OS, Symbol.second);
}
}

private:
std::map<std::string, std::set<SymbolInfo>> Symbols;
};

// FIXME: Move this out from the main file, make it reusable in unittest.
class FindAllSymbolsAction : public clang::ASTFrontendAction {
public:
FindAllSymbolsAction()
: Reporter(), MatchFinder(), Collector(), Handler(&Collector),
Matcher(&Reporter, &Collector) {
Matcher.registerMatchers(&MatchFinder);
}

std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler,
StringRef InFile) override {
Compiler.getPreprocessor().addCommentHandler(&Handler);
Compiler.getPreprocessor().addPPCallbacks(llvm::make_unique<FindAllMacros>(
&Reporter, &Compiler.getSourceManager(), &Collector));
return MatchFinder.newASTConsumer();
void reportSymbol(StringRef FileName, const SymbolInfo &Symbol) override {
Symbols[FileName].insert(Symbol);
}

void EndSourceFileAction() override { Reporter.Write(OutputDir); }

private:
YamlReporter Reporter;
clang::ast_matchers::MatchFinder MatchFinder;
HeaderMapCollector Collector;
PragmaCommentHandler Handler;
FindAllSymbols Matcher;
// Directory to write yaml files to.
const std::string Directory;
std::map<std::string, std::set<SymbolInfo>> Symbols;
};

bool Merge(llvm::StringRef MergeDir, llvm::StringRef OutputFile) {
Expand Down Expand Up @@ -176,8 +146,12 @@ int main(int argc, const char **argv) {
clang::find_all_symbols::Merge(MergeDir, sources[0]);
return 0;
}
Tool.run(
newFrontendActionFactory<clang::find_all_symbols::FindAllSymbolsAction>()
.get());

clang::find_all_symbols::YamlReporter Reporter;

auto Factory =
llvm::make_unique<clang::find_all_symbols::FindAllSymbolsActionFactory>(
&Reporter, &clang::find_all_symbols::STLPostfixHeaderMap);
Tool.run(Factory.get());
return 0;
}

0 comments on commit a7d1941

Please sign in to comment.