diff options
5 files changed, 162 insertions, 56 deletions
diff --git a/clang-tools-extra/include-fixer/InMemoryXrefsDB.cpp b/clang-tools-extra/include-fixer/InMemoryXrefsDB.cpp index 2a71d9dd81c..4db4c717519 100644 --- a/clang-tools-extra/include-fixer/InMemoryXrefsDB.cpp +++ b/clang-tools-extra/include-fixer/InMemoryXrefsDB.cpp @@ -28,7 +28,8 @@ InMemoryXrefsDB::InMemoryXrefsDB(                                *IdentiferContext);        } -      SymbolInfo Symbol(Names.back(), SymbolInfo::Class, Header, Contexts, 1); +      SymbolInfo Symbol(Names.back(), SymbolInfo::SymbolKind::Class, Header, +                        Contexts, 1);        this->LookupTable[Symbol.getName()].push_back(Symbol);      }    } diff --git a/clang-tools-extra/include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/include-fixer/find-all-symbols/FindAllSymbols.cpp index 508c11211ba..4cff03a34c4 100644 --- a/clang-tools-extra/include-fixer/find-all-symbols/FindAllSymbols.cpp +++ b/clang-tools-extra/include-fixer/find-all-symbols/FindAllSymbols.cpp @@ -23,6 +23,13 @@ using namespace clang::ast_matchers;  namespace clang {  namespace find_all_symbols {  namespace { + +AST_MATCHER(EnumConstantDecl, isInScopedEnum) { +  if (const auto *ED = dyn_cast<EnumDecl>(Node.getDeclContext())) +    return ED->isScoped(); +  return false; +} +  std::vector<SymbolInfo::Context> GetContexts(const NamedDecl *ND) {    std::vector<SymbolInfo::Context> Contexts;    for (const auto *Context = ND->getDeclContext(); Context; @@ -34,12 +41,16 @@ std::vector<SymbolInfo::Context> GetContexts(const NamedDecl *ND) {      assert(llvm::isa<NamedDecl>(Context) &&             "Expect Context to be a NamedDecl");      if (const auto *NSD = dyn_cast<NamespaceDecl>(Context)) { -      Contexts.emplace_back(SymbolInfo::Namespace, NSD->isAnonymousNamespace() -                                                       ? "" -                                                       : NSD->getName().str()); +      Contexts.emplace_back(SymbolInfo::ContextType::Namespace, +                            NSD->isAnonymousNamespace() ? "" +                                                        : NSD->getName().str()); +    } else if (const auto *ED = dyn_cast<EnumDecl>(Context)) { +      Contexts.emplace_back(SymbolInfo::ContextType::EnumDecl, +                            ED->getName().str());      } else {        const auto *RD = cast<RecordDecl>(Context); -      Contexts.emplace_back(SymbolInfo::Record, RD->getName().str()); +      Contexts.emplace_back(SymbolInfo::ContextType::Record, +                            RD->getName().str());      }    }    return Contexts; @@ -49,19 +60,24 @@ llvm::Optional<SymbolInfo> CreateSymbolInfo(const NamedDecl *ND,                                              const SourceManager &SM) {    SymbolInfo::SymbolKind Type;    if (llvm::isa<VarDecl>(ND)) { -    Type = SymbolInfo::Variable; +    Type = SymbolInfo::SymbolKind::Variable;    } else if (llvm::isa<FunctionDecl>(ND)) { -    Type = SymbolInfo::Function; +    Type = SymbolInfo::SymbolKind::Function;    } else if (llvm::isa<TypedefNameDecl>(ND)) { -    Type = SymbolInfo::TypedefName; +    Type = SymbolInfo::SymbolKind::TypedefName; +  } else if (llvm::isa<EnumConstantDecl>(ND)) { +    Type = SymbolInfo::SymbolKind::EnumConstantDecl; +  } else if (llvm::isa<EnumDecl>(ND)) { +    Type = SymbolInfo::SymbolKind::EnumDecl;    } else { -    assert(llvm::isa<RecordDecl>(ND) && "Matched decl must be one of VarDecl, " -                                        "FunctionDecl, TypedefNameDecl and " -                                        "RecordDecl!"); +    assert(llvm::isa<RecordDecl>(ND) && +           "Matched decl must be one of VarDecl, " +           "FunctionDecl, TypedefNameDecl, EnumConstantDecl, " +           "EnumDecl and RecordDecl!");      // C-style record decl can have empty name, e.g "struct { ... } var;".      if (ND->getName().empty())        return llvm::None; -    Type = SymbolInfo::Class; +    Type = SymbolInfo::SymbolKind::Class;    }    SourceLocation Loc = SM.getExpansionLoc(ND->getLocation()); @@ -159,6 +175,23 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {                                            hasDeclContext(linkageSpecDecl())))            .bind("decl"),        this); + +  // Matchers for enum declarations. +  MatchFinder->addMatcher( +      enumDecl(CommonFilter, anyOf(HasNSOrTUCtxMatcher, ExternCMatcher)) +          .bind("decl"), +      this); + +  // 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. +  MatchFinder->addMatcher( +      enumConstantDecl( +          CommonFilter, +          unless(isInScopedEnum()), +          anyOf(hasDeclContext(enumDecl(HasNSOrTUCtxMatcher)), ExternCMatcher)) +          .bind("decl"), +      this);  }  void FindAllSymbols::run(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.cpp b/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.cpp index 54e29cd5bfc..8b412a154cc 100644 --- a/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.cpp +++ b/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.cpp @@ -49,6 +49,9 @@ template <> struct ScalarEnumerationTraits<SymbolKind> {      io.enumCase(value, "Function", SymbolKind::Function);      io.enumCase(value, "Class", SymbolKind::Class);      io.enumCase(value, "TypedefName", SymbolKind::TypedefName); +    io.enumCase(value, "EnumDecl", SymbolKind::EnumDecl); +    io.enumCase(value, "EnumConstantDecl", SymbolKind::EnumConstantDecl); +    io.enumCase(value, "Unknown", SymbolKind::Unknown);    }  }; diff --git a/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.h b/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.h index 7893a49f0bc..f831aa125f8 100644 --- a/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.h +++ b/clang-tools-extra/include-fixer/find-all-symbols/SymbolInfo.h @@ -25,18 +25,21 @@ namespace find_all_symbols {  class SymbolInfo {  public:    /// \brief The SymbolInfo Type. -  enum SymbolKind { +  enum class SymbolKind {      Function,      Class,      Variable,      TypedefName, +    EnumDecl, +    EnumConstantDecl,      Unknown,    };    /// \brief The Context Type. -  enum ContextType { +  enum class ContextType {      Namespace, // Symbols declared in a namespace.      Record,    // Symbols declared in a class. +    EnumDecl,  // Enum constants declared in a enum declaration.    };    /// \brief A pair of <ContextType, ContextName>. @@ -44,7 +47,7 @@ public:    // The default constructor is required by YAML traits in    // LLVM_YAML_IS_DOCUMENT_LIST_VECTOR. -  SymbolInfo() : Type(Unknown), LineNumber(-1) {}; +  SymbolInfo() : Type(SymbolKind::Unknown), LineNumber(-1) {};    SymbolInfo(llvm::StringRef Name, SymbolKind Type, llvm::StringRef FilePath,               const std::vector<Context> &Contexts, int LineNumber); diff --git a/clang-tools-extra/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp b/clang-tools-extra/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp index d265c61d364..29562ba424a 100644 --- a/clang-tools-extra/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp +++ b/clang-tools-extra/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp @@ -104,17 +104,19 @@ TEST_F(FindAllSymbolsTest, VariableSymbols) {        })";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("xargc", SymbolInfo::Variable, HeaderName, 2, {}); +  SymbolInfo Symbol = CreateSymbolInfo( +      "xargc", SymbolInfo::SymbolKind::Variable, HeaderName, 2, {});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("SSSS", SymbolInfo::Variable, HeaderName, 4, -                            {{SymbolInfo::Namespace, "na"}}); +  Symbol = +      CreateSymbolInfo("SSSS", SymbolInfo::SymbolKind::Variable, HeaderName, 4, +                       {{SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo( -      "XXXX", SymbolInfo::Variable, HeaderName, 5, -      {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, "na"}}); +  Symbol = +      CreateSymbolInfo("XXXX", SymbolInfo::SymbolKind::Variable, HeaderName, 5, +                       {{SymbolInfo::ContextType::Namespace, "nb"}, +                        {SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol));  } @@ -128,11 +130,12 @@ TEST_F(FindAllSymbolsTest, ExternCSymbols) {        })";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("C_Func", SymbolInfo::Function, HeaderName, 3, {}); +  SymbolInfo Symbol = CreateSymbolInfo( +      "C_Func", SymbolInfo::SymbolKind::Function, HeaderName, 3, {});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("C_struct", SymbolInfo::Class, HeaderName, 4, {}); +  Symbol = CreateSymbolInfo("C_struct", SymbolInfo::SymbolKind::Class, +                            HeaderName, 4, {});    EXPECT_TRUE(hasSymbol(Symbol));  } @@ -152,13 +155,18 @@ TEST_F(FindAllSymbolsTest, CXXRecordSymbols) {        )";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("Glob", SymbolInfo::Class, HeaderName, 2, {}); +  SymbolInfo Symbol = CreateSymbolInfo("Glob", SymbolInfo::SymbolKind::Class, +                                       HeaderName, 2, {});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("A", SymbolInfo::Class, HeaderName, 6, -                            {{SymbolInfo::Namespace, "na"}}); +  Symbol = CreateSymbolInfo("A", SymbolInfo::SymbolKind::Class, HeaderName, 6, +                            {{SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol)); + +  Symbol = CreateSymbolInfo("AAA", SymbolInfo::SymbolKind::Class, HeaderName, 7, +                            {{SymbolInfo::ContextType::Record, "A"}, +                             {SymbolInfo::ContextType::Namespace, "na"}}); +  EXPECT_FALSE(hasSymbol(Symbol));  }  TEST_F(FindAllSymbolsTest, CXXRecordSymbolsTemplate) { @@ -179,8 +187,8 @@ TEST_F(FindAllSymbolsTest, CXXRecordSymbolsTemplate) {        )";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("T_TEMP", SymbolInfo::Class, HeaderName, 3, {}); +  SymbolInfo Symbol = CreateSymbolInfo("T_TEMP", SymbolInfo::SymbolKind::Class, +                                       HeaderName, 3, {});    EXPECT_TRUE(hasSymbol(Symbol));  } @@ -200,21 +208,23 @@ TEST_F(FindAllSymbolsTest, FunctionSymbols) {        )";    runFindAllSymbols(Code); -  SymbolInfo Symbol = CreateSymbolInfo("gg", SymbolInfo::Function, HeaderName, -                                       3, {{SymbolInfo::Namespace, "na"}}); +  SymbolInfo Symbol = +      CreateSymbolInfo("gg", SymbolInfo::SymbolKind::Function, HeaderName, 3, +                       {{SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("f", SymbolInfo::Function, HeaderName, 4, -                            {{SymbolInfo::Namespace, "na"}}); +  Symbol = CreateSymbolInfo("f", SymbolInfo::SymbolKind::Function, HeaderName, +                            4, {{SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("SSSFFF", SymbolInfo::Function, HeaderName, 5, -                            {{SymbolInfo::Namespace, "na"}}); +  Symbol = +      CreateSymbolInfo("SSSFFF", SymbolInfo::SymbolKind::Function, HeaderName, +                       5, {{SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo( -      "fun", SymbolInfo::Function, HeaderName, 10, -      {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, "na"}}); +  Symbol = CreateSymbolInfo("fun", SymbolInfo::SymbolKind::Function, HeaderName, +                            10, {{SymbolInfo::ContextType::Namespace, "nb"}, +                                 {SymbolInfo::ContextType::Namespace, "na"}});    EXPECT_TRUE(hasSymbol(Symbol));  } @@ -227,30 +237,30 @@ TEST_F(FindAllSymbolsTest, NamespaceTest) {        )";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("X1", SymbolInfo::Variable, HeaderName, 2, {}); +  SymbolInfo Symbol = CreateSymbolInfo("X1", SymbolInfo::SymbolKind::Variable, +                                       HeaderName, 2, {});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("X2", SymbolInfo::Variable, HeaderName, 3, -                            {{SymbolInfo::Namespace, ""}}); +  Symbol = CreateSymbolInfo("X2", SymbolInfo::SymbolKind::Variable, HeaderName, +                            3, {{SymbolInfo::ContextType::Namespace, ""}});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo( -      "X3", SymbolInfo::Variable, HeaderName, 4, -      {{SymbolInfo::Namespace, ""}, {SymbolInfo::Namespace, ""}}); +  Symbol = CreateSymbolInfo("X3", SymbolInfo::SymbolKind::Variable, HeaderName, +                            4, {{SymbolInfo::ContextType::Namespace, ""}, +                                {SymbolInfo::ContextType::Namespace, ""}});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo( -      "X4", SymbolInfo::Variable, HeaderName, 5, -      {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, ""}}); +  Symbol = CreateSymbolInfo("X4", SymbolInfo::SymbolKind::Variable, HeaderName, +                            5, {{SymbolInfo::ContextType::Namespace, "nb"}, +                                {SymbolInfo::ContextType::Namespace, ""}});    EXPECT_TRUE(hasSymbol(Symbol));  }  TEST_F(FindAllSymbolsTest, DecayedTypeTest) {    static const char Code[] = "void DecayedFunc(int x[], int y[10]) {}";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("DecayedFunc", SymbolInfo::Function, HeaderName, 1, {}); +  SymbolInfo Symbol = CreateSymbolInfo( +      "DecayedFunc", SymbolInfo::SymbolKind::Function, HeaderName, 1, {});    EXPECT_TRUE(hasSymbol(Symbol));  } @@ -262,16 +272,72 @@ TEST_F(FindAllSymbolsTest, CTypedefTest) {        )";    runFindAllSymbols(Code); -  SymbolInfo Symbol = -      CreateSymbolInfo("size_t_", SymbolInfo::TypedefName, HeaderName, 2, {}); +  SymbolInfo Symbol = CreateSymbolInfo( +      "size_t_", SymbolInfo::SymbolKind::TypedefName, HeaderName, 2, {});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("X", SymbolInfo::TypedefName, HeaderName, 3, {}); +  Symbol = CreateSymbolInfo("X", SymbolInfo::SymbolKind::TypedefName, +                            HeaderName, 3, {});    EXPECT_TRUE(hasSymbol(Symbol)); -  Symbol = CreateSymbolInfo("XX", SymbolInfo::TypedefName, HeaderName, 4, {}); +  Symbol = CreateSymbolInfo("XX", SymbolInfo::SymbolKind::TypedefName, +                            HeaderName, 4, {});    EXPECT_TRUE(hasSymbol(Symbol));  } +TEST_F(FindAllSymbolsTest, EnumTest) { +  static const char Code[] = R"( +      enum Glob_E { G1, G2 }; +      enum class Altitude { high='h', low='l'}; +      enum { A1, A2 }; +      class A { +      public: +        enum A_ENUM { X1, X2 }; +      }; +      )"; +  runFindAllSymbols(Code); + +  SymbolInfo Symbol = CreateSymbolInfo( +      "Glob_E", SymbolInfo::SymbolKind::EnumDecl, HeaderName, 2, {}); +  EXPECT_TRUE(hasSymbol(Symbol)); + +  Symbol = CreateSymbolInfo("G1", SymbolInfo::SymbolKind::EnumConstantDecl, +                            HeaderName, 2, +                            {{SymbolInfo::ContextType::EnumDecl, "Glob_E"}}); +  EXPECT_TRUE(hasSymbol(Symbol)); + +  Symbol = CreateSymbolInfo("G2", SymbolInfo::SymbolKind::EnumConstantDecl, +                            HeaderName, 2, +                            {{SymbolInfo::ContextType::EnumDecl, "Glob_E"}}); +  EXPECT_TRUE(hasSymbol(Symbol)); + +  Symbol = CreateSymbolInfo("Altitude", SymbolInfo::SymbolKind::EnumDecl, +                            HeaderName, 3, {}); +  EXPECT_TRUE(hasSymbol(Symbol)); +  Symbol = CreateSymbolInfo("high", SymbolInfo::SymbolKind::EnumConstantDecl, +                            HeaderName, 3, +                            {{SymbolInfo::ContextType::EnumDecl, "Altitude"}}); +  EXPECT_FALSE(hasSymbol(Symbol)); + +  Symbol = CreateSymbolInfo("A1", SymbolInfo::SymbolKind::EnumConstantDecl, +                            HeaderName, 4, +                            {{SymbolInfo::ContextType::EnumDecl, ""}}); +  EXPECT_TRUE(hasSymbol(Symbol)); +  Symbol = CreateSymbolInfo("A2", SymbolInfo::SymbolKind::EnumConstantDecl, +                            HeaderName, 4, +                            {{SymbolInfo::ContextType::EnumDecl, ""}}); +  EXPECT_TRUE(hasSymbol(Symbol)); + +  Symbol = +      CreateSymbolInfo("A_ENUM", SymbolInfo::SymbolKind::EnumDecl, HeaderName, +                       7, {{SymbolInfo::ContextType::Record, "A"}}); +  EXPECT_FALSE(hasSymbol(Symbol)); + +  Symbol = CreateSymbolInfo("X1", SymbolInfo::SymbolKind::EnumDecl, HeaderName, +                            7, {{SymbolInfo::ContextType::EnumDecl, "A_ENUM"}, +                                {SymbolInfo::ContextType::Record, "A"}}); +  EXPECT_FALSE(hasSymbol(Symbol)); +} +  } // namespace find_all_symbols  } // namespace clang  | 

