Index: clang/test/Analysis/func-mapping-path.c =================================================================== --- /dev/null +++ clang/test/Analysis/func-mapping-path.c @@ -0,0 +1,3 @@ +// RUN: %clang_extdef_map %s -m '^(.*)clang(.*)$' -r '\1ctu-dir\2.ast' -- | FileCheck %s +// CHECK: {{ctu-dir.*func-mapping-path\.c\.ast}} +void f() {} Index: clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp =================================================================== --- clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp +++ clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp @@ -30,11 +30,45 @@ using namespace clang::tooling; static cl::OptionCategory ClangExtDefMapGenCategory("clang-extdefmapgen options"); +static cl::opt OutputPathAdjusterMatcher( + "m", cl::desc("Match the part of output path to be replaced with regex"), + cl::cat(ClangExtDefMapGenCategory)); +static cl::opt OutputPathAdjusterNewPath( + "r", cl::desc("The string which matched pattern will be replaced to"), + cl::cat(ClangExtDefMapGenCategory)); + +namespace { +class OutputPathAdjuster { + Regex Matcher; + std::string NewPath; + +public: + std::string adjust(StringRef Path) const { + return Matcher.sub(NewPath, Path); + } + + bool resetMatcher(StringRef MatcherStr, StringRef NewPathStr); +}; + +bool OutputPathAdjuster::resetMatcher(StringRef MatcherStr, + StringRef NewPathStr) { + std::string ErrMsg; + Regex MatcherRegex(MatcherStr); + if (!MatcherRegex.isValid(ErrMsg)) { + errs() << "Invalid adjuster template: " << ErrMsg << '\n'; + return false; + } + + Matcher = std::move(MatcherRegex); + NewPath = NewPathStr.str(); + return true; +} +} // namespace class MapExtDefNamesConsumer : public ASTConsumer { public: - MapExtDefNamesConsumer(ASTContext &Context) - : Ctx(Context), SM(Context.getSourceManager()) {} + MapExtDefNamesConsumer(const OutputPathAdjuster *Adjuster) + : Adjuster(Adjuster) {} ~MapExtDefNamesConsumer() { // Flush results to standard output. @@ -49,10 +83,9 @@ void handleDecl(const Decl *D); void addIfInMain(const DeclaratorDecl *DD, SourceLocation defStart); - ASTContext &Ctx; - SourceManager &SM; llvm::StringMap Index; std::string CurrentFileName; + const OutputPathAdjuster *Adjuster = nullptr; }; void MapExtDefNamesConsumer::handleDecl(const Decl *D) { @@ -64,7 +97,7 @@ if (const Stmt *Body = FD->getBody()) addIfInMain(FD, Body->getBeginLoc()); } else if (const auto *VD = dyn_cast(D)) { - if (cross_tu::containsConst(VD, Ctx) && VD->hasInit()) + if (cross_tu::containsConst(VD, VD->getASTContext()) && VD->hasInit()) if (const Expr *Init = VD->getInit()) addIfInMain(VD, Init->getBeginLoc()); } @@ -82,9 +115,12 @@ return; assert(!LookupName->empty() && "Lookup name should be non-empty."); + SourceManager &SM = DD->getASTContext().getSourceManager(); if (CurrentFileName.empty()) { CurrentFileName = std::string( SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName()); + if (Adjuster) + CurrentFileName = Adjuster->adjust(CurrentFileName); if (CurrentFileName.empty()) CurrentFileName = "invalid_file"; } @@ -101,11 +137,15 @@ } } -class MapExtDefNamesAction : public ASTFrontendAction { -protected: - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - llvm::StringRef) override { - return std::make_unique(CI.getASTContext()); +class MapExtDefNamesConsumerFactory { + const OutputPathAdjuster *Adjuster = nullptr; + +public: + MapExtDefNamesConsumerFactory(const OutputPathAdjuster *Adjuster) + : Adjuster(Adjuster) {} + + std::unique_ptr newASTConsumer() { + return std::make_unique(Adjuster); } }; @@ -118,7 +158,8 @@ const char *Overview = "\nThis tool collects the USR name and location " "of external definitions in the source files " - "(excluding headers).\n"; + "(excluding headers).\n\nReset output path with -m " + " -r .\n"; auto ExpectedParser = CommonOptionsParser::create( argc, argv, ClangExtDefMapGenCategory, cl::ZeroOrMore, Overview); if (!ExpectedParser) { @@ -127,8 +168,17 @@ } CommonOptionsParser &OptionsParser = ExpectedParser.get(); + std::unique_ptr Adjuster; + if (!OutputPathAdjusterMatcher.empty()) { + Adjuster = std::make_unique(); + if (!Adjuster->resetMatcher(OutputPathAdjusterMatcher, + OutputPathAdjusterNewPath)) + return 1; + } + ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); - return Tool.run(newFrontendActionFactory().get()); + MapExtDefNamesConsumerFactory Factory(Adjuster.get()); + return Tool.run(newFrontendActionFactory(&Factory).get()); }