Added -block-check-header-list-only option. This is a work-around for private includes that purposefully get included inside blocks.

llvm-svn: 228846
This commit is contained in:
John Thompson 2015-02-11 16:58:36 +00:00
parent 9724431c77
commit ecd3b04cd7
5 changed files with 61 additions and 7 deletions

View File

@ -49,3 +49,10 @@ Modularize Command Line Options
Put modules generated by the -module-map-path option in an enclosing Put modules generated by the -module-map-path option in an enclosing
module with the given name. See the description in :ref:`module-map-generation`. module with the given name. See the description in :ref:`module-map-generation`.
.. option:: -block-check-header-list-only
Limit the #include-inside-extern-or-namespace-block
check to only those headers explicitly listed in the header list.
This is a work-around for avoiding error messages for private includes that
purposefully get included inside blocks.

View File

@ -209,6 +209,15 @@ cl::opt<std::string>
RootModule("root-module", cl::init(""), RootModule("root-module", cl::init(""),
cl::desc("Specify the name of the root module.")); cl::desc("Specify the name of the root module."));
// Option for limiting the #include-inside-extern-or-namespace-block
// check to only those headers explicitly listed in the header list.
// This is a work-around for private includes that purposefully get
// included inside blocks.
static cl::opt<bool>
BlockCheckHeaderListOnly("block-check-header-list-only", cl::init(false),
cl::desc("Only warn if #include directives are inside extern or namespace"
" blocks if the included header is in the header list."));
// Save the program name for error messages. // Save the program name for error messages.
const char *Argv0; const char *Argv0;
// Save the command line for comments. // Save the command line for comments.
@ -722,7 +731,8 @@ int main(int Argc, const char **Argv) {
new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments)); new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments));
// Create preprocessor tracker, to watch for macro and conditional problems. // Create preprocessor tracker, to watch for macro and conditional problems.
std::unique_ptr<PreprocessorTracker> PPTracker(PreprocessorTracker::create()); std::unique_ptr<PreprocessorTracker> PPTracker(
PreprocessorTracker::create(Headers, BlockCheckHeaderListOnly));
// Parse all of the headers, detecting duplicates. // Parse all of the headers, detecting duplicates.
EntityMap Entities; EntityMap Entities;

View File

