This warning fires a handful of times in a clang self-host, and ultimately the problem is a false positive as described in http://llvm.org/bugs/show_bug.cgi?id=18481
On Fri, Dec 27, 2013 at 11:46 AM, Will Wilson <[email protected]> wrote: > Author: lantictac > Date: Fri Dec 27 13:46:16 2013 > New Revision: 198082 > > URL: http://llvm.org/viewvc/llvm-project?rev=198082&view=rev > Log: > Implement MSVC header search algorithm in MicrosoftMode. > Follows algorithm described here: > http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx > > Added: > cfe/trunk/test/Preprocessor/microsoft-header-search/ > cfe/trunk/test/Preprocessor/microsoft-header-search.c > cfe/trunk/test/Preprocessor/microsoft-header-search/a/ > cfe/trunk/test/Preprocessor/microsoft-header-search/a/b/ > cfe/trunk/test/Preprocessor/microsoft-header-search/a/b/include3.h > cfe/trunk/test/Preprocessor/microsoft-header-search/a/findme.h > cfe/trunk/test/Preprocessor/microsoft-header-search/a/include2.h > cfe/trunk/test/Preprocessor/microsoft-header-search/findme.h > cfe/trunk/test/Preprocessor/microsoft-header-search/include1.h > Modified: > cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td > cfe/trunk/include/clang/Lex/HeaderSearch.h > cfe/trunk/lib/Lex/HeaderSearch.cpp > cfe/trunk/lib/Lex/PPDirectives.cpp > cfe/trunk/lib/Rewrite/Frontend/InclusionRewriter.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=198082&r1=198081&r2=198082&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Dec 27 > 13:46:16 2013 > @@ -300,6 +300,9 @@ def ext_pp_import_directive : Extension< > InGroup<DiagGroup<"import-preprocessor-directive-pedantic">>; > def err_pp_import_directive_ms : Error< > "#import of type library is an unsupported Microsoft feature">; > +def ext_pp_include_search_ms : ExtWarn< > + "#include resolved using non-portable MSVC search rules as: %0">, > + InGroup<DiagGroup<"msvc-include">>; > > def ext_pp_ident_directive : Extension<"#ident is a language extension">; > def ext_pp_include_next_directive : Extension< > > Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=198082&r1=198081&r2=198082&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Lex/HeaderSearch.h (original) > +++ cfe/trunk/include/clang/Lex/HeaderSearch.h Fri Dec 27 13:46:16 2013 > @@ -158,6 +158,8 @@ class HeaderSearch { > /// \brief Header-search options used to initialize this header search. > IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts; > > + DiagnosticsEngine &Diags; > + SourceManager &SourceMgr; > FileManager &FileMgr; > /// \#include search path information. Requests for \#include "x" > search the > /// directory of the \#including file first, then each directory in > SearchDirs > @@ -349,13 +351,15 @@ public: > /// \returns If successful, this returns 'UsedDir', the DirectoryLookup > member > /// the file was found in, or null if not applicable. > /// > + /// \param IncludeLoc Used for diagnostics if valid. > + /// > /// \param isAngled indicates whether the file reference is a <> > reference. > /// > /// \param CurDir If non-null, the file was found in the specified > directory > /// search location. This is used to implement \#include_next. > /// > - /// \param CurFileEnt If non-null, indicates where the \#including file > is, in > - /// case a relative search is needed. > + /// \param Includers Indicates where the \#including file(s) are, in > case > + /// relative searches are needed. In reverse order of inclusion. > /// > /// \param SearchPath If non-null, will be set to the search path > relative > /// to which the file was found. If the include path is absolute, > SearchPath > @@ -368,10 +372,10 @@ public: > /// \param SuggestedModule If non-null, and the file found is > semantically > /// part of a known module, this will be set to the module that should > /// be imported instead of preprocessing/parsing the file found. > - const FileEntry *LookupFile(StringRef Filename, bool isAngled, > - const DirectoryLookup *FromDir, > + const FileEntry *LookupFile(StringRef Filename, SourceLocation > IncludeLoc, > + bool isAngled, const DirectoryLookup > *FromDir, > const DirectoryLookup *&CurDir, > - const FileEntry *CurFileEnt, > + ArrayRef<const FileEntry *> Includers, > SmallVectorImpl<char> *SearchPath, > SmallVectorImpl<char> *RelativePath, > ModuleMap::KnownHeader *SuggestedModule, > > Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=198082&r1=198081&r2=198082&view=diff > > ============================================================================== > --- cfe/trunk/lib/Lex/HeaderSearch.cpp (original) > +++ cfe/trunk/lib/Lex/HeaderSearch.cpp Fri Dec 27 13:46:16 2013 > @@ -12,12 +12,12 @@ > > > //===----------------------------------------------------------------------===// > > #include "clang/Lex/HeaderSearch.h" > -#include "clang/Basic/Diagnostic.h" > #include "clang/Basic/FileManager.h" > #include "clang/Basic/IdentifierTable.h" > #include "clang/Lex/HeaderMap.h" > #include "clang/Lex/HeaderSearchOptions.h" > #include "clang/Lex/Lexer.h" > +#include "clang/Lex/LexDiagnostic.h" > #include "llvm/ADT/SmallString.h" > #include "llvm/Support/Capacity.h" > #include "llvm/Support/FileSystem.h" > @@ -45,11 +45,11 @@ ExternalHeaderFileInfoSource::~ExternalH > > HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, > SourceManager &SourceMgr, DiagnosticsEngine > &Diags, > - const LangOptions &LangOpts, > + const LangOptions &LangOpts, > const TargetInfo *Target) > - : HSOpts(HSOpts), FileMgr(SourceMgr.getFileManager()), FrameworkMap(64), > - ModMap(SourceMgr, Diags, LangOpts, Target, *this) > -{ > + : HSOpts(HSOpts), Diags(Diags), SourceMgr(SourceMgr), > + FileMgr(SourceMgr.getFileManager()), FrameworkMap(64), > + ModMap(SourceMgr, Diags, LangOpts, Target, *this) { > AngledDirIdx = 0; > SystemDirIdx = 0; > NoCurDirSearch = false; > @@ -493,20 +493,15 @@ void HeaderSearch::setTarget(const Targe > > /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated > file, > /// return null on failure. isAngled indicates whether the file > reference is > -/// for system \#include's or not (i.e. using <> instead of ""). > CurFileEnt, if > -/// non-null, indicates where the \#including file is, in case a relative > search > -/// is needed. > +/// for system \#include's or not (i.e. using <> instead of ""). > Includers, if > +/// non-empty, indicates where the \#including file(s) are, in case a > relative > +/// search is needed. Microsoft mode will pass all \#including files. > const FileEntry *HeaderSearch::LookupFile( > - StringRef Filename, > - bool isAngled, > - const DirectoryLookup *FromDir, > - const DirectoryLookup *&CurDir, > - const FileEntry *CurFileEnt, > - SmallVectorImpl<char> *SearchPath, > + StringRef Filename, SourceLocation IncludeLoc, bool isAngled, > + const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, > + ArrayRef<const FileEntry *> Includers, SmallVectorImpl<char> > *SearchPath, > SmallVectorImpl<char> *RelativePath, > - ModuleMap::KnownHeader *SuggestedModule, > - bool SkipCache) > -{ > + ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) { > if (!HSOpts->ModuleMapFiles.empty()) { > // Preload all explicitly specified module map files. This enables > modules > // map files lying in a directory structure separate from the header > files > @@ -546,44 +541,53 @@ const FileEntry *HeaderSearch::LookupFil > } > > // Unless disabled, check to see if the file is in the #includer's > - // directory. This has to be based on CurFileEnt, not CurDir, because > - // CurFileEnt could be a #include of a subdirectory (#include > "foo/bar.h") and > - // a subsequent include of "baz.h" should resolve to > "whatever/foo/baz.h". > + // directory. This cannot be based on CurDir, because each includer > could be > + // a #include of a subdirectory (#include "foo/bar.h") and a subsequent > + // include of "baz.h" should resolve to "whatever/foo/baz.h". > // This search is not done for <> headers. > - if (CurFileEnt && !isAngled && !NoCurDirSearch) { > + if (!Includers.empty() && !isAngled && !NoCurDirSearch) { > SmallString<1024> TmpDir; > - // Concatenate the requested file onto the directory. > - // FIXME: Portability. Filename concatenation should be in sys::Path. > - TmpDir += CurFileEnt->getDir()->getName(); > - TmpDir.push_back('/'); > - TmpDir.append(Filename.begin(), Filename.end()); > - if (const FileEntry *FE = > FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { > - // Leave CurDir unset. > - // This file is a system header or C++ unfriendly if the old file > is. > - // > - // Note that we only use one of FromHFI/ToHFI at once, due to > potential > - // reallocation of the underlying vector potentially making the > first > - // reference binding dangling. > - HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt); > - unsigned DirInfo = FromHFI.DirInfo; > - bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; > - StringRef Framework = FromHFI.Framework; > - > - HeaderFileInfo &ToHFI = getFileInfo(FE); > - ToHFI.DirInfo = DirInfo; > - ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; > - ToHFI.Framework = Framework; > - > - if (SearchPath != NULL) { > - StringRef SearchPathRef(CurFileEnt->getDir()->getName()); > - SearchPath->clear(); > - SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); > - } > - if (RelativePath != NULL) { > - RelativePath->clear(); > - RelativePath->append(Filename.begin(), Filename.end()); > + for (ArrayRef<const FileEntry *>::iterator I(Includers.begin()), > + E(Includers.end()); > + I != E; ++I) { > + const FileEntry *Includer = *I; > + // Concatenate the requested file onto the directory. > + // FIXME: Portability. Filename concatenation should be in > sys::Path. > + TmpDir = Includer->getDir()->getName(); > + TmpDir.push_back('/'); > + TmpDir.append(Filename.begin(), Filename.end()); > + if (const FileEntry *FE = > + FileMgr.getFile(TmpDir.str(), /*openFile=*/true)) { > + // Leave CurDir unset. > + // This file is a system header or C++ unfriendly if the old file > is. > + // > + // Note that we only use one of FromHFI/ToHFI at once, due to > potential > + // reallocation of the underlying vector potentially making the > first > + // reference binding dangling. > + HeaderFileInfo &FromHFI = getFileInfo(Includer); > + unsigned DirInfo = FromHFI.DirInfo; > + bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; > + StringRef Framework = FromHFI.Framework; > + > + HeaderFileInfo &ToHFI = getFileInfo(FE); > + ToHFI.DirInfo = DirInfo; > + ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; > + ToHFI.Framework = Framework; > + > + if (SearchPath != NULL) { > + StringRef SearchPathRef(Includer->getDir()->getName()); > + SearchPath->clear(); > + SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); > + } > + if (RelativePath != NULL) { > + RelativePath->clear(); > + RelativePath->append(Filename.begin(), Filename.end()); > + } > + if (I != Includers.begin()) > + Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) > + << FE->getName(); > + return FE; > } > - return FE; > } > } > > @@ -667,18 +671,18 @@ const FileEntry *HeaderSearch::LookupFil > // a header in a framework that is currently being built, and we > couldn't > // resolve "foo.h" any other way, change the include to <Foo/foo.h>, > where > // "Foo" is the name of the framework in which the including header was > found. > - if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { > - HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); > + if (!Includers.empty() && !isAngled && > + Filename.find('/') == StringRef::npos) { > + HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front()); > if (IncludingHFI.IndexHeaderMapHeader) { > SmallString<128> ScratchFilename; > ScratchFilename += IncludingHFI.Framework; > ScratchFilename += '/'; > ScratchFilename += Filename; > - > - const FileEntry *Result = LookupFile(ScratchFilename, > /*isAngled=*/true, > - FromDir, CurDir, CurFileEnt, > - SearchPath, RelativePath, > - SuggestedModule); > + > + const FileEntry *Result = LookupFile( > + ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir, > + Includers.front(), SearchPath, RelativePath, SuggestedModule); > std::pair<unsigned, unsigned> &CacheLookup > = LookupFileCache.GetOrCreateValue(Filename).getValue(); > CacheLookup.second > > Modified: cfe/trunk/lib/Lex/PPDirectives.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=198082&r1=198081&r2=198082&view=diff > > ============================================================================== > --- cfe/trunk/lib/Lex/PPDirectives.cpp (original) > +++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Dec 27 13:46:16 2013 > @@ -560,12 +560,12 @@ const FileEntry *Preprocessor::LookupFil > SmallVectorImpl<char> *RelativePath, > ModuleMap::KnownHeader *SuggestedModule, > bool SkipCache) { > - // If the header lookup mechanism may be relative to the current file, > pass in > - // info about where the current file is. > - const FileEntry *CurFileEnt = 0; > + // If the header lookup mechanism may be relative to the current > inclusion > + // stack, record the parent #includes. > + SmallVector<const FileEntry *, 16> Includers; > if (!FromDir) { > FileID FID = getCurrentFileLexer()->getFileID(); > - CurFileEnt = SourceMgr.getFileEntryForID(FID); > + const FileEntry *FileEnt = SourceMgr.getFileEntryForID(FID); > > // If there is no file entry associated with this file, it must be the > // predefines buffer. Any other file is not lexed with a normal > lexer, so > @@ -573,17 +573,31 @@ const FileEntry *Preprocessor::LookupFil > // predefines buffer, resolve #include references (which come from the > // -include command line argument) as if they came from the main > file, this > // affects file lookup etc. > - if (CurFileEnt == 0) { > - FID = SourceMgr.getMainFileID(); > - CurFileEnt = SourceMgr.getFileEntryForID(FID); > + if (!FileEnt) > + FileEnt = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); > + > + if (FileEnt) > + Includers.push_back(FileEnt); > + > + // MSVC searches the current include stack from top to bottom for > + // headers included by quoted include directives. > + // See: http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx > + if (LangOpts.MicrosoftMode && !isAngled) { > + for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) { > + IncludeStackInfo &ISEntry = IncludeMacroStack[e - i - 1]; > + if (IsFileLexer(ISEntry)) > + if ((FileEnt = SourceMgr.getFileEntryForID( > + ISEntry.ThePPLexer->getFileID()))) > + Includers.push_back(FileEnt); > + } > } > } > > // Do a standard file entry lookup. > CurDir = CurDirLookup; > const FileEntry *FE = HeaderInfo.LookupFile( > - Filename, isAngled, FromDir, CurDir, CurFileEnt, > - SearchPath, RelativePath, SuggestedModule, SkipCache); > + Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, > SearchPath, > + RelativePath, SuggestedModule, SkipCache); > if (FE) { > if (SuggestedModule) > HeaderInfo.getModuleMap().diagnoseHeaderInclusion( > @@ -591,6 +605,7 @@ const FileEntry *Preprocessor::LookupFil > return FE; > } > > + const FileEntry *CurFileEnt; > // 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 > // headers on the #include stack and pass them to HeaderInfo. > > Modified: cfe/trunk/lib/Rewrite/Frontend/InclusionRewriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Frontend/InclusionRewriter.cpp?rev=198082&r1=198081&r2=198082&view=diff > > ============================================================================== > --- cfe/trunk/lib/Rewrite/Frontend/InclusionRewriter.cpp (original) > +++ cfe/trunk/lib/Rewrite/Frontend/InclusionRewriter.cpp Fri Dec 27 > 13:46:16 2013 > @@ -335,7 +335,7 @@ bool InclusionRewriter::HandleHasInclude > bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), > Filename); > const DirectoryLookup *CurDir; > const FileEntry *File = PP.getHeaderSearchInfo().LookupFile( > - Filename, isAngled, 0, CurDir, > + Filename, SourceLocation(), isAngled, 0, CurDir, > PP.getSourceManager().getFileEntryForID(FileId), 0, 0, 0, false); > > FileExists = File != 0; > > Added: cfe/trunk/test/Preprocessor/microsoft-header-search.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-header-search.c?rev=198082&view=auto > > ============================================================================== > --- cfe/trunk/test/Preprocessor/microsoft-header-search.c (added) > +++ cfe/trunk/test/Preprocessor/microsoft-header-search.c Fri Dec 27 > 13:46:16 2013 > @@ -0,0 +1,6 @@ > +// RUN: %clang_cc1 -I%S/microsoft-header-search %s -fms-compatibility > -verify > + > +// expected-warning@microsoft-header-search/a/findme.h:3 {{findme.h > successfully included using MS search rules}} > +// expected-warning@microsoft-header-search/a/b/include3.h:3 {{#include > resolved using non-portable MSVC search rules as}} > + > +#include "microsoft-header-search/include1.h" > \ No newline at end of file > > Added: cfe/trunk/test/Preprocessor/microsoft-header-search/a/b/include3.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-header-search/a/b/include3.h?rev=198082&view=auto > > ============================================================================== > --- cfe/trunk/test/Preprocessor/microsoft-header-search/a/b/include3.h > (added) > +++ cfe/trunk/test/Preprocessor/microsoft-header-search/a/b/include3.h Fri > Dec 27 13:46:16 2013 > @@ -0,0 +1,3 @@ > +#pragma once > + > +#include "findme.h" > \ No newline at end of file > > Added: cfe/trunk/test/Preprocessor/microsoft-header-search/a/findme.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-header-search/a/findme.h?rev=198082&view=auto > > ============================================================================== > --- cfe/trunk/test/Preprocessor/microsoft-header-search/a/findme.h (added) > +++ cfe/trunk/test/Preprocessor/microsoft-header-search/a/findme.h Fri Dec > 27 13:46:16 2013 > @@ -0,0 +1,3 @@ > +#pragma once > + > +#warning findme.h successfully included using MS search rules > \ No newline at end of file > > Added: cfe/trunk/test/Preprocessor/microsoft-header-search/a/include2.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-header-search/a/include2.h?rev=198082&view=auto > > ============================================================================== > --- cfe/trunk/test/Preprocessor/microsoft-header-search/a/include2.h > (added) > +++ cfe/trunk/test/Preprocessor/microsoft-header-search/a/include2.h Fri > Dec 27 13:46:16 2013 > @@ -0,0 +1,6 @@ > +#pragma once > + > +#include "b/include3.h" > +#pragma once > + > +#include "b/include3.h" > \ No newline at end of file > > Added: cfe/trunk/test/Preprocessor/microsoft-header-search/findme.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-header-search/findme.h?rev=198082&view=auto > > ============================================================================== > --- cfe/trunk/test/Preprocessor/microsoft-header-search/findme.h (added) > +++ cfe/trunk/test/Preprocessor/microsoft-header-search/findme.h Fri Dec > 27 13:46:16 2013 > @@ -0,0 +1,3 @@ > +#pragma once > + > +#error Wrong findme.h included, MSVC header search incorrect > \ No newline at end of file > > Added: cfe/trunk/test/Preprocessor/microsoft-header-search/include1.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/microsoft-header-search/include1.h?rev=198082&view=auto > > ============================================================================== > --- cfe/trunk/test/Preprocessor/microsoft-header-search/include1.h (added) > +++ cfe/trunk/test/Preprocessor/microsoft-header-search/include1.h Fri Dec > 27 13:46:16 2013 > @@ -0,0 +1,6 @@ > +#pragma once > + > +#include "a/include2.h" > +#pragma once > + > +#include "a/include2.h" > \ No newline at end of file > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
