From: Douglas Gregor Date: Wed, 30 Nov 2011 18:02:36 +0000 (+0000) Subject: Introduce an opt-in warning indicating when the compiler is treating X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3a8256a9c1f2f1037fcb844ed7666759124a852;p=clang Introduce an opt-in warning indicating when the compiler is treating an #include/#import as a module import. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145500 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 48b02d6ecf..fcdd88b7cd 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -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">; diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 0f9a8214c5..ccfa3216c1 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -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, DefaultIgnore; + } diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 140f793234..5047be3485 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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 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; diff --git a/test/Modules/Inputs/DependsOnModule.framework/Headers/DependsOnModule.h b/test/Modules/Inputs/DependsOnModule.framework/Headers/DependsOnModule.h index 411e97868c..8ce3520a3c 100644 --- a/test/Modules/Inputs/DependsOnModule.framework/Headers/DependsOnModule.h +++ b/test/Modules/Inputs/DependsOnModule.framework/Headers/DependsOnModule.h @@ -1,4 +1,4 @@ -#include +#include //expected-warning{{treating #include as an import of module 'Module'}} #define DEPENDS_ON_MODULE 1 #__private_macro__ DEPENDS_ON_MODULE diff --git a/test/Modules/auto-module-import.c b/test/Modules/auto-module-import.c index 1dda642593..a161f33efa 100644 --- a/test/Modules/auto-module-import.c +++ b/test/Modules/auto-module-import.c @@ -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 +#include // expected-warning{{treating #include as an import of module 'DependsOnModule'}} #ifdef MODULE_H_MACRO # error MODULE_H_MACRO should have been hidden