Introduce an opt-in warning indicating when the compiler is treating

an #include/#import as a module import.

llvm-svn: 145500
This commit is contained in:
Douglas Gregor 2011-11-30 18:02:36 +00:00
parent 0a1801015c
commit 41e115a81a
5 changed files with 50 additions and 3 deletions

View File

@ -25,6 +25,7 @@ def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
def Availability : DiagGroup<"availability">;
def AutoImport : DiagGroup<"auto-import">;
def BoolConversions : DiagGroup<"bool-conversions">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
def CXXCompat: DiagGroup<"c++-compat">;

View File

@ -400,4 +400,8 @@ def err_mmap_umbrella_header_submodule : Error<
def err_mmap_umbrella_clash : Error<
"umbrella header for module '%0' already covers this directory">;
def warn_auto_module_import : Warning<
"treating #%select{include|import|include_next|__include_macros}0 as an "
"import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
}

View File

@ -22,6 +22,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/APInt.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@ -1208,6 +1209,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
llvm::SmallString<128> FilenameBuffer;
StringRef Filename;
SourceLocation End;
SourceLocation CharEnd; // the end of this directive, in characters
switch (FilenameTok.getKind()) {
case tok::eod:
@ -1218,6 +1220,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
case tok::string_literal:
Filename = getSpelling(FilenameTok, FilenameBuffer);
End = FilenameTok.getLocation();
CharEnd = End.getLocWithOffset(Filename.size());
break;
case tok::less:
@ -1227,6 +1230,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
if (ConcatenateIncludeName(FilenameBuffer, End))
return; // Found <eod> but no ">"? Diagnostic already emitted.
Filename = FilenameBuffer.str();
CharEnd = getLocForEndOfToken(End);
break;
default:
Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
@ -1288,6 +1292,44 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FilenameTok.getLocation()));
std::reverse(Path.begin(), Path.end());
// Warn that we're replacing the include/import with a module import.
llvm::SmallString<128> PathString;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
if (I)
PathString += '.';
PathString += Path[I].first->getName();
}
int IncludeKind = 0;
switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
case tok::pp_include:
IncludeKind = 0;
break;
case tok::pp_import:
IncludeKind = 1;
break;
case tok::pp_include_next:
IncludeKind = 2;
break;
case tok::pp___include_macros:
IncludeKind = 3;
break;
default:
llvm_unreachable("unknown include directive kind");
break;
}
CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd),
/*IsTokenRange=*/false);
Diag(HashLoc, diag::warn_auto_module_import)
<< IncludeKind << PathString
<< FixItHint::CreateReplacement(ReplaceRange,
"__import_module__ " + PathString.str().str() + ";");
// Load the module.
TheModuleLoader.loadModule(IncludeTok.getLocation(), Path);
return;

View File

@ -1,4 +1,4 @@
#include <Module/Module.h>
#include <Module/Module.h> //expected-warning{{treating #include as an import of module 'Module'}}
#define DEPENDS_ON_MODULE 1
#__private_macro__ DEPENDS_ON_MODULE

View File

@ -1,8 +1,8 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fauto-module-import -F %S/Inputs %s -verify
// RUN: %clang_cc1 -x objective-c -Wauto-import -fmodule-cache-path %t -fauto-module-import -F %S/Inputs %s -verify
#include <DependsOnModule/DependsOnModule.h>
#include <DependsOnModule/DependsOnModule.h> // expected-warning{{treating #include as an import of module 'DependsOnModule'}}
#ifdef MODULE_H_MACRO
# error MODULE_H_MACRO should have been hidden