This is an archive of the discontinued LLVM Phabricator instance.

Private Headers for Modules
Needs ReviewPublic

Authored by crowl on May 20 2013, 5:42 PM.

Details

Reviewers
doug.gregor
Summary

This patch adds new private headers to the module map. Private
headers may be included from within the module, but not from outside
the module.

The patch does not provide any symbol export control, only inclusion
control. This capability enables a small step towards limiting
unintended use of a module/library.

Add a new declaration to module maps

private header "filename";

DOCUMENTATION

In docs/Modules.rst, document the declaration.

MODULE

Modify class Module to track private headers.

Add field PrivateHeaders to list the private headers.

Rename field Headers to NormalHeaders. Update uses to match.

Print private headers in Module::print.

MODULE MAP

Modify class ModuleMap to keep the role of the header as an enum
rather than a boolean.

Add enum ModuleHeaderRole describing the role of the header, normal,
private, and excluded.

To nested class KnownHeader, change bool Excluded to ModuleHeaderRole
Role.

Several functions that take or return a bool Excluded parameter, now
take a ModuleHeaderRole Role parameter. Several functions that did
not take a parameter, because they only dealt with normal headers,
now take an additional ModuleHeaderRole Role parameter.

Several that take that take or return Module* will instead take or
return KnownHeader, which provides access to the ModuleHeaderRole.

Add syntax for private headers. This syntax is the same as excluded
headers, but substituting the token "private" instead of "exclude".
Add MMToken::PrivateKeyword.

Change the parameters of parseHeaderDecl from two mutually exclusive
SourceLocations to a the leading token and the source location
of that token. Modify callers to match. Some checking need not
happen as a result. Infer the header role from the leading token.

HEADER SEARCH

Modify struct HeaderFileInfo to keep the role of the header.

Add field ModuleMap::ModuleHeaderRole HeaderRole : 2; constructed
with value ModuleMap::NormalHeader by default.

PREPROCESSOR

Modify In Preprocessor::LookupFile to check for inappropriate use
of private headers. This requires changing the parameter Module
**SuggestedModule to ModuleMap::KnownHeader *SuggestedModule.
To provide diagnostic line information, It also requires adding a
parameter SourceLocation FilenameLoc. Update callers to match.

FRONTEND ACTIONS

Make a note that private headers will not be top headers.

SERIALIZATION

Adjust serialization.

To enum SubmoduleRecordTypes add SUBMODULE_PRIVATE_HEADER = 13.

In ASTWriter::WriteSubmodules, add BitCodeAbbrev for
SUBMODULE_PRIVATE_HEADER. Emit PrivateHeaders names.

In ASTWriter.cpp'HeaderFileInfoTrait::EmitData, write HeaderRole
to flag byte. This addition uses both remaining bits in the byte.

In ASTReader.cpp'HeaderFileInfoTrait::ReadData: read HeaderRole
from flags; Pass HeaderRole to ModMap.addHeader.

In ASTReader.cpp'ASTReader::ReadSubmoduleBlock: Handle
SUBMODULE_PRIVATE_HEADER like the other headers.

TESTING

Add new module tests for private headers. These are pretty minimal.

Diff Detail

Event Timeline

klimek added inline comments.May 20 2013, 10:09 PM
lib/Lex/PPDirectives.cpp
573–582

This looks unintentionally left as a comment?

doug.gregor requested changes to this revision.Jun 7 2013, 3:48 PM

This is looking really good. Only minor change requests above.

lib/Lex/PPDirectives.cpp
573–582

If this is really that expensive, it can go behind ENABLE_EXPENSIVE_CHECKS, but we'd rather not have it commented out.

test/Modules/private1.cpp
9

Please merge these three tests into a single ".cpp" file, since there's a nontrivial cost to testing each individual file.

Also, please add an #include "private.h" with an expected-error to test the new diagnostic.

gribozavr added inline comments.Jun 7 2013, 8:31 PM
include/clang/Lex/HeaderSearch.h
61

IIRC, this should be unsigned because MSVC does not like bitfields with signed enum types.

include/clang/Lex/ModuleMap.h
205–207

The name and \returns documentation now don't quite reflect the actual return value.

crowl updated this revision to Unknown Object (????).Jun 12 2013, 12:44 PM

This diff addresses the previous comments and adds a new test case.

doug.gregor accepted this revision.Jun 19 2013, 10:26 AM

This LGTM now, thanks!

This revision now requires review to proceed.Oct 5 2016, 1:40 PM