Skip to content

Commit

Permalink
add protected header; cache other cppLibraries as well
Browse files Browse the repository at this point in the history
  • Loading branch information
ggeorgiev committed May 28, 2016
1 parent 5511a32 commit 29a6af6
Show file tree
Hide file tree
Showing 20 changed files with 292 additions and 81 deletions.
6 changes: 6 additions & 0 deletions src/3rdparty/axe.dbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ cxx_library /axe
@directory=../../axe/include:

axe.h
;

cxx_header
@visibility=protected
@directory=../../axe/include:

axe_composite.h
axe_composite_function.h
axe_exception.h
Expand Down
3 changes: 3 additions & 0 deletions src/doim/cxx/cxx_header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ std::ostream& operator<<(std::ostream& out, const CxxHeader& header)
case CxxHeader::EVisibility::kPublic:
out << "public";
break;
case CxxHeader::EVisibility::kProtected:
out << "protected";
break;
case CxxHeader::EVisibility::kPrivate:
out << "private";
break;
Expand Down
7 changes: 7 additions & 0 deletions src/doim/cxx/cxx_header.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ struct CxxHeaderEnums
};
enum class EVisibility
{
// Header file that is visible to the library and all libraries that depend on it.
kPublic,

// Header that is visible to the library files and public headers, but not to the
// dependent libraries.
kProtected,

// Header that is visible only to the library files.
kPrivate,
};
};
Expand Down
81 changes: 76 additions & 5 deletions src/doim/cxx/cxx_include_directory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,14 @@ ECode CxxIncludeDirectory::findHeader(

ECode CxxIncludeDirectory::findHeader(
const FsFileSPtr& header,
const doim::CxxIncludeDirectorySPtr& currentIncludeDirectory,
const doim::CxxIncludeDirectorySetSPtr& includeDirectories,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo)
{
CxxHeaderInfo result;

if (currentIncludeDirectory != nullptr)
{
result = {currentIncludeDirectory->findHeader(header), currentIncludeDirectory};
}

for (const auto& directory : *includeDirectories)
{
Expand All @@ -82,6 +80,79 @@ ECode CxxIncludeDirectory::findHeader(
EHEnd;
}

template <typename H>
ECode findHeaderDeepTemplate(const H& header,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxIncludeDirectory::CxxHeaderInfo& headerInfo)
{
CxxIncludeDirectorySet checked;
CxxIncludeDirectorySet todo;
if (currentIncludeDirectory != nullptr)
todo.insert(currentIncludeDirectory);
todo.insert(includeDirectories->begin(), includeDirectories->end());

CxxIncludeDirectory::CxxHeaderInfo result;
while (!todo.empty())
{
auto current = *todo.begin();
todo.erase(todo.begin());
checked.insert(current);

for (const auto cxxHeader : *current->headerFiles())
{
for (auto includeDir : *cxxHeader->cxxIncludeDirectories())
{
if (checked.count(includeDir) == 0)
todo.insert(includeDir);
}
}

auto cxxHeader = current->findHeader(header);
if (cxxHeader == nullptr)
continue;

if (result.mHeader != nullptr)
EHBan(kTooMany);

DLOG("Deep found header {} in directory {}",
cxxHeader->file()->path(),
current->directory()->path());

result = {cxxHeader, current};
}

if (result.mHeader == nullptr)
EHBan(kNotFound);

headerInfo = result;
EHEnd;
}

ECode CxxIncludeDirectory::findHeaderDeep(
const string_view& header,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo)
{
return findHeaderDeepTemplate(header,
currentIncludeDirectory,
includeDirectories,
headerInfo);
}

ECode CxxIncludeDirectory::findHeaderDeep(
const FsFileSPtr& header,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo)
{
return findHeaderDeepTemplate(header,
currentIncludeDirectory,
includeDirectories,
headerInfo);
}

CxxIncludeDirectory::CxxIncludeDirectory(const EType type,
const FsDirectorySPtr& directory,
const CxxHeaderSetSPtr& headerFiles)
Expand All @@ -103,7 +174,7 @@ void CxxIncludeDirectory::finally()

CxxHeaderSPtr CxxIncludeDirectory::findHeader(const string_view& header) const
{
const auto& file = doim::FsFile::find(directory(), header);
const auto& file = FsFile::find(directory(), header);
if (file == nullptr)
return nullptr;

Expand Down
29 changes: 23 additions & 6 deletions src/doim/cxx/cxx_include_directory.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,37 @@ class CxxIncludeDirectory : public CxxIncludeDirectoryEnums,
public:
struct CxxHeaderInfo
{
doim::CxxHeaderSPtr mHeader;
doim::CxxIncludeDirectorySPtr mIncludeDirectory;
CxxHeaderSPtr mHeader;
CxxIncludeDirectorySPtr mIncludeDirectory;
};

// Searches for a header with a string presentation in one current directory and a set
// of directories. The reason for the extra directory is that a header does not keep
// track of the directory it belongs too, but yet it might include header from it.
static ECode findHeader(const string_view& header,
const doim::CxxIncludeDirectorySPtr& currentIncludeDirectory,
const doim::CxxIncludeDirectorySetSPtr& includeDirectories,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo);

static ECode findHeader(const FsFileSPtr& header,
const doim::CxxIncludeDirectorySPtr& currentIncludeDirectory,
const doim::CxxIncludeDirectorySetSPtr& includeDirectories,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo);

// Searches deep for a header. Not all include directories that a particular file
// can see, are propagated up. For example a public header can see protected header,
// but a file that depends on it will not. Deep search goes recursively to track the
// header.
static ECode findHeaderDeep(const string_view& header,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo);

static ECode findHeaderDeep(const FsFileSPtr& header,
const CxxIncludeDirectorySPtr& currentIncludeDirectory,
const CxxIncludeDirectorySetSPtr& includeDirectories,
CxxHeaderInfo& headerInfo);

CxxIncludeDirectory(const EType type,
const FsDirectorySPtr& directory,
const CxxHeaderSetSPtr& headerFiles);
Expand Down
121 changes: 101 additions & 20 deletions src/dom/cxx/cxx_library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ doim::AttributeNameSPtr CxxLibrary::gVisibility =
doim::AttributeName::global("visibility", CxxLibrary::gVisibility);
doim::AttributeValueSPtr CxxLibrary::gPublic =
doim::AttributeValue::global("public", CxxLibrary::gPublic);
doim::AttributeValueSPtr CxxLibrary::gProtected =
doim::AttributeValue::global("protected", CxxLibrary::gProtected);
doim::AttributeValueSPtr CxxLibrary::gPrivate =
doim::AttributeValue::global("private", CxxLibrary::gPrivate);

CxxLibrary::CxxLibrary()
: mType(EType::kUser)
, mIndirectPublicCxxIncludeDirectoriesMemoization(
std::make_shared<RecursiveCxxIncludeDirectoriesMemoization>())
, mRecursivePublicCxxIncludeDirectoriesMemoization(
std::make_shared<RecursiveCxxIncludeDirectoriesMemoization>())
, mVisibleCxxIncludeDirectoriesMemoization(
std::make_shared<RecursiveCxxIncludeDirectoriesMemoization>())
{
resetRecursiveCxxIncludeDirectoriesMemoization();
resetCxxIncludeDirectoriesMemoization();
}

ECode CxxLibrary::updateAttribute(const doim::AttributeSPtr& attribute)
Expand Down Expand Up @@ -71,7 +77,7 @@ ECode CxxLibrary::updateBinary(const doim::FsFileSPtr& binary)

ECode CxxLibrary::updateCxxLibraries(CxxLibrarySet& libraries)
{
resetRecursiveCxxIncludeDirectoriesMemoization();
resetCxxIncludeDirectoriesMemoization();

mCxxLibraries.swap(libraries);
EHEnd;
Expand Down Expand Up @@ -127,6 +133,19 @@ doim::CxxIncludeDirectorySPtr CxxLibrary::cxxPublicIncludeDirectory(
publicCxxHeaders(root));
}

doim::CxxIncludeDirectorySPtr CxxLibrary::cxxProtectedIncludeDirectory(
const doim::FsDirectorySPtr& root) const
{
auto directory = headersDirectory(doim::CxxHeader::EVisibility::kProtected);

if (directory == nullptr)
return nullptr;

return doim::CxxIncludeDirectory::unique(cxxIncludeDirectoryType(),
directory,
protectedCxxHeaders(root));
}

doim::CxxIncludeDirectorySetSPtr CxxLibrary::indirectPublicCxxIncludeDirectories(
const doim::FsDirectorySPtr& root) const
{
Expand All @@ -145,39 +164,71 @@ doim::CxxIncludeDirectorySetSPtr CxxLibrary::indirectPublicCxxIncludeDirectories
return doim::CxxIncludeDirectorySet::unique(directories);
};

return mIndirectPublicCxxIncludeDirectoriesMemoization->get(mMemoizationHandle,
root,
fn);
return mIndirectPublicCxxIncludeDirectoriesMemoization->get(
mCxxIncludeDirectoriesMemoizationHandle, root, fn);
}

doim::CxxIncludeDirectorySetSPtr CxxLibrary::recursivePublicCxxIncludeDirectories(
doim::CxxIncludeDirectorySetSPtr CxxLibrary::recursiveProtectedCxxIncludeDirectories(
const doim::FsDirectorySPtr& root) const
{
auto directories = doim::CxxIncludeDirectorySet::make();

const auto& publicDirectory = cxxPublicIncludeDirectory(root);
if (publicDirectory != nullptr)
directories->insert(publicDirectory);
const auto& protectedDirectory = cxxProtectedIncludeDirectory(root);
if (protectedDirectory != nullptr)
directories->insert(protectedDirectory);

const auto& libDirectories = indirectPublicCxxIncludeDirectories(root);
directories->insert(libDirectories->begin(), libDirectories->end());

return doim::CxxIncludeDirectorySet::unique(directories);
}

doim::CxxIncludeDirectorySetSPtr CxxLibrary::recursivePublicCxxIncludeDirectories(
const doim::FsDirectorySPtr& root) const
{
auto fn = [this](doim::FsDirectorySPtr root,
std::vector<dp::Handle::ControllerSPtr>& dependencies) {

auto directories = doim::CxxIncludeDirectorySet::make();

const auto& publicDirectory = cxxPublicIncludeDirectory(root);
if (publicDirectory != nullptr)
directories->insert(publicDirectory);

const auto& libDirectories = indirectPublicCxxIncludeDirectories(root);
directories->insert(libDirectories->begin(), libDirectories->end());

return doim::CxxIncludeDirectorySet::unique(directories);
};

return mRecursivePublicCxxIncludeDirectoriesMemoization->get(
mCxxIncludeDirectoriesMemoizationHandle, root, fn);
}

doim::CxxIncludeDirectorySetSPtr CxxLibrary::visibleCxxIncludeDirectories(
const doim::FsDirectorySPtr& root) const
{
auto directories = doim::CxxIncludeDirectorySet::make();
auto fn = [this](doim::FsDirectorySPtr root,
std::vector<dp::Handle::ControllerSPtr>& dependencies) {

const auto& privateDirectory = cxxPrivateIncludeDirectory(root);
if (privateDirectory != nullptr)
directories->insert(privateDirectory);
auto directories = doim::CxxIncludeDirectorySet::make();

const auto& libDirectories = recursivePublicCxxIncludeDirectories(root);
directories->insert(libDirectories->begin(), libDirectories->end());
const auto& privateDirectory = cxxPrivateIncludeDirectory(root);
if (privateDirectory != nullptr)
directories->insert(privateDirectory);

return doim::CxxIncludeDirectorySet::unique(directories);
const auto& protectedDirectory = cxxProtectedIncludeDirectory(root);
if (protectedDirectory != nullptr)
directories->insert(protectedDirectory);

const auto& libDirectories = recursivePublicCxxIncludeDirectories(root);
directories->insert(libDirectories->begin(), libDirectories->end());

return doim::CxxIncludeDirectorySet::unique(directories);
};

return mVisibleCxxIncludeDirectoriesMemoization->get(
mCxxIncludeDirectoriesMemoizationHandle, root, fn);
}

doim::CxxHeaderSetSPtr CxxLibrary::publicCxxHeaders(
Expand All @@ -191,7 +242,7 @@ doim::CxxHeaderSetSPtr CxxLibrary::publicCxxHeaders(
return doim::CxxHeaderSet::unique(headers);

auto type = cxxHeaderType();
const auto& directories = indirectPublicCxxIncludeDirectories(root);
const auto& directories = recursiveProtectedCxxIncludeDirectories(root);
for (const auto& header : *files)
{
auto cxxHeader = doim::CxxHeader::unique(type,
Expand All @@ -203,6 +254,29 @@ doim::CxxHeaderSetSPtr CxxLibrary::publicCxxHeaders(
return doim::CxxHeaderSet::unique(headers);
}

doim::CxxHeaderSetSPtr CxxLibrary::protectedCxxHeaders(
const doim::FsDirectorySPtr& root) const
{
auto headers = doim::CxxHeaderSet::make();

const auto files = headerFiles(doim::CxxHeader::EVisibility::kProtected);

if (files == nullptr)
return doim::CxxHeaderSet::unique(headers);

auto type = cxxHeaderType();
const auto& directories = indirectPublicCxxIncludeDirectories(root);
for (const auto& header : *files)
{
auto cxxHeader = doim::CxxHeader::unique(type,
doim::CxxHeader::EVisibility::kProtected,
header,
directories);
headers->insert(cxxHeader);
}
return doim::CxxHeaderSet::unique(headers);
}

doim::CxxHeaderSetSPtr CxxLibrary::recursivePublicCxxHeaders(
const doim::FsDirectorySPtr& root) const
{
Expand All @@ -220,9 +294,16 @@ doim::CxxHeaderSetSPtr CxxLibrary::recursivePublicCxxHeaders(
return doim::CxxHeaderSet::unique(headers);
}

void CxxLibrary::resetRecursiveCxxIncludeDirectoriesMemoization()
void CxxLibrary::resetCxxIncludeDirectoriesMemoization()
{
auto memorization = mIndirectPublicCxxIncludeDirectoriesMemoization;
mMemoizationHandle = dp::Handle::create([memorization] { memorization->clear(); });
auto indirect = mIndirectPublicCxxIncludeDirectoriesMemoization;
auto recursive = mRecursivePublicCxxIncludeDirectoriesMemoization;
auto visible = mVisibleCxxIncludeDirectoriesMemoization;
mCxxIncludeDirectoriesMemoizationHandle =
dp::Handle::create([indirect, recursive, visible] {
indirect->clear();
recursive->clear();
visible->clear();
});
}
}
Loading

0 comments on commit 29a6af6

Please sign in to comment.