logic: fixed bug where anonymous symbols were only partly named like the enclosing typedef

* removed post processing for anonymous typedefs. The storage transformation did not work in
  cases where the typedef is recorded in a previously indexed header. No type information
  was recorded while indexing the header a second time. But this type information would have
  been required by the transformation.
This commit is contained in:
mlangkabel
2017-12-21 19:36:16 +01:00
parent 1a9d736f28
commit 455c1230b1
23 changed files with 167 additions and 380 deletions
-3
View File
@@ -77,9 +77,6 @@ add_files(
data/parser/cxx/PreprocessorCallbacks.h
data/parser/cxx/utilityClang.cpp
data/parser/cxx/utilityClang.h
data/storage/StorageTransformationAnonymousTypedef.cpp
data/storage/StorageTransformationAnonymousTypedef.h
project/IncludeDirective.cpp
project/IncludeDirective.h
@@ -6,14 +6,12 @@ IndexerCommandCxx::IndexerCommandCxx(
const std::set<FilePath>& excludedPaths,
const std::vector<FilePath>& systemHeaderSearchPaths,
const std::vector<FilePath>& frameworkSearchPaths,
const std::vector<std::string>& compilerFlags,
const bool shouldApplyAnonymousTypedefTransformation
const std::vector<std::string>& compilerFlags
)
: IndexerCommand(sourceFilePath, indexedPaths, excludedPaths)
, m_systemHeaderSearchPaths(systemHeaderSearchPaths)
, m_frameworkSearchPaths(frameworkSearchPaths)
, m_compilerFlags(compilerFlags)
, m_shouldApplyAnonymousTypedefTransformation(shouldApplyAnonymousTypedefTransformation)
{
}
@@ -57,8 +55,3 @@ std::vector<std::string> IndexerCommandCxx::getCompilerFlags() const
{
return m_compilerFlags;
}
bool IndexerCommandCxx::shouldApplyAnonymousTypedefTransformation() const
{
return m_shouldApplyAnonymousTypedefTransformation;
}
+1 -5
View File
@@ -18,8 +18,7 @@ public:
const std::set<FilePath>& excludedPaths,
const std::vector<FilePath>& systemHeaderSearchPaths,
const std::vector<FilePath>& frameworkSearchPaths,
const std::vector<std::string>& compilerFlags,
const bool shouldApplyAnonymousTypedefTransformation);
const std::vector<std::string>& compilerFlags);
virtual ~IndexerCommandCxx();
virtual size_t getByteSize(size_t stringSize) const override;
@@ -28,13 +27,10 @@ public:
std::vector<FilePath> getFrameworkSearchPaths() const;
std::vector<std::string> getCompilerFlags() const;
bool shouldApplyAnonymousTypedefTransformation() const;
private:
std::vector<FilePath> m_systemHeaderSearchPaths;
std::vector<FilePath> m_frameworkSearchPaths;
std::vector<std::string> m_compilerFlags;
bool m_shouldApplyAnonymousTypedefTransformation;
};
#endif // INDEXER_COMMAND_CXXL_H
@@ -46,10 +46,9 @@ IndexerCommandCxxCdb::IndexerCommandCxxCdb(
const FilePath& workingDirectory,
const std::vector<std::string>& compilerFlags,
const std::vector<FilePath>& systemHeaderSearchPaths,
const std::vector<FilePath>& frameworkSearchPaths,
const bool shouldApplyAnonymousTypedefTransformation
const std::vector<FilePath>& frameworkSearchPaths
)
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags, shouldApplyAnonymousTypedefTransformation)
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags)
, m_workingDirectory(workingDirectory)
{
}
@@ -27,8 +27,7 @@ public:
const FilePath& workingDirectory,
const std::vector<std::string>& compilerFlags,
const std::vector<FilePath>& systemHeaderSearchPaths,
const std::vector<FilePath>& frameworkSearchPaths,
const bool shouldApplyAnonymousTypedefTransformation);
const std::vector<FilePath>& frameworkSearchPaths);
virtual ~IndexerCommandCxxCdb();
@@ -12,10 +12,9 @@ IndexerCommandCxxManual::IndexerCommandCxxManual(
const std::string& languageStandard,
const std::vector<FilePath>& systemHeaderSearchPaths,
const std::vector<FilePath>& frameworkSearchPaths,
const std::vector<std::string>& compilerFlags,
const bool shouldApplyAnonymousTypedefTransformation
const std::vector<std::string>& compilerFlags
)
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags, shouldApplyAnonymousTypedefTransformation)
: IndexerCommandCxx(sourceFilePath, indexedPaths, excludedPaths, systemHeaderSearchPaths, frameworkSearchPaths, compilerFlags)
, m_languageStandard(languageStandard)
{
}
@@ -18,8 +18,7 @@ public:
const std::string& languageStandard,
const std::vector<FilePath>& systemHeaderSearchPaths,
const std::vector<FilePath>& frameworkSearchPaths,
const std::vector<std::string>& compilerFlags,
const bool shouldApplyAnonymousTypedefTransformation);
const std::vector<std::string>& compilerFlags);
virtual ~IndexerCommandCxxManual();
-6
View File
@@ -5,7 +5,6 @@
#include "data/indexer/Indexer.h"
#include "data/parser/ParserClientImpl.h"
#include "data/storage/StorageTransformationAnonymousTypedef.h"
#include "utility/file/FileRegister.h"
template <typename IndexerCommandType, typename ParserType>
@@ -55,11 +54,6 @@ std::shared_ptr<IntermediateStorage> IndexerCxx<IndexerCommandType, ParserType>:
return std::shared_ptr<IntermediateStorage>();
}
if (indexerCommand->shouldApplyAnonymousTypedefTransformation())
{
StorageTransformationAnonymousTypedef::transform(storage);
}
return storage;
}
@@ -194,7 +194,6 @@ void CxxAstVisitorComponentIndexer::visitTagDecl(clang::TagDecl* d)
symbolKind
);
}
}
}
@@ -441,7 +440,7 @@ void CxxAstVisitorComponentIndexer::visitTypedefDecl(clang::TypedefDecl* d)
{
m_client->recordSymbol(
getAstVisitor()->getDeclNameCache()->getValue(d),
SYMBOL_TYPEDEF,
d->getAnonDeclWithTypedefName() == NULL ? SYMBOL_TYPEDEF : utility::convertTagKind(d->getAnonDeclWithTypedefName()->getTagKind()),
getParseLocation(d->getLocation()),
utility::convertAccessSpecifier(d->getAccess()),
utility::isImplicit(d) ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT
@@ -455,7 +454,7 @@ void CxxAstVisitorComponentIndexer::visitTypeAliasDecl(clang::TypeAliasDecl* d)
{
m_client->recordSymbol(
getAstVisitor()->getDeclNameCache()->getValue(d),
SYMBOL_TYPEDEF,
d->getAnonDeclWithTypedefName() == NULL ? SYMBOL_TYPEDEF : utility::convertTagKind(d->getAnonDeclWithTypedefName()->getTagKind()),
getParseLocation(d->getLocation()),
utility::convertAccessSpecifier(d->getAccess()),
utility::isImplicit(d) ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT
@@ -171,6 +171,14 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
ScopedSwitcher<const clang::NamedDecl*> switcher(m_currentDecl, declaration);
std::string declNameString = declaration->getNameAsString();
if (const clang::TagDecl* tagDecl = clang::dyn_cast_or_null<clang::TagDecl>(declaration))
{
if (const clang::TypedefNameDecl* typedefNameDecl = tagDecl->getTypedefNameForAnonDecl())
{
declNameString = typedefNameDecl->getNameAsString();
}
}
if (const clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast_or_null<clang::TypeAliasDecl>(declaration))
{
clang::TypeAliasTemplateDecl* templatedDeclaration = typeAliasDecl->getDescribedAliasTemplate();
@@ -1,112 +0,0 @@
#include "data/storage/StorageTransformationAnonymousTypedef.h"
#include <map>
#include "data/graph/Node.h"
#include "data/name/NameDelimiterType.h"
#include "data/storage/IntermediateStorage.h"
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
void StorageTransformationAnonymousTypedef::transform(std::shared_ptr<IntermediateStorage> storage)
{
LOG_INFO("Applying storage transformation to rename anonymous types inside typedefs.");
if (!storage)
{
return;
}
std::vector<StorageNode> nodes = storage->getStorageNodes();
std::vector<StorageEdge> edges = storage->getStorageEdges();
std::vector<StorageOccurrence> occurrences = storage->getStorageOccurrences();
std::map<Id, Id> nodesToMerge;
std::map<std::string, std::string> nodesToRename;
{
std::map<Id, StorageNode> typedefNodes;
std::map<Id, StorageNode> anonymousTypeNodes;
for (const StorageNode& node : nodes)
{
const NodeType::Type nodeType = utility::intToType(node.type);
if (nodeType & NodeType::NODE_TYPEDEF)
{
typedefNodes.insert(std::pair<Id, StorageNode>(node.id, node));
}
else if(nodeType & (NodeType::NODE_STRUCT | NodeType::NODE_CLASS | NodeType::NODE_ENUM | NodeType::NODE_UNION))
{
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName);
if (nameHierarchy.back() && utility::isPrefix("anonymous ", nameHierarchy.back()->getName()))
{
anonymousTypeNodes.insert(std::pair<Id, StorageNode>(node.id, node));
}
}
}
for (const StorageEdge& edge : edges)
{
if (Edge::intToType(edge.type) & Edge::EDGE_TYPE_USAGE)
{
std::map<Id, StorageNode>::const_iterator itAnonymousTypeNodes = anonymousTypeNodes.find(edge.targetNodeId);
if (itAnonymousTypeNodes != anonymousTypeNodes.end())
{
std::map<Id, StorageNode>::const_iterator itTypedefNodes = typedefNodes.find(edge.sourceNodeId);
if (itTypedefNodes != typedefNodes.end())
{
nodesToMerge.insert(std::pair<Id, Id>(itTypedefNodes->first, itAnonymousTypeNodes->first));
nodesToRename.insert(std::pair<std::string, std::string>(itAnonymousTypeNodes->second.serializedName, itTypedefNodes->second.serializedName));
}
}
}
}
}
// remove typedef nodes that refer to anonymous types
// and rename anonymous types to typedef name
for (size_t i = 0; i < nodes.size(); i++)
{
if (nodesToMerge.find(nodes[i].id) != nodesToMerge.end())
{
nodes.erase(nodes.begin() + i);
i--;
}
else
{
for (std::map<std::string, std::string>::const_iterator it = nodesToRename.begin(); it != nodesToRename.end(); it++)
{
if (utility::isPrefix(it->first, nodes[i].serializedName))
{
nodes[i].serializedName = it->second + nodes[i].serializedName.substr(it->first.size());
}
}
}
}
// redirect edges that pointed to removed nodes
for (StorageEdge& edge : edges)
{
std::map<Id, Id>::const_iterator it = nodesToMerge.find(edge.targetNodeId);
if (it != nodesToMerge.end())
{
edge.targetNodeId = it->second;
}
}
// relink source locations of removed nodes
for (StorageOccurrence& occurrence : occurrences)
{
std::map<Id, Id>::const_iterator it = nodesToMerge.find(occurrence.elementId);
if (it != nodesToMerge.end())
{
occurrence.elementId = it->second;
}
}
storage->setStorageNodes(nodes);
storage->setStorageEdges(edges);
storage->setStorageOccurrences(occurrences);
LOG_INFO("Renamed " + std::to_string(nodesToRename.size()) + " types.");
}
@@ -1,14 +0,0 @@
#ifndef STORAGE_TRANSFORMATION_ANONYMOUS_TYPEDEF_H
#define STORAGE_TRANSFORMATION_ANONYMOUS_TYPEDEF_H
#include <memory>
class IntermediateStorage;
class StorageTransformationAnonymousTypedef
{
public:
static void transform(std::shared_ptr<IntermediateStorage> storage);
};
#endif // STORAGE_TRANSFORMATION_ANONYMOUS_TYPEDEF_H
+1 -2
View File
@@ -118,8 +118,7 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxCdb::getIndexerComman
FilePath(command.Directory),
currentCompilerFlags,
systemHeaderSearchPaths,
frameworkSearchPaths,
m_settings->getShouldApplyAnonymousTypedefTransformation()
frameworkSearchPaths
));
}
}
+1 -2
View File
@@ -65,8 +65,7 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCxxEmpty::getIndexerComm
m_settings->getStandard(),
systemHeaderSearchPaths,
frameworkSearchPaths,
compilerFlags,
m_settings->getShouldApplyAnonymousTypedefTransformation()
compilerFlags
));
}
}