From: Chris Lattner Date: Sun, 10 Jan 2010 00:24:58 +0000 (+0000) Subject: implement rdar://7520940: published framework headers should X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=804f65271953f358dc01bfcf74a93e8c93c5b2d6;p=clang implement rdar://7520940: published framework headers should import other headers within the same framework with the full framework path, not with a relative include. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93083 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index d8b5f2dad3..d79091a1f6 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -169,6 +169,9 @@ def err_pp_hash_error : Error<"#error%0">; def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; +def warn_pp_relative_include_from_framework : Warning< + "published framework headers should always #import headers within the " + "framework with framework paths">, InGroup>; def err_pp_empty_filename : Error<"empty filename">; def err_pp_include_too_deep : Error<"#include nested too deeply">; def err_pp_expects_filename : Error<"expected \"FILENAME\" or ">; diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index a73d829f9e..5669a63207 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -698,7 +698,8 @@ public: /// return null on failure. isAngled indicates whether the file reference is /// for system #include's or not (i.e. using <> instead of ""). const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd, - bool isAngled, const DirectoryLookup *FromDir, + SourceLocation FilenameTokLoc, bool isAngled, + const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir); /// GetCurLookup - The DirectoryLookup structure used to find the current diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 9e3d283d88..a719a541a3 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -406,6 +406,7 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() { /// for system #include's or not (i.e. using <> instead of ""). const FileEntry *Preprocessor::LookupFile(const char *FilenameStart, const char *FilenameEnd, + SourceLocation FilenameTokLoc, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir) { @@ -433,7 +434,16 @@ const FileEntry *Preprocessor::LookupFile(const char *FilenameStart, const FileEntry *FE = HeaderInfo.LookupFile(FilenameStart, FilenameEnd, isAngled, FromDir, CurDir, CurFileEnt); - if (FE) return FE; + if (FE) { + // Warn about normal quoted #include from framework headers. Since + // framework headers are published (both public and private ones) they + // should not do relative searches, they should do an include relative to + // their framework. + if (!isAngled && CurDir && FilenameTokLoc.isValid() && + CurDir->isFramework() && CurDir == CurDirLookup) + Diag(FilenameTokLoc, diag::warn_pp_relative_include_from_framework); + return FE; + } // Otherwise, see if this is a subframework header. If so, this is relative // to one of the headers on the #include stack. Walk the list of the current @@ -1080,13 +1090,14 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok, // Search include directories. const DirectoryLookup *CurDir; const FileEntry *File = LookupFile(FilenameStart, FilenameEnd, + FilenameTok.getLocation(), isAngled, LookupFrom, CurDir); if (File == 0) { Diag(FilenameTok, diag::err_pp_file_not_found) << std::string(FilenameStart, FilenameEnd); return; } - + // Ask HeaderInfo if we should enter this #include file. If not, #including // this file will have no effect. if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 80202ddb6d..1c8af8385b 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -561,7 +561,8 @@ static bool EvaluateHasIncludeCommon(bool &Result, Token &Tok, // Search include directories. const DirectoryLookup *CurDir; const FileEntry *File = PP.LookupFile(FilenameStart, FilenameEnd, - isAngled, LookupFrom, CurDir); + SourceLocation(),// produce no warnings. + isAngled, LookupFrom, CurDir); // Get the result value. Result = true means the file exists. Result = File != 0; diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 8b46f71691..74692faf42 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -302,6 +302,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) { // Search include directories for this file. const DirectoryLookup *CurDir; const FileEntry *File = LookupFile(FilenameStart, FilenameEnd, + FilenameTok.getLocation(), isAngled, 0, CurDir); if (File == 0) { Diag(FilenameTok, diag::err_pp_file_not_found) diff --git a/test/Preprocessor/foo.framework/Headers/bar.h b/test/Preprocessor/foo.framework/Headers/bar.h new file mode 100644 index 0000000000..574e851bb3 --- /dev/null +++ b/test/Preprocessor/foo.framework/Headers/bar.h @@ -0,0 +1,3 @@ + +int y; + diff --git a/test/Preprocessor/foo.framework/Headers/foo.h b/test/Preprocessor/foo.framework/Headers/foo.h new file mode 100644 index 0000000000..1b3f83492b --- /dev/null +++ b/test/Preprocessor/foo.framework/Headers/foo.h @@ -0,0 +1,4 @@ +#include "bar.h" + +int x; + diff --git a/test/Preprocessor/framework-include.m b/test/Preprocessor/framework-include.m new file mode 100644 index 0000000000..3de378ed18 --- /dev/null +++ b/test/Preprocessor/framework-include.m @@ -0,0 +1,5 @@ +// RUN: %clang -E -F%S %s 2>&1 | grep "Headers/foo.h:1:10: warning: published framework headers should always #import headers within the framework with framework paths" + +// rdar://7520940 +#include +