r198082 - Implement MSVC header search algorithm in MicrosoftMode.

Reid Kleckner rnk at google.com
Tue Jan 14 18:48:56 PST 2014


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 <will at indefiant.com> 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 at microsoft-header-search/a/findme.h:3 {{findme.h
> successfully included using MS search rules}}
> +// expected-warning at 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140114/d73cbb7e/attachment.html>


More information about the cfe-commits mailing list