Index: include-fixer/find-all-symbols/CMakeLists.txt =================================================================== --- include-fixer/find-all-symbols/CMakeLists.txt +++ include-fixer/find-all-symbols/CMakeLists.txt @@ -7,6 +7,7 @@ FindAllSymbolsAction.cpp FindAllMacros.cpp HeaderMapCollector.cpp + PathConfig.cpp PragmaCommentHandler.cpp STLPostfixHeaderMap.cpp SymbolInfo.cpp Index: include-fixer/find-all-symbols/FindAllMacros.cpp =================================================================== --- include-fixer/find-all-symbols/FindAllMacros.cpp +++ include-fixer/find-all-symbols/FindAllMacros.cpp @@ -9,6 +9,7 @@ #include "FindAllMacros.h" #include "HeaderMapCollector.h" +#include "PathConfig.h" #include "SymbolInfo.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceManager.h" @@ -21,21 +22,11 @@ void FindAllMacros::MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) { SourceLocation Loc = SM->getExpansionLoc(MacroNameTok.getLocation()); - if (Loc.isInvalid() || SM->isInMainFile(Loc)) - return; - - llvm::StringRef FilePath = SM->getFilename(Loc); - if (FilePath.empty()) - return; - - // If Collector is not nullptr, check pragma remapping header. - FilePath = Collector ? Collector->getMappedHeader(FilePath) : FilePath; - - SmallString<256> CleanedFilePath = FilePath; - llvm::sys::path::remove_dots(CleanedFilePath, /*remove_dot_dot=*/true); + std::string FilePath = getIncludePath(*SM, Loc, Collector); + if (FilePath.empty()) return; SymbolInfo Symbol(MacroNameTok.getIdentifierInfo()->getName(), - SymbolInfo::SymbolKind::Macro, CleanedFilePath, + SymbolInfo::SymbolKind::Macro, FilePath, SM->getSpellingLineNumber(Loc), {}); Reporter->reportSymbol(SM->getFileEntryForID(SM->getMainFileID())->getName(), Index: include-fixer/find-all-symbols/FindAllSymbols.cpp =================================================================== --- include-fixer/find-all-symbols/FindAllSymbols.cpp +++ include-fixer/find-all-symbols/FindAllSymbols.cpp @@ -9,6 +9,7 @@ #include "FindAllSymbols.h" #include "HeaderMapCollector.h" +#include "PathConfig.h" #include "SymbolInfo.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -92,17 +93,11 @@ << ") has invalid declaration location."; return llvm::None; } - llvm::StringRef FilePath = SM.getFilename(Loc); - if (FilePath.empty()) - return llvm::None; - - // If Collector is not nullptr, check pragma remapping header. - FilePath = Collector ? Collector->getMappedHeader(FilePath) : FilePath; - SmallString<256> CleanedFilePath = FilePath; - llvm::sys::path::remove_dots(CleanedFilePath, /*remove_dot_dot=*/true); + std::string FilePath = getIncludePath(SM, Loc, Collector); + if (FilePath.empty()) return llvm::None; - return SymbolInfo(ND->getNameAsString(), Type, CleanedFilePath, + return SymbolInfo(ND->getNameAsString(), Type, FilePath, SM.getExpansionLineNumber(Loc), GetContexts(ND)); } Index: include-fixer/find-all-symbols/PathConfig.h =================================================================== --- /dev/null +++ include-fixer/find-all-symbols/PathConfig.h @@ -0,0 +1,37 @@ +//===-- PathConfig.h - Process paths of symbols -----------------*- 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_PATH_CONFIG_H +#define LLVM_CLANG_TOOLS_EXTRA_FIND_ALL_SYMBOLS_PATH_CONFIG_H + +#include "HeaderMapCollector.h" +#include "clang/Basic/SourceManager.h" +#include + +namespace clang { +namespace find_all_symbols { + +/// \brief This calculates the include path for \p Loc. +/// +/// \param SM SourceManager. +/// \param Loc A SourceLocation. +/// \param Collector An optional header mapping collector. +/// +/// \return The file path (or mapped file path if Collector is provided) of the +/// header that includes \p Loc. If \p Loc comes from .inc header file, \p Loc +/// is set to the location from which the .inc header file is included. If \p +/// Loc is invalid or comes from a main file, this returns an empty string. +std::string getIncludePath(const SourceManager &SM, SourceLocation Loc, + const HeaderMapCollector *Collector = nullptr); + +} // namespace find_all_symbols +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_FIND_ALL_SYMBOLS_PATH_CONFIG_H Index: include-fixer/find-all-symbols/PathConfig.cpp =================================================================== --- /dev/null +++ include-fixer/find-all-symbols/PathConfig.cpp @@ -0,0 +1,42 @@ +//===-- PathConfig.cpp - Process paths of symbols ---------------*- C++ -*-===// +// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PathConfig.h" +#include "llvm/Support/Path.h" + +namespace clang { +namespace find_all_symbols { + +std::string getIncludePath(const SourceManager &SM, SourceLocation Loc, + const HeaderMapCollector *Collector) { + llvm::StringRef FilePath; + while (true) { + if (!Loc.isValid() || SM.isInMainFile(Loc)) + return ""; + FilePath = SM.getFilename(Loc); + if (FilePath.empty()) + return ""; + if (!FilePath.endswith(".inc")) + break; + FileID ID = SM.getFileID(Loc); + Loc = SM.getIncludeLoc(ID); + } + + // If Collector is not nullptr, check pragma remapping header. + FilePath = Collector ? Collector->getMappedHeader(FilePath) : FilePath; + + SmallString<256> CleanedFilePath = FilePath; + llvm::sys::path::remove_dots(CleanedFilePath, /*remove_dot_dot=*/true); + + return CleanedFilePath.str(); +} + +} // namespace find_all_symbols +} // namespace clang Index: unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp =================================================================== --- unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp +++ unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp @@ -68,13 +68,23 @@ const std::string InternalHeader = "internal/internal.h"; const std::string TopHeader = ""; + // Test .inc header path. The header for `IncHeaderClass` should be + // internal.h, which will eventually be mapped to . + std::string IncHeader = "internal/private.inc"; + std::string IncHeaderCode = "class IncHeaderClass {};"; + HeaderMapCollector::HeaderMap PostfixMap = { {"internal.h", TopHeader}, }; - std::string InternalCode = "class Internal {};"; + std::string InternalCode = + "#include \"private.inc\"\nclass Internal {};"; SymbolInfo InternalSymbol("Internal", SymbolInfo::SymbolKind::Class, - TopHeader, 1, {}); + TopHeader, 2, {}); + SymbolInfo IncSymbol("IncHeaderClass", SymbolInfo::SymbolKind::Class, + TopHeader, 1, {}); + InMemoryFileSystem->addFile( + IncHeader, 0, llvm::MemoryBuffer::getMemBuffer(IncHeaderCode)); InMemoryFileSystem->addFile(InternalHeader, 0, llvm::MemoryBuffer::getMemBuffer(InternalCode)); @@ -111,6 +121,7 @@ llvm::MemoryBuffer::getMemBuffer(Content)); Invocation.run(); EXPECT_TRUE(hasSymbol(InternalSymbol)); + EXPECT_TRUE(hasSymbol(IncSymbol)); #if !defined(_MSC_VER) && !defined(__MINGW32__) EXPECT_TRUE(hasSymbol(DirtySymbol)); EXPECT_TRUE(hasSymbol(DirtyMacro));