@ -866,9 +866,19 @@ ConditionalExpansionMapIter;
// course of running modularize. // course of running modularize.
class PreprocessorTrackerImpl : public PreprocessorTracker { class PreprocessorTrackerImpl : public PreprocessorTracker {
public: public:
PreprocessorTrackerImpl() PreprocessorTrackerImpl(llvm::SmallVector<std::string, 32> &Headers,
: CurrentInclusionPathHandle(InclusionPathHandleInvalid), bool DoBlockCheckHeaderListOnly)
InNestedHeader(false) {} : BlockCheckHeaderListOnly(DoBlockCheckHeaderListOnly),
CurrentInclusionPathHandle(InclusionPathHandleInvalid),
InNestedHeader(false) {
// Use canonical header path representation.
for (llvm::ArrayRef<std::string>::iterator I = Headers.begin(),
E = Headers.end();
I != E; ++I) {
HeaderList.push_back(getCanonicalPath(*I));
}
}
~PreprocessorTrackerImpl() {} ~PreprocessorTrackerImpl() {}
// Handle entering a preprocessing session. // Handle entering a preprocessing session.
@ -889,6 +899,10 @@ public:
// "namespace {}" blocks containing #include directives. // "namespace {}" blocks containing #include directives.
void handleIncludeDirective(llvm::StringRef DirectivePath, int DirectiveLine, void handleIncludeDirective(llvm::StringRef DirectivePath, int DirectiveLine,
int DirectiveColumn, llvm::StringRef TargetPath) { int DirectiveColumn, llvm::StringRef TargetPath) {
// If it's not a header in the header list, ignore it with respect to
// the check.
if (BlockCheckHeaderListOnly && !isHeaderListHeader(DirectivePath))
return;
HeaderHandle CurrentHeaderHandle = findHeaderHandle(DirectivePath); HeaderHandle CurrentHeaderHandle = findHeaderHandle(DirectivePath);
StringHandle IncludeHeaderHandle = addString(TargetPath); StringHandle IncludeHeaderHandle = addString(TargetPath);
for (std::vector<PPItemKey>::const_iterator I = IncludeDirectives.begin(), for (std::vector<PPItemKey>::const_iterator I = IncludeDirectives.begin(),
@ -959,6 +973,7 @@ public:
if (!InNestedHeader) if (!InNestedHeader)
InNestedHeader = !HeadersInThisCompile.insert(H).second; InNestedHeader = !HeadersInThisCompile.insert(H).second;
} }
// Handle exiting a header source file. // Handle exiting a header source file.
void handleHeaderExit(llvm::StringRef HeaderPath) { void handleHeaderExit(llvm::StringRef HeaderPath) {
// Ignore <built-in> and <command-line> to reduce message clutter. // Ignore <built-in> and <command-line> to reduce message clutter.
@ -982,6 +997,18 @@ public:
return CanonicalPath; return CanonicalPath;
} }
// Return true if the given header is in the header list.
bool isHeaderListHeader(llvm::StringRef HeaderPath) const {
std::string CanonicalPath = getCanonicalPath(HeaderPath);
for (llvm::ArrayRef<std::string>::iterator I = HeaderList.begin(),
E = HeaderList.end();
I != E; ++I) {
if (*I == CanonicalPath)
return true;
}
return false;
}
// Get the handle of a header file entry. // Get the handle of a header file entry.
// Return HeaderHandleInvalid if not found. // Return HeaderHandleInvalid if not found.
HeaderHandle findHeaderHandle(llvm::StringRef HeaderPath) const { HeaderHandle findHeaderHandle(llvm::StringRef HeaderPath) const {
@ -1301,6 +1328,9 @@ public:
} }
private: private:
llvm::SmallVector<std::string, 32> HeaderList;
// Only do extern, namespace check for headers in HeaderList.
bool BlockCheckHeaderListOnly;
llvm::StringPool Strings; llvm::StringPool Strings;
std::vector<StringHandle> HeaderPaths; std::vector<StringHandle> HeaderPaths;
std::vector<HeaderHandle> HeaderStack; std::vector<HeaderHandle> HeaderStack;
@ -1319,8 +1349,10 @@ private:
PreprocessorTracker::~PreprocessorTracker() {} PreprocessorTracker::~PreprocessorTracker() {}
// Create instance of PreprocessorTracker. // Create instance of PreprocessorTracker.
PreprocessorTracker *PreprocessorTracker::create() { PreprocessorTracker *PreprocessorTracker::create(
return new PreprocessorTrackerImpl(); llvm::SmallVector<std::string, 32> &Headers,
bool DoBlockCheckHeaderListOnly) {
return new PreprocessorTrackerImpl(Headers, DoBlockCheckHeaderListOnly);
} }
// Preprocessor callbacks for modularize. // Preprocessor callbacks for modularize.

View File

@ -77,7 +77,9 @@ public:
virtual bool reportInconsistentConditionals(llvm::raw_ostream &OS) = 0; virtual bool reportInconsistentConditionals(llvm::raw_ostream &OS) = 0;
// Create instance of PreprocessorTracker. // Create instance of PreprocessorTracker.
static PreprocessorTracker *create(); static PreprocessorTracker *create(
llvm::SmallVector<std::string, 32> &Headers,
bool DoBlockCheckHeaderListOnly);
}; };
} // end namespace Modularize } // end namespace Modularize

View File

@ -0,0 +1,3 @@
# RUN: modularize -block-check-header-list-only
Inputs/IncludeInNamespace.h