Index: include-fixer/InMemoryXrefsDB.cpp =================================================================== --- include-fixer/InMemoryXrefsDB.cpp +++ include-fixer/InMemoryXrefsDB.cpp @@ -21,16 +21,17 @@ llvm::SmallVector Names; Identifier.split(Names, "::"); for (const auto &Header : Entry.second) { - // FIXME: create a complete instance with static member function when it - // is implemented. - SymbolInfo Info; - Info.Name = Names.back(); - Info.FilePath = Header; + // Since we don't have all symbol information here, we just construct a + // dummy SymbolInfo with the given contexts and header path. + std::vector Contexts; for (auto IdentiferContext = Names.rbegin() + 1; IdentiferContext != Names.rend(); ++IdentiferContext) { - Info.Contexts.push_back( + Contexts.push_back( {SymbolInfo::ContextType::Namespace, *IdentiferContext}); } + SymbolInfo Info = + SymbolInfo::CreateClassSymbolInfo(Names.back(), Header, Contexts, 1); + this->LookupTable[Info.Name].push_back(Info); } } Index: include-fixer/find-all-symbols/SymbolInfo.h =================================================================== --- include-fixer/find-all-symbols/SymbolInfo.h +++ include-fixer/find-all-symbols/SymbolInfo.h @@ -21,7 +21,6 @@ namespace find_all_symbols { /// \brief Contains all information for a Symbol. -// FIXME: add static members for creating complete instances. struct SymbolInfo { enum SymbolKind { Function, @@ -65,14 +64,22 @@ struct FunctionInfo { std::string ReturnType; std::vector ParameterTypes; + bool operator==(const FunctionInfo &Info) const { + return ReturnType == Info.ReturnType && + ParameterTypes == Info.ParameterTypes; + } }; struct TypedefNameInfo { std::string UnderlyingType; + bool operator==(const TypedefNameInfo &Info) const { + return UnderlyingType == Info.UnderlyingType; + } }; struct VariableInfo { std::string Type; + bool operator==(const VariableInfo &Info) const { return Type == Info.Type; } }; /// \brief The function information. @@ -87,6 +94,33 @@ bool operator==(const SymbolInfo &Symbol) const; bool operator<(const SymbolInfo &Symbol) const; + + static SymbolInfo + CreateFunctionSymbolInfo(const std::string &Name, const std::string &FilePath, + const std::vector &Contexts, int LineNumber, + const FunctionInfo &FuncInfo); + + static SymbolInfo CreateClassSymbolInfo(const std::string &Name, + const std::string &FilePath, + const std::vector &Contexts, + int LineNumber); + + static SymbolInfo + CreateVariableSymbolInfo(const std::string &Name, const std::string &FilePath, + const std::vector &Contexts, int LineNumber, + const VariableInfo &VarInfo); + + static SymbolInfo + CreateTypedefNameSymbolInfo(const std::string &Name, + const std::string &FilePath, + const std::vector &Contexts, + int LineNumber, const TypedefNameInfo &TDInfo); + +private: + static void SetCommonInfo(const std::string &Name, SymbolKind Kind, + const std::string &FilePath, + const std::vector &Contexts, + int LineNumber, SymbolInfo *Info); }; /// \brief Write SymbolInfos to a stream (YAML format). Index: include-fixer/find-all-symbols/SymbolInfo.cpp =================================================================== --- include-fixer/find-all-symbols/SymbolInfo.cpp +++ include-fixer/find-all-symbols/SymbolInfo.cpp @@ -87,9 +87,69 @@ namespace clang { namespace find_all_symbols { +void SymbolInfo::SetCommonInfo(const std::string &Name, SymbolKind Kind, + const std::string &FilePath, + const std::vector &Contexts, + int LineNumber, SymbolInfo *Info) { + Info->Name = Name; + Info->Type = Kind; + Info->FilePath = FilePath; + Info->Contexts = Contexts; + Info->LineNumber = LineNumber; +} + +SymbolInfo SymbolInfo::CreateFunctionSymbolInfo( + const std::string &Name, const std::string &FilePath, + const std::vector &Contexts, int LineNumber, + const FunctionInfo &FuncInfo) { + SymbolInfo Ret; + SetCommonInfo(Name, Function, FilePath, Contexts, LineNumber, &Ret); + Ret.FunctionInfos = FuncInfo; + return Ret; +} + +SymbolInfo SymbolInfo::CreateClassSymbolInfo( + const std::string &Name, const std::string &FilePath, + const std::vector &Contexts, int LineNumber) { + SymbolInfo Ret; + SetCommonInfo(Name, Class, FilePath, Contexts, LineNumber, &Ret); + return Ret; +} + +SymbolInfo SymbolInfo::CreateVariableSymbolInfo( + const std::string &Name, const std::string &FilePath, + const std::vector &Contexts, int LineNumber, + const VariableInfo &VarInfo) { + SymbolInfo Ret; + SetCommonInfo(Name, Variable, FilePath, Contexts, LineNumber, &Ret); + Ret.VariableInfos = VarInfo; + return Ret; +} + +SymbolInfo SymbolInfo::CreateTypedefNameSymbolInfo( + const std::string &Name, const std::string &FilePath, + const std::vector &Contexts, int LineNumber, + const TypedefNameInfo &TDInfo) { + SymbolInfo Ret; + SetCommonInfo(Name, TypedefName, FilePath, Contexts, LineNumber, &Ret); + Ret.TypedefNameInfos = TDInfo; + return Ret; +} + +template +static bool CompareOptionalInfo(const llvm::Optional &LHS, + const llvm::Optional &RHS) { + return (!LHS.hasValue() && !RHS.hasValue()) || + (LHS.hasValue() && RHS.hasValue() && LHS.getValue() == RHS.getValue()); +} + bool SymbolInfo::operator==(const SymbolInfo &Symbol) const { - return Name == Symbol.Name && FilePath == Symbol.FilePath && - LineNumber == Symbol.LineNumber && Contexts == Symbol.Contexts; + return Type == Symbol.Type && Name == Symbol.Name && + FilePath == Symbol.FilePath && LineNumber == Symbol.LineNumber && + Contexts == Symbol.Contexts && + CompareOptionalInfo(FunctionInfos, Symbol.FunctionInfos) && + CompareOptionalInfo(TypedefNameInfos, Symbol.TypedefNameInfos) && + CompareOptionalInfo(VariableInfos, Symbol.VariableInfos); } bool SymbolInfo::operator<(const SymbolInfo &Symbol) const { 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 @@ -46,18 +46,6 @@ return false; } - bool getSymbolExtraInfo(SymbolInfo *Symbol) { - for (const auto &S : Symbols) { - if (S == *Symbol) { - Symbol->FunctionInfos = S.FunctionInfos; - Symbol->TypedefNameInfos = S.TypedefNameInfos; - Symbol->VariableInfos = S.VariableInfos; - return true; - } - } - return false; - } - private: std::vector Symbols; }; @@ -68,10 +56,6 @@ return Reporter.hasSymbol(Symbol); } - bool getSymbolExtraInfo(SymbolInfo &Symbol) { - return Reporter.getSymbolExtraInfo(&Symbol); - } - bool runFindAllSymbols(StringRef Code) { FindAllSymbols matcher(&Reporter); clang::ast_matchers::MatchFinder MatchFinder; @@ -87,7 +71,7 @@ clang::tooling::newFrontendActionFactory(&MatchFinder); tooling::ToolInvocation Invocation( {std::string("find_all_symbols"), std::string("-fsyntax-only"), - FileName}, + std::string("-std=c++11"), FileName}, Factory->create(), Files.get(), std::make_shared()); @@ -105,19 +89,6 @@ MockReporter Reporter; }; -SymbolInfo -CreateSymbolInfo(StringRef Name, SymbolInfo::SymbolKind Type, - const std::string FilePath, int LineNumber, - const std::vector &Contexts) { - SymbolInfo Symbol; - Symbol.Name = Name; - Symbol.Type = Type; - Symbol.FilePath = FilePath; - Symbol.LineNumber = LineNumber; - Symbol.Contexts = Contexts; - return Symbol; -} - TEST_F(FindAllSymbolsTest, VariableSymbols) { static const char Code[] = R"( extern int xargc; @@ -127,29 +98,19 @@ })"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = - CreateSymbolInfo("xargc", SymbolInfo::Variable, HeaderName, 2, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.VariableInfos.getValue().Type); - } - { - SymbolInfo Symbol = - CreateSymbolInfo("SSSS", SymbolInfo::Variable, HeaderName, 4, - {{SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("_Bool", Symbol.VariableInfos.getValue().Type); - } - { - SymbolInfo Symbol = CreateSymbolInfo( - "XXXX", SymbolInfo::Variable, HeaderName, 5, - {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("const long long *", Symbol.VariableInfos.getValue().Type); - } + SymbolInfo Symbol = + SymbolInfo::CreateVariableSymbolInfo("xargc", HeaderName, {}, 2, {"int"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateVariableSymbolInfo( + "SSSS", HeaderName, {{SymbolInfo::Namespace, "na"}}, 4, {"_Bool"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateVariableSymbolInfo( + "XXXX", HeaderName, + {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, "na"}}, 5, + {"const long long *"}); + EXPECT_TRUE(hasSymbol(Symbol)); } TEST_F(FindAllSymbolsTest, ExternCSymbols) { @@ -162,19 +123,12 @@ })"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = - CreateSymbolInfo("C_Func", SymbolInfo::Function, HeaderName, 3, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.FunctionInfos.getValue().ReturnType); - EXPECT_TRUE(Symbol.FunctionInfos.getValue().ParameterTypes.empty()); - } - { - SymbolInfo Symbol = - CreateSymbolInfo("C_struct", SymbolInfo::Class, HeaderName, 4, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - } + SymbolInfo Symbol = SymbolInfo::CreateFunctionSymbolInfo("C_Func", HeaderName, + {}, 3, {"int", {}}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateClassSymbolInfo("C_struct", HeaderName, {}, 4); + EXPECT_TRUE(hasSymbol(Symbol)); } TEST_F(FindAllSymbolsTest, CXXRecordSymbols) { @@ -193,16 +147,12 @@ )"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = - CreateSymbolInfo("Glob", SymbolInfo::Class, HeaderName, 2, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - } - { - SymbolInfo Symbol = CreateSymbolInfo("A", SymbolInfo::Class, HeaderName, 6, - {{SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - } + SymbolInfo Symbol = + SymbolInfo::CreateClassSymbolInfo("Glob", HeaderName, {}, 2); + EXPECT_TRUE(hasSymbol(Symbol)); + Symbol = SymbolInfo::CreateClassSymbolInfo( + "A", HeaderName, {{SymbolInfo::Namespace, "na"}}, 6); + EXPECT_TRUE(hasSymbol(Symbol)); } TEST_F(FindAllSymbolsTest, CXXRecordSymbolsTemplate) { @@ -223,11 +173,9 @@ )"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = - CreateSymbolInfo("T_TEMP", SymbolInfo::Class, HeaderName, 3, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - } + SymbolInfo Symbol = + SymbolInfo::CreateClassSymbolInfo("T_TEMP", HeaderName, {}, 3); + EXPECT_TRUE(hasSymbol(Symbol)); } TEST_F(FindAllSymbolsTest, FunctionSymbols) { @@ -246,43 +194,24 @@ )"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = CreateSymbolInfo("gg", SymbolInfo::Class, HeaderName, 3, - {{SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.FunctionInfos.getValue().ReturnType); - EXPECT_EQ(1u, Symbol.FunctionInfos.getValue().ParameterTypes.size()); - EXPECT_EQ("int", Symbol.FunctionInfos.getValue().ParameterTypes[0]); - } - { - SymbolInfo Symbol = CreateSymbolInfo("f", SymbolInfo::Class, HeaderName, 4, - {{SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.FunctionInfos.getValue().ReturnType); - EXPECT_EQ(1u, Symbol.FunctionInfos.getValue().ParameterTypes.size()); - EXPECT_EQ("const int &", Symbol.FunctionInfos.getValue().ParameterTypes[0]); - } - { - SymbolInfo Symbol = - CreateSymbolInfo("SSSFFF", SymbolInfo::Class, HeaderName, 5, - {{SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("void", Symbol.FunctionInfos.getValue().ReturnType); - EXPECT_TRUE(Symbol.FunctionInfos.getValue().ParameterTypes.empty()); - } - { - SymbolInfo Symbol = CreateSymbolInfo( - "fun", SymbolInfo::Class, HeaderName, 10, - {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("void", Symbol.FunctionInfos.getValue().ReturnType); - EXPECT_EQ(1u, Symbol.FunctionInfos.getValue().ParameterTypes.size()); - EXPECT_EQ("T", Symbol.FunctionInfos.getValue().ParameterTypes[0]); - } + SymbolInfo Symbol = SymbolInfo::CreateFunctionSymbolInfo( + "gg", HeaderName, {{SymbolInfo::Namespace, "na"}}, 3, {"int", {"int"}}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateFunctionSymbolInfo("f", HeaderName, + {{SymbolInfo::Namespace, "na"}}, + 4, {"int", {"const int &"}}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateFunctionSymbolInfo( + "SSSFFF", HeaderName, {{SymbolInfo::Namespace, "na"}}, 5, {"void", {}}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateFunctionSymbolInfo( + "fun", HeaderName, + {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, "na"}}, 10, + {"void", {"T"}}); + EXPECT_TRUE(hasSymbol(Symbol)); } TEST_F(FindAllSymbolsTest, NamespaceTest) { @@ -294,49 +223,31 @@ )"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = - CreateSymbolInfo("X1", SymbolInfo::Variable, HeaderName, 2, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.VariableInfos.getValue().Type); - } - { - SymbolInfo Symbol = CreateSymbolInfo("X2", SymbolInfo::Variable, HeaderName, - 3, {{SymbolInfo::Namespace, ""}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.VariableInfos.getValue().Type); - } - { - SymbolInfo Symbol = CreateSymbolInfo( - "X3", SymbolInfo::Variable, HeaderName, 4, - {{SymbolInfo::Namespace, ""}, {SymbolInfo::Namespace, ""}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.VariableInfos.getValue().Type); - } - { - SymbolInfo Symbol = CreateSymbolInfo( - "X4", SymbolInfo::Variable, HeaderName, 5, - {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, ""}}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("int", Symbol.VariableInfos.getValue().Type); - } + SymbolInfo Symbol = + SymbolInfo::CreateVariableSymbolInfo("X1", HeaderName, {}, 2, {"int"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateVariableSymbolInfo( + "X2", HeaderName, {{SymbolInfo::Namespace, ""}}, 3, {"int"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateVariableSymbolInfo( + "X3", HeaderName, + {{SymbolInfo::Namespace, ""}, {SymbolInfo::Namespace, ""}}, 4, {"int"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateVariableSymbolInfo( + "X4", HeaderName, + {{SymbolInfo::Namespace, "nb"}, {SymbolInfo::Namespace, ""}}, 5, {"int"}); + 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::Class, HeaderName, 1, {}); + SymbolInfo Symbol = SymbolInfo::CreateFunctionSymbolInfo( + "DecayedFunc", HeaderName, {}, 1, {"void", {"int *", "int *"}}); EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("void", Symbol.FunctionInfos.getValue().ReturnType); - EXPECT_EQ(2u, Symbol.FunctionInfos.getValue().ParameterTypes.size()); - EXPECT_EQ("int *", Symbol.FunctionInfos.getValue().ParameterTypes[0]); - EXPECT_EQ("int *", Symbol.FunctionInfos.getValue().ParameterTypes[1]); } TEST_F(FindAllSymbolsTest, CTypedefTest) { @@ -347,28 +258,17 @@ )"; runFindAllSymbols(Code); - { - SymbolInfo Symbol = - CreateSymbolInfo("size_t_", SymbolInfo::TypedefName, HeaderName, 2, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("unsigned int", - Symbol.TypedefNameInfos.getValue().UnderlyingType); - } - { - SymbolInfo Symbol = - CreateSymbolInfo("X", SymbolInfo::TypedefName, HeaderName, 3, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("struct X", Symbol.TypedefNameInfos.getValue().UnderlyingType); - } - { - SymbolInfo Symbol = - CreateSymbolInfo("XX", SymbolInfo::TypedefName, HeaderName, 4, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - getSymbolExtraInfo(Symbol); - EXPECT_EQ("X", Symbol.TypedefNameInfos.getValue().UnderlyingType); - } + SymbolInfo Symbol = SymbolInfo::CreateTypedefNameSymbolInfo( + "size_t_", HeaderName, {}, 2, {"unsigned int"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = SymbolInfo::CreateTypedefNameSymbolInfo("X", HeaderName, {}, 3, + {"struct X"}); + EXPECT_TRUE(hasSymbol(Symbol)); + + Symbol = + SymbolInfo::CreateTypedefNameSymbolInfo("XX", HeaderName, {}, 4, {"X"}); + EXPECT_TRUE(hasSymbol(Symbol)); } } // namespace find_all_symbols