data: fixed anonymous symbol name conflicts (issue #241)
* added start location to symbol name string * added tests for this case
This commit is contained in:
@@ -100,7 +100,7 @@ namespace utility
|
||||
return c;
|
||||
}
|
||||
|
||||
std::string substrBefore(const std::string& str, char delimiter)
|
||||
std::string substrBeforeFirst(const std::string& str, char delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
@@ -110,6 +110,16 @@ namespace utility
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string substrBeforeLast(const std::string& str, char delimiter)
|
||||
{
|
||||
size_t pos = str.rfind(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return str.substr(0, pos);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string substrAfter(const std::string& str, char delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace utility
|
||||
std::deque<std::string> tokenize(const std::deque<std::string>& list, char delimiter);
|
||||
std::deque<std::string> tokenize(const std::deque<std::string>& list, const std::string& delimiter);
|
||||
|
||||
std::string substrBefore(const std::string& str, char delimiter);
|
||||
std::string substrBeforeFirst(const std::string& str, char delimiter);
|
||||
std::string substrBeforeLast(const std::string& str, char delimiter);
|
||||
std::string substrAfter(const std::string& str, char delimiter);
|
||||
|
||||
std::string substrBetween(const std::string& str, const std::string& delimiter1, const std::string& delimiter2);
|
||||
|
||||
@@ -163,8 +163,8 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
const std::string recordType = (recordDecl->isStruct() ? "struct" : "class");
|
||||
return std::make_shared<NameElement>("anonymous " + recordType + " (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
const std::string symbolKindName = (recordDecl->isStruct() ? "struct" : "class");
|
||||
return getNameForAnonymousSymbol(symbolKindName, presumedBegin);
|
||||
}
|
||||
}
|
||||
else if (clang::isa<clang::FunctionDecl>(declaration))
|
||||
@@ -252,13 +252,13 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<NameElement>("anonymous namespace (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
return getNameForAnonymousSymbol("namespace", presumedBegin);
|
||||
}
|
||||
else if (clang::isa<clang::EnumDecl>(declaration) && declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<NameElement>("anonymous enum (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
return getNameForAnonymousSymbol("enum", presumedBegin);
|
||||
}
|
||||
else if (
|
||||
(
|
||||
@@ -269,13 +269,13 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<NameElement>("anonymous template parameter (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
return getNameForAnonymousSymbol("template parameter", presumedBegin);
|
||||
}
|
||||
else if (clang::isa<clang::ParmVarDecl>(declaration) && declNameString.size() == 0)
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
return std::make_shared<NameElement>("anonymous parameter (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
return getNameForAnonymousSymbol("parameter", presumedBegin);
|
||||
}
|
||||
|
||||
if (declNameString.size() > 0)
|
||||
@@ -286,7 +286,7 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName()
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
// LOG_ERROR("could not resolve name of decl at: " + declaration->getLocation().printToString(sourceManager));
|
||||
return std::make_shared<NameElement>("anonymous symbol (" + FilePath(presumedBegin.getFilename()).fileName() + ")");
|
||||
return getNameForAnonymousSymbol("symbol", presumedBegin);
|
||||
}
|
||||
|
||||
std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName(const clang::NamedDecl* declaration)
|
||||
@@ -295,6 +295,13 @@ std::shared_ptr<NameElement> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
return resolver.getDeclName();
|
||||
}
|
||||
|
||||
std::shared_ptr<NameElement> CxxDeclNameResolver::getNameForAnonymousSymbol(const std::string& symbolKindName, const clang::PresumedLoc& presumedBegin)
|
||||
{
|
||||
return std::make_shared<NameElement>("anonymous " + symbolKindName +
|
||||
" (" + FilePath(presumedBegin.getFilename()).fileName() + "<" + std::to_string(presumedBegin.getLine()) + ":" + std::to_string(presumedBegin.getColumn()) + ">)"
|
||||
);
|
||||
}
|
||||
|
||||
std::string CxxDeclNameResolver::getTemplateParameterString(const clang::NamedDecl* parameter)
|
||||
{
|
||||
std::string templateParameterTypeString = "";
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
private:
|
||||
NameHierarchy getContextNameHierarchy(const clang::DeclContext* declaration);
|
||||
std::shared_ptr<NameElement> getDeclName(const clang::NamedDecl* declaration);
|
||||
std::shared_ptr<NameElement> getNameForAnonymousSymbol(const std::string& symbolKindName, const clang::PresumedLoc& presumedBegin);
|
||||
std::string getTemplateParameterString(const clang::NamedDecl* parameter);
|
||||
std::string getTemplateParameterTypeString(const clang::NonTypeTemplateParmDecl* parameter);
|
||||
std::string getTemplateParameterTypeString(const clang::TemplateTypeParmDecl* parameter);
|
||||
|
||||
@@ -221,7 +221,38 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->namespaces.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->namespaces[0], "anonymous namespace (input.cc) <1:1 3:1>");
|
||||
TS_ASSERT_EQUALS(client->namespaces[0], "anonymous namespace (input.cc<1:1>) <1:1 3:1>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_anonymous_struct_declaration()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"} Foo;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->structs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->structs[0], "anonymous struct (input.cc<1:9>) <1:9 <1:9 1:14> 4:1>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_multiple_anonymous_struct_declarations_as_distinct_elements()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" int x;\n"
|
||||
"} Foo;\n"
|
||||
"typedef struct\n"
|
||||
"{\n"
|
||||
" float x;\n"
|
||||
"} Bar;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->structs.size(), 2);
|
||||
TS_ASSERT_EQUALS(client->fields.size(), 2);
|
||||
TS_ASSERT_DIFFERS(utility::substrBeforeLast(client->fields[0], '<'), utility::substrBeforeLast(client->fields[1], '<'));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_enum_defined_in_global_namespace()
|
||||
@@ -282,7 +313,7 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->typedefs.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->typedefs[0], "anonymous namespace (input.cc)::uint <3:23 3:26>");
|
||||
TS_ASSERT_EQUALS(client->typedefs[0], "anonymous namespace (input.cc<1:1>)::uint <3:23 3:26>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_type_alias_in_class()
|
||||
@@ -1019,7 +1050,7 @@ public:
|
||||
);
|
||||
|
||||
TS_ASSERT_EQUALS(client->functions.size(), 1);
|
||||
TS_ASSERT_EQUALS(client->functions[0], "int anonymous namespace (input.cc)::sum(int, int) <3:6 3:8>");
|
||||
TS_ASSERT_EQUALS(client->functions[0], "int anonymous namespace (input.cc<1:1>)::sum(int, int) <3:6 3:8>");
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_method_declared_in_nested_class()
|
||||
|
||||
@@ -156,29 +156,54 @@ public:
|
||||
TS_ASSERT_EQUALS(result.at(6), "D");
|
||||
}
|
||||
|
||||
void test_substr_before_with_single_delimiter_occurence()
|
||||
void test_substr_before_first_with_single_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBefore("foo bar", ' '), "foo");
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foo bar", ' '), "foo");
|
||||
}
|
||||
|
||||
void test_substr_before_with_multiple_delimiter_occurences()
|
||||
void test_substr_before_first_with_multiple_delimiter_occurences()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBefore("foo bar foo", ' '), "foo");
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foo bar foo", ' '), "foo");
|
||||
}
|
||||
|
||||
void test_substr_before_with_no_delimiter_occurence()
|
||||
void test_substr_before_first_with_no_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBefore("foobar", ' '), "foobar");
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foobar", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_before_with_delimiter_at_start()
|
||||
void test_substr_before_first_with_delimiter_at_start()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBefore(" foobar", ' '), "");
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst(" foobar", ' '), "");
|
||||
}
|
||||
|
||||
void test_substr_before_with_delimiter_at_end()
|
||||
void test_substr_before_first_with_delimiter_at_end()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBefore("foobar ", ' '), "foobar");
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeFirst("foobar ", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_single_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foo bar", ' '), "foo");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_multiple_delimiter_occurences()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foo bar foo", ' '), "foo bar");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_no_delimiter_occurence()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foobar", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_delimiter_at_start()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast(" foobar", ' '), "");
|
||||
}
|
||||
|
||||
void test_substr_before_last_with_delimiter_at_end()
|
||||
{
|
||||
TS_ASSERT_EQUALS(utility::substrBeforeLast("foobar ", ' '), "foobar");
|
||||
}
|
||||
|
||||
void test_substr_after_with_single_delimiter_occurence()
|
||||
|
||||
Reference in New Issue
Block a user