fn_inserter.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "migrate_cpp/cpp_refactoring/fn_inserter.h"
  5. #include "clang/ASTMatchers/ASTMatchers.h"
  6. // NOLINTNEXTLINE(readability-identifier-naming)
  7. namespace cam = ::clang::ast_matchers;
  8. namespace Carbon {
  9. static constexpr char Label[] = "FnInserter";
  10. void FnInserter::Run() {
  11. const auto& decl = GetNodeAsOrDie<clang::FunctionDecl>(Label);
  12. // For names like "Class::Method", replace up to "Class" not "Method".
  13. clang::NestedNameSpecifierLoc qual_loc = decl.getQualifierLoc();
  14. clang::SourceLocation name_begin_loc =
  15. qual_loc.hasQualifier() ? qual_loc.getBeginLoc() : decl.getLocation();
  16. auto range =
  17. clang::CharSourceRange::getCharRange(decl.getBeginLoc(), name_begin_loc);
  18. // In order to handle keywords like "virtual" in "virtual auto Foo() -> ...",
  19. // scan the replaced text and only drop auto/void entries.
  20. llvm::SmallVector<llvm::StringRef> split;
  21. GetSourceText(range).split(split, ' ', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
  22. std::string new_text = "fn ";
  23. for (llvm::StringRef t : split) {
  24. if (t != "auto" && t != "void") {
  25. new_text += t.str() + " ";
  26. }
  27. }
  28. AddReplacement(range, new_text);
  29. }
  30. void FnInserterFactory::AddMatcher(cam::MatchFinder* finder,
  31. cam::MatchFinder::MatchCallback* callback) {
  32. finder->addMatcher(
  33. cam::functionDecl(cam::anyOf(cam::hasTrailingReturn(),
  34. cam::returns(cam::asString("void"))),
  35. cam::unless(cam::anyOf(cam::cxxConstructorDecl(),
  36. cam::cxxDestructorDecl())))
  37. .bind(Label),
  38. callback);
  39. }
  40. } // namespace Carbon