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:
malte_langkabel
2016-11-03 09:08:35 +01:00
parent f80a371d44
commit 5b47d195ff
6 changed files with 97 additions and 22 deletions
+11 -1
View File
@@ -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);
+2 -1
View File
@@ -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);
+34 -3
View File
@@ -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()
+35 -10
View File
@@ -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()