<div dir="ltr">On Mon, Dec 2, 2013 at 5:58 PM, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">looks like this found a real issue with OS X 10.9's headers.</blockquote><div><br></div><div>I agree that this looks like a bug in the headers; it looks like sys/_types/_wchar_t.h should probably not be specified as a separate submodule, since including it in an 'extern "C" {' suggests that it's just a fragment of text rather than an actual submodule.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Should we just xfail the test?</blockquote><div><br></div><div>That fixes the test, but does nothing for people who are using Clang SVN on Mac OS with older (incompatible) modules. We need to figure out how to handle that case. Maybe we should include a version number in module.map files, and ignore module.maps that don't specify the right version?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Including a system header (<stdint.h>) in a<br>
clang test seems like a bad idea, no?</blockquote><div><br></div><div>Well... the point of this test is to ensure that we do the right thing when our own <stdint.h> #include_next's the system one. We should probably change the test to get that effect a different way (for instance, by providing a fake sysroot with a fake <stdint.h>).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I am getting:<br>
<br>
Command Output (stderr):<br>
<br>
--<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:10:<br>
<br>
/usr/include/inttypes.h:252:1: error: expected '}'<br>
<br>
#include <sys/_types/_wchar_t.h><br>
<br>
^<br>
<br>
/usr/include/inttypes.h:235:1: note: to match this '{'<br>
<br>
__BEGIN_DECLS<br>
<br>
^<br>
<br>
/usr/include/sys/cdefs.h:71:34: note: expanded from macro '__BEGIN_DECLS'<br>
<br>
#define __BEGIN_DECLS   extern "C" {<br>
<br>
                                   ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:10:<br>
<br>
/usr/include/inttypes.h:263:1: error: extraneous closing brace ('}')<br>
<br>
__END_DECLS<br>
<br>
^<br>
<br>
/usr/include/sys/cdefs.h:72:21: note: expanded from macro '__END_DECLS'<br>
<br>
#define __END_DECLS     }<br>
<br>
                        ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:25:<br>
<br>
/usr/include/stdlib.h:238:1: error: expected '}'<br>
<br>
#include <machine/types.h><br>
<br>
^<br>
<br>
/usr/include/stdlib.h:127:1: note: to match this '{'<br>
<br>
__BEGIN_DECLS<br>
<br>
^<br>
<br>
/usr/include/sys/cdefs.h:71:34: note: expanded from macro '__BEGIN_DECLS'<br>
<br>
#define __BEGIN_DECLS   extern "C" {<br>
<br>
                                   ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:25:<br>
<br>
/usr/include/stdlib.h:323:1: error: extraneous closing brace ('}')<br>
<br>
__END_DECLS<br>
<br>
^<br>
<br>
/usr/include/sys/cdefs.h:72:21: note: expanded from macro '__END_DECLS'<br>
<br>
#define __END_DECLS     }<br>
<br>
                        ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:49:<br>
<br>
/usr/include/iconv.h:80:1: error: expected '}'<br>
<br>
#include <sys/_types/_wchar_t.h><br>
<br>
^<br>
<br>
/usr/include/iconv.h:56:12: note: to match this '{'<br>
<br>
extern "C" {<br>
<br>
           ^<br>
<br>
/usr/include/iconv.h:185:1: error: extraneous closing brace ('}')<br>
<br>
}<br>
<br>
^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:56:<br>
<br>
In file included from /usr/include/net/if.h:106:<br>
<br>
In file included from /usr/include/net/if_var.h:70:<br>
<br>
/usr/include/sys/time.h:193:1: error: expected '}'<br>
<br>
#include <sys/_select.h>        /* select() prototype */<br>
<br>
^<br>
<br>
/usr/include/sys/time.h:181:1: note: to match this '{'<br>
<br>
__BEGIN_DECLS<br>
<br>
^<br>
<br>
/usr/include/sys/cdefs.h:71:34: note: expanded from macro '__BEGIN_DECLS'<br>
<br>
#define __BEGIN_DECLS   extern "C" {<br>
<br>
                                   ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:56:<br>
<br>
In file included from /usr/include/net/if.h:106:<br>
<br>
In file included from /usr/include/net/if_var.h:70:<br>
<br>
/usr/include/sys/time.h:199:1: error: extraneous closing brace ('}')<br>
<br>
__END_DECLS<br>
<br>
^<br>
<br>
/usr/include/sys/cdefs.h:72:21: note: expanded from macro '__END_DECLS'<br>
<br>
#define __END_DECLS     }<br>
<br>
                        ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:185:<br>
<br>
/usr/include/unistd.h:707:7: error: declaration of 'valloc' has a<br>
different language linkage<br>
<br>
void    *valloc(size_t);<br>
<br>
         ^<br>
<br>
/usr/include/stdlib.h:316:7: note: previous declaration is here<br>
<br>
void    *valloc(size_t);<br>
<br>
         ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:185:<br>
<br>
/usr/include/unistd.h:709:14: error: declaration of 'suboptarg' has a<br>
different language linkage<br>
<br>
extern char *suboptarg;                 /* getsubopt(3) external variable */<br>
<br>
             ^<br>
<br>
/usr/include/stdlib.h:315:14: note: previous definition is here<br>
<br>
extern char *suboptarg;         /* getsubopt(3) external variable */<br>
<br>
             ^<br>
<br>
While building module 'Darwin' imported from<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:<br>
<br>
In file included from <module-includes>:325:<br>
<br>
In file included from /usr/include/ncurses.h:141:<br>
<br>
/usr/include/unctrl.h:54:1: error: expected '}'<br>
<br>
#include <curses.h><br>
<br>
^<br>
<br>
/usr/include/unctrl.h:51:12: note: to match this '{'<br>
<br>
extern "C" {<br>
<br>
           ^<br>
<br>
/usr/include/unctrl.h:60:1: error: extraneous closing brace ('}')<br>
<br>
}<br>
<br>
^<br>
<br>
/Users/respindola/llvm/clang/test/Headers/cxx11.cpp:18:10: fatal<br>
error: could not build module 'Darwin'<br>
<br>
#include <stdint.h><br>
<br>
 ~~~~~~~~^<br>
<br>
13 errors generated.<br>
<div class="HOEnZb"><div class="h5"><br>
On 22 November 2013 23:06, Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
> Author: rsmith<br>
> Date: Fri Nov 22 22:06:09 2013<br>
> New Revision: 195543<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=195543&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=195543&view=rev</a><br>
> Log:<br>
> Generate a marker token when entering or leaving a submodule when building a<br>
> module. Use the marker to diagnose cases where we try to transition between<br>
> submodules when not at the top level (most likely because a closing brace was<br>
> missing at the end of a header file, but is also possible if submodule headers<br>
> attempt to do something fundamentally non-modular, like our .def files).<br>
><br>
> Added:<br>
>     cfe/trunk/test/Modules/Inputs/malformed/<br>
>     cfe/trunk/test/Modules/Inputs/malformed/a1.h<br>
>     cfe/trunk/test/Modules/Inputs/malformed/a2.h<br>
>     cfe/trunk/test/Modules/Inputs/malformed/b1.h<br>
>     cfe/trunk/test/Modules/Inputs/malformed/b2.h<br>
>     cfe/trunk/test/Modules/Inputs/malformed/module.map<br>
>     cfe/trunk/test/Modules/malformed.cpp<br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/TokenKinds.def<br>
>     cfe/trunk/include/clang/Lex/Preprocessor.h<br>
>     cfe/trunk/include/clang/Parse/Parser.h<br>
>     cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp<br>
>     cfe/trunk/lib/Lex/PPDirectives.cpp<br>
>     cfe/trunk/lib/Lex/PPLexerChange.cpp<br>
>     cfe/trunk/lib/Lex/Preprocessor.cpp<br>
>     cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br>
>     cfe/trunk/lib/Parse/ParseDecl.cpp<br>
>     cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
>     cfe/trunk/lib/Parse/ParseInit.cpp<br>
>     cfe/trunk/lib/Parse/ParseObjc.cpp<br>
>     cfe/trunk/lib/Parse/ParseStmt.cpp<br>
>     cfe/trunk/lib/Parse/Parser.cpp<br>
>     cfe/trunk/test/Modules/auto-module-import.m<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/TokenKinds.def<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/TokenKinds.def (original)<br>
> +++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri Nov 22 22:06:09 2013<br>
> @@ -667,8 +667,10 @@ ANNOTATION(pragma_opencl_extension)<br>
>  ANNOTATION(pragma_openmp)<br>
>  ANNOTATION(pragma_openmp_end)<br>
><br>
> -// Annotation for module import translated from #include etc.<br>
> +// Annotations for module import translated from #include etc.<br>
>  ANNOTATION(module_include)<br>
> +ANNOTATION(module_begin)<br>
> +ANNOTATION(module_end)<br>
><br>
>  #undef ANNOTATION<br>
>  #undef TESTING_KEYWORD<br>
><br>
> Modified: cfe/trunk/include/clang/Lex/Preprocessor.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Lex/Preprocessor.h (original)<br>
> +++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Nov 22 22:06:09 2013<br>
> @@ -276,22 +276,26 @@ class Preprocessor : public RefCountedBa<br>
>      CLK_LexAfterModuleImport<br>
>    } CurLexerKind;<br>
><br>
> +  /// \brief True if the current lexer is for a submodule.<br>
> +  bool CurIsSubmodule;<br>
> +<br>
>    /// IncludeMacroStack - This keeps track of the stack of files currently<br>
>    /// \#included, and macros currently being expanded from, not counting<br>
>    /// CurLexer/CurTokenLexer.<br>
>    struct IncludeStackInfo {<br>
>      enum CurLexerKind     CurLexerKind;<br>
> +    bool                  IsSubmodule;<br>
>      Lexer                 *TheLexer;<br>
>      PTHLexer              *ThePTHLexer;<br>
>      PreprocessorLexer     *ThePPLexer;<br>
>      TokenLexer            *TheTokenLexer;<br>
>      const DirectoryLookup *TheDirLookup;<br>
><br>
> -    IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P,<br>
> -                     PreprocessorLexer* PPL,<br>
> -                     TokenLexer* TL, const DirectoryLookup *D)<br>
> -      : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL),<br>
> -        TheTokenLexer(TL), TheDirLookup(D) {}<br>
> +    IncludeStackInfo(enum CurLexerKind K, bool SM, Lexer *L, PTHLexer *P,<br>
> +                     PreprocessorLexer *PPL, TokenLexer *TL,<br>
> +                     const DirectoryLookup *D)<br>
> +        : CurLexerKind(K), IsSubmodule(SM), TheLexer(L), ThePTHLexer(P),<br>
> +          ThePPLexer(PPL), TheTokenLexer(TL), TheDirLookup(D) {}<br>
>    };<br>
>    std::vector<IncludeStackInfo> IncludeMacroStack;<br>
><br>
> @@ -662,7 +666,7 @@ public:<br>
>    /// start lexing tokens from it instead of the current buffer.  Emit an error<br>
>    /// and don't enter the file on error.<br>
>    void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,<br>
> -                       SourceLocation Loc);<br>
> +                       SourceLocation Loc, bool IsSubmodule = false);<br>
><br>
>    /// EnterMacro - Add a Macro to the top of the include stack and start lexing<br>
>    /// tokens from it instead of the current buffer.  Args specifies the<br>
> @@ -1155,6 +1159,9 @@ private:<br>
>    IdentifierInfo *Ident__abnormal_termination,<br>
>                   *Ident___abnormal_termination,<br>
>                   *Ident_AbnormalTermination;<br>
> +<br>
> +  const char *getCurLexerEndPos();<br>
> +<br>
>  public:<br>
>    void PoisonSEHIdentifiers(bool Poison = true); // Borland<br>
><br>
> @@ -1265,6 +1272,7 @@ private:<br>
><br>
>    void PushIncludeMacroStack() {<br>
>      IncludeMacroStack.push_back(IncludeStackInfo(CurLexerKind,<br>
> +                                                 CurIsSubmodule,<br>
>                                                   CurLexer.take(),<br>
>                                                   CurPTHLexer.take(),<br>
>                                                   CurPPLexer,<br>
> @@ -1280,6 +1288,7 @@ private:<br>
>      CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);<br>
>      CurDirLookup  = IncludeMacroStack.back().TheDirLookup;<br>
>      CurLexerKind = IncludeMacroStack.back().CurLexerKind;<br>
> +    CurIsSubmodule = IncludeMacroStack.back().IsSubmodule;<br>
>      IncludeMacroStack.pop_back();<br>
>    }<br>
><br>
> @@ -1380,11 +1389,13 @@ private:<br>
><br>
>    /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and<br>
>    /// start lexing tokens from it instead of the current buffer.<br>
> -  void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);<br>
> +  void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir,<br>
> +                                bool IsSubmodule = false);<br>
><br>
>    /// EnterSourceFileWithPTH - Add a lexer to the top of the include stack and<br>
>    /// start getting tokens from it using the PTH cache.<br>
> -  void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);<br>
> +  void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir,<br>
> +                              bool IsSubmodule = false);<br>
><br>
>    /// \brief Set the file ID for the preprocessor predefines.<br>
>    void setPredefinesFileID(FileID FID) {<br>
><br>
> Modified: cfe/trunk/include/clang/Parse/Parser.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
> +++ cfe/trunk/include/clang/Parse/Parser.h Fri Nov 22 22:06:09 2013<br>
> @@ -73,7 +73,7 @@ class Parser : public CodeCompletionHand<br>
>    SourceLocation PrevTokLocation;<br>
><br>
>    unsigned short ParenCount, BracketCount, BraceCount;<br>
> -<br>
> +<br>
>    /// Actions - These are the callbacks we invoke as we parse various constructs<br>
>    /// in the file.<br>
>    Sema &Actions;<br>
> @@ -408,6 +408,14 @@ private:<br>
>      Tok.setKind(tok::eof);<br>
>    }<br>
><br>
> +  /// \brief Determine if we're at the end of the file or at a transition<br>
> +  /// between modules.<br>
> +  bool isEofOrEom() {<br>
> +    tok::TokenKind Kind = Tok.getKind();<br>
> +    return Kind == tok::eof || Kind == tok::annot_module_begin ||<br>
> +           Kind == tok::annot_module_end || Kind == tok::annot_module_include;<br>
> +  }<br>
> +<br>
>    /// \brief Handle the annotation token produced for #pragma unused(...)<br>
>    void HandlePragmaUnused();<br>
><br>
><br>
> Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)<br>
> +++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -657,7 +657,9 @@ static void PrintPreprocessedTokens(Prep<br>
>        // -traditional-cpp the lexer keeps /all/ whitespace, including comments.<br>
>        SourceLocation StartLoc = Tok.getLocation();<br>
>        Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));<br>
> -    } else if (Tok.is(tok::annot_module_include)) {<br>
> +    } else if (Tok.is(tok::annot_module_include) ||<br>
> +               Tok.is(tok::annot_module_begin) ||<br>
> +               Tok.is(tok::annot_module_end)) {<br>
>        // PrintPPOutputPPCallbacks::InclusionDirective handles producing<br>
>        // appropriate output here. Ignore this token entirely.<br>
>        PP.Lex(Tok);<br>
><br>
> Modified: cfe/trunk/lib/Lex/PPDirectives.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Lex/PPDirectives.cpp (original)<br>
> +++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -1389,6 +1389,19 @@ bool Preprocessor::ConcatenateIncludeNam<br>
>    return true;<br>
>  }<br>
><br>
> +/// \brief Push a token onto the token stream containing an annotation.<br>
> +static void EnterAnnotationToken(Preprocessor &PP,<br>
> +                                 SourceLocation Begin, SourceLocation End,<br>
> +                                 tok::TokenKind Kind, void *AnnotationVal) {<br>
> +  Token *Tok = new Token[1];<br>
> +  Tok[0].startToken();<br>
> +  Tok[0].setKind(Kind);<br>
> +  Tok[0].setLocation(Begin);<br>
> +  Tok[0].setAnnotationEndLoc(End);<br>
> +  Tok[0].setAnnotationValue(AnnotationVal);<br>
> +  PP.EnterTokenStream(Tok, 1, true, true);<br>
> +}<br>
> +<br>
>  /// HandleIncludeDirective - The "\#include" tokens have just been read, read<br>
>  /// the file to be included from the lexer, then include it!  This is a common<br>
>  /// routine with functionality shared between \#include, \#include_next and<br>
> @@ -1590,7 +1603,7 @@ void Preprocessor::HandleIncludeDirectiv<br>
>      // include directive maps to.<br>
>      bool BuildingImportedModule<br>
>        = Path[0].first->getName() == getLangOpts().CurrentModule;<br>
> -<br>
> +<br>
>      if (!BuildingImportedModule && getLangOpts().ObjC2) {<br>
>        // If we're not building the imported module, warn that we're going<br>
>        // to automatically turn this inclusion directive into a module import.<br>
> @@ -1639,13 +1652,8 @@ void Preprocessor::HandleIncludeDirectiv<br>
>          // make the module visible.<br>
>          // FIXME: Produce this as the current token directly, rather than<br>
>          // allocating a new token for it.<br>
> -        Token *Tok = new Token[1];<br>
> -        Tok[0].startToken();<br>
> -        Tok[0].setKind(tok::annot_module_include);<br>
> -        Tok[0].setLocation(HashLoc);<br>
> -        Tok[0].setAnnotationEndLoc(End);<br>
> -        Tok[0].setAnnotationValue(Imported);<br>
> -        EnterTokenStream(Tok, 1, true, true);<br>
> +        EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include,<br>
> +                             Imported);<br>
>        }<br>
>        return;<br>
>      }<br>
> @@ -1692,8 +1700,23 @@ void Preprocessor::HandleIncludeDirectiv<br>
>    FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);<br>
>    assert(!FID.isInvalid() && "Expected valid file ID");<br>
><br>
> -  // Finally, if all is good, enter the new file!<br>
> -  EnterSourceFile(FID, CurDir, FilenameTok.getLocation());<br>
> +  // Determine if we're switching to building a new submodule, and which one.<br>
> +  ModuleMap::KnownHeader BuildingModule;<br>
> +  if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty()) {<br>
> +    Module *RequestingModule = getModuleForLocation(FilenameLoc);<br>
> +    BuildingModule =<br>
> +        HeaderInfo.getModuleMap().findModuleForHeader(File, RequestingModule);<br>
> +  }<br>
> +<br>
> +  // If all is good, enter the new file!<br>
> +  EnterSourceFile(FID, CurDir, FilenameTok.getLocation(),<br>
> +                  static_cast<bool>(BuildingModule));<br>
> +<br>
> +  // If we're walking into another part of the same module, let the parser<br>
> +  // know that any future declarations are within that other submodule.<br>
> +  if (BuildingModule)<br>
> +    EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,<br>
> +                         BuildingModule.getModule());<br>
>  }<br>
><br>
>  /// HandleIncludeNextDirective - Implements \#include_next.<br>
><br>
> Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)<br>
> +++ cfe/trunk/lib/Lex/PPLexerChange.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -69,7 +69,7 @@ PreprocessorLexer *Preprocessor::getCurr<br>
>  /// EnterSourceFile - Add a source file to the top of the include stack and<br>
>  /// start lexing tokens from it instead of the current buffer.<br>
>  void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,<br>
> -                                   SourceLocation Loc) {<br>
> +                                   SourceLocation Loc, bool IsSubmodule) {<br>
>    assert(!CurTokenLexer && "Cannot #include a file inside a macro!");<br>
>    ++NumEnteredSourceFiles;<br>
><br>
> @@ -78,7 +78,7 @@ void Preprocessor::EnterSourceFile(FileI<br>
><br>
>    if (PTH) {<br>
>      if (PTHLexer *PL = PTH->CreateLexer(FID)) {<br>
> -      EnterSourceFileWithPTH(PL, CurDir);<br>
> +      EnterSourceFileWithPTH(PL, CurDir, IsSubmodule);<br>
>        return;<br>
>      }<br>
>    }<br>
> @@ -101,14 +101,16 @@ void Preprocessor::EnterSourceFile(FileI<br>
>          CodeCompletionFileLoc.getLocWithOffset(CodeCompletionOffset);<br>
>    }<br>
><br>
> -  EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir);<br>
> +  EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir,<br>
> +                           IsSubmodule);<br>
>    return;<br>
>  }<br>
><br>
>  /// EnterSourceFileWithLexer - Add a source file to the top of the include stack<br>
>  ///  and start lexing tokens from it instead of the current buffer.<br>
>  void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,<br>
> -                                            const DirectoryLookup *CurDir) {<br>
> +                                            const DirectoryLookup *CurDir,<br>
> +                                            bool IsSubmodule) {<br>
><br>
>    // Add the current lexer to the include stack.<br>
>    if (CurPPLexer || CurTokenLexer)<br>
> @@ -117,6 +119,7 @@ void Preprocessor::EnterSourceFileWithLe<br>
>    CurLexer.reset(TheLexer);<br>
>    CurPPLexer = TheLexer;<br>
>    CurDirLookup = CurDir;<br>
> +  CurIsSubmodule = IsSubmodule;<br>
>    if (CurLexerKind != CLK_LexAfterModuleImport)<br>
>      CurLexerKind = CLK_Lexer;<br>
><br>
> @@ -133,7 +136,8 @@ void Preprocessor::EnterSourceFileWithLe<br>
>  /// EnterSourceFileWithPTH - Add a source file to the top of the include stack<br>
>  /// and start getting tokens from it using the PTH cache.<br>
>  void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL,<br>
> -                                          const DirectoryLookup *CurDir) {<br>
> +                                          const DirectoryLookup *CurDir,<br>
> +                                          bool IsSubmodule) {<br>
><br>
>    if (CurPPLexer || CurTokenLexer)<br>
>      PushIncludeMacroStack();<br>
> @@ -141,6 +145,7 @@ void Preprocessor::EnterSourceFileWithPT<br>
>    CurDirLookup = CurDir;<br>
>    CurPTHLexer.reset(PL);<br>
>    CurPPLexer = CurPTHLexer.get();<br>
> +  CurIsSubmodule = IsSubmodule;<br>
>    if (CurLexerKind != CLK_LexAfterModuleImport)<br>
>      CurLexerKind = CLK_PTHLexer;<br>
><br>
> @@ -244,6 +249,29 @@ void Preprocessor::PropagateLineStartLea<br>
>    // but it might if they're empty?<br>
>  }<br>
><br>
> +/// \brief Determine the location to use as the end of the buffer for a lexer.<br>
> +///<br>
> +/// If the file ends with a newline, form the EOF token on the newline itself,<br>
> +/// rather than "on the line following it", which doesn't exist.  This makes<br>
> +/// diagnostics relating to the end of file include the last file that the user<br>
> +/// actually typed, which is goodness.<br>
> +const char *Preprocessor::getCurLexerEndPos() {<br>
> +  const char *EndPos = CurLexer->BufferEnd;<br>
> +  if (EndPos != CurLexer->BufferStart &&<br>
> +      (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {<br>
> +    --EndPos;<br>
> +<br>
> +    // Handle \n\r and \r\n:<br>
> +    if (EndPos != CurLexer->BufferStart &&<br>
> +        (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&<br>
> +        EndPos[-1] != EndPos[0])<br>
> +      --EndPos;<br>
> +  }<br>
> +<br>
> +  return EndPos;<br>
> +}<br>
> +<br>
> +<br>
>  /// HandleEndOfFile - This callback is invoked when the lexer hits the end of<br>
>  /// the current file.  This either returns the EOF token or pops a level off<br>
>  /// the include stack and keeps going.<br>
> @@ -342,7 +370,19 @@ bool Preprocessor::HandleEndOfFile(Token<br>
>      FileID ExitedFID;<br>
>      if (Callbacks && !isEndOfMacro && CurPPLexer)<br>
>        ExitedFID = CurPPLexer->getFileID();<br>
> -<br>
> +<br>
> +    // If this file corresponded to a submodule, notify the parser that we've<br>
> +    // left that submodule.<br>
> +    bool LeavingSubmodule = CurIsSubmodule && CurLexer;<br>
> +    if (LeavingSubmodule) {<br>
> +      const char *EndPos = getCurLexerEndPos();<br>
> +      Result.startToken();<br>
> +      CurLexer->BufferPtr = EndPos;<br>
> +      CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);<br>
> +      Result.setAnnotationEndLoc(Result.getLocation());<br>
> +      Result.setAnnotationValue(0);<br>
> +    }<br>
> +<br>
>      // We're done with the #included file.<br>
>      RemoveTopOfLexerStack();<br>
><br>
> @@ -357,27 +397,13 @@ bool Preprocessor::HandleEndOfFile(Token<br>
>                               PPCallbacks::ExitFile, FileType, ExitedFID);<br>
>      }<br>
><br>
> -    // Client should lex another token.<br>
> -    return false;<br>
> +    // Client should lex another token unless we generated an EOM.<br>
> +    return LeavingSubmodule;<br>
>    }<br>
><br>
> -  // If the file ends with a newline, form the EOF token on the newline itself,<br>
> -  // rather than "on the line following it", which doesn't exist.  This makes<br>
> -  // diagnostics relating to the end of file include the last file that the user<br>
> -  // actually typed, which is goodness.<br>
> +  // If this is the end of the main file, form an EOF token.<br>
>    if (CurLexer) {<br>
> -    const char *EndPos = CurLexer->BufferEnd;<br>
> -    if (EndPos != CurLexer->BufferStart &&<br>
> -        (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {<br>
> -      --EndPos;<br>
> -<br>
> -      // Handle \n\r and \r\n:<br>
> -      if (EndPos != CurLexer->BufferStart &&<br>
> -          (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&<br>
> -          EndPos[-1] != EndPos[0])<br>
> -        --EndPos;<br>
> -    }<br>
> -<br>
> +    const char *EndPos = getCurLexerEndPos();<br>
>      Result.startToken();<br>
>      CurLexer->BufferPtr = EndPos;<br>
>      CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);<br>
><br>
> Modified: cfe/trunk/lib/Lex/Preprocessor.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Lex/Preprocessor.cpp (original)<br>
> +++ cfe/trunk/lib/Lex/Preprocessor.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -67,8 +67,8 @@ Preprocessor::Preprocessor(IntrusiveRefC<br>
>        CodeComplete(0), CodeCompletionFile(0), CodeCompletionOffset(0),<br>
>        LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),<br>
>        CodeCompletionReached(0), SkipMainFilePreamble(0, true), CurPPLexer(0),<br>
> -      CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0),<br>
> -      MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),<br>
> +      CurDirLookup(0), CurLexerKind(CLK_Lexer), CurIsSubmodule(false),<br>
> +      Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),<br>
>        DeserialMIChainHead(0) {<br>
>    OwnsHeaderSearch = OwnsHeaders;<br>
><br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -580,6 +580,9 @@ bool Parser::ConsumeAndStoreUntil(tok::T<br>
><br>
>      switch (Tok.getKind()) {<br>
>      case tok::eof:<br>
> +    case tok::annot_module_begin:<br>
> +    case tok::annot_module_end:<br>
> +    case tok::annot_module_include:<br>
>        // Ran out of tokens.<br>
>        return false;<br>
><br>
> @@ -965,6 +968,9 @@ bool Parser::ConsumeAndStoreInitializer(<br>
>        goto consume_token;<br>
><br>
>      case tok::eof:<br>
> +    case tok::annot_module_begin:<br>
> +    case tok::annot_module_end:<br>
> +    case tok::annot_module_include:<br>
>        // Ran out of tokens.<br>
>        return false;<br>
><br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -1561,6 +1561,9 @@ void Parser::SkipMalformedDecl() {<br>
>        break;<br>
><br>
>      case tok::eof:<br>
> +    case tok::annot_module_begin:<br>
> +    case tok::annot_module_end:<br>
> +    case tok::annot_module_include:<br>
>        return;<br>
><br>
>      default:<br>
> @@ -3371,7 +3374,7 @@ void Parser::ParseStructUnionBody(Source<br>
>    SmallVector<Decl *, 32> FieldDecls;<br>
><br>
>    // While we still have something to read, read the declarations in the struct.<br>
> -  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>      // Each iteration of this loop reads one struct-declaration.<br>
><br>
>      // Check for extraneous top-level semicolon.<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -195,7 +195,7 @@ void Parser::ParseInnerNamespace(std::ve<br>
>                                   ParsedAttributes& attrs,<br>
>                                   BalancedDelimiterTracker &Tracker) {<br>
>    if (index == Ident.size()) {<br>
> -    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +    while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>        ParsedAttributesWithRange attrs(AttrFactory);<br>
>        MaybeParseCXX11Attributes(attrs);<br>
>        MaybeParseMicrosoftAttributes(attrs);<br>
> @@ -318,7 +318,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSp<br>
><br>
>    BalancedDelimiterTracker T(*this, tok::l_brace);<br>
>    T.consumeOpen();<br>
> -  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>      ParsedAttributesWithRange attrs(AttrFactory);<br>
>      MaybeParseCXX11Attributes(attrs);<br>
>      MaybeParseMicrosoftAttributes(attrs);<br>
> @@ -2452,7 +2452,7 @@ ExprResult Parser::ParseCXXMemberInitial<br>
>        // a top-level comma always ends the initializer expression.<br>
>        const Token &Next = NextToken();<br>
>        if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||<br>
> -           Next.is(tok::eof)) {<br>
> +          Next.is(tok::eof)) {<br>
>          if (IsFunction)<br>
>            Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)<br>
>              << 1 /* delete */;<br>
> @@ -2597,7 +2597,7 @@ void Parser::ParseCXXMemberSpecification<br>
><br>
>    if (TagDecl) {<br>
>      // While we still have something to read, read the member-declarations.<br>
> -    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +    while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>        // Each iteration of this loop reads one member-declaration.<br>
><br>
>        if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||<br>
> @@ -3420,7 +3420,7 @@ void Parser::ParseMicrosoftIfExistsClass<br>
>      return;<br>
>    }<br>
><br>
> -  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>      // __if_exists, __if_not_exists can nest.<br>
>      if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {<br>
>        ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseInit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseInit.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseInit.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -512,7 +512,7 @@ bool Parser::ParseMicrosoftIfExistsBrace<br>
>      return false;<br>
>    }<br>
><br>
> -  while (Tok.isNot(tok::eof)) {<br>
> +  while (!isEofOrEom()) {<br>
>      trailingComma = false;<br>
>      // If we know that this cannot be a designation, just parse the nested<br>
>      // initializer directly.<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseObjc.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseObjc.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -423,7 +423,7 @@ void Parser::ParseObjCInterfaceDeclList(<br>
>      }<br>
><br>
>      // If we got to the end of the file, exit the loop.<br>
> -    if (Tok.is(tok::eof))<br>
> +    if (isEofOrEom())<br>
>        break;<br>
><br>
>      // Code completion within an Objective-C interface.<br>
> @@ -1289,7 +1289,7 @@ void Parser::ParseObjCClassInstanceVaria<br>
>    BalancedDelimiterTracker T(*this, tok::l_brace);<br>
>    T.consumeOpen();<br>
>    // While we still have something to read, read the instance variables.<br>
> -  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>      // Each iteration of this loop reads one objc-instance-variable-decl.<br>
><br>
>      // Check for extraneous top-level semicolon.<br>
> @@ -1582,7 +1582,7 @@ Parser::ParseObjCAtImplementationDeclara<br>
><br>
>    {<br>
>      ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);<br>
> -    while (!ObjCImplParsing.isFinished() && Tok.isNot(tok::eof)) {<br>
> +    while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {<br>
>        ParsedAttributesWithRange attrs(AttrFactory);<br>
>        MaybeParseCXX11Attributes(attrs);<br>
>        MaybeParseMicrosoftAttributes(attrs);<br>
> @@ -1612,7 +1612,7 @@ Parser::ParseObjCAtEndDeclaration(Source<br>
>  Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {<br>
>    if (!Finished) {<br>
>      finish(P.Tok.getLocation());<br>
> -    if (<a href="http://P.Tok.is" target="_blank">P.Tok.is</a>(tok::eof)) {<br>
> +    if (P.isEofOrEom()) {<br>
>        P.Diag(P.Tok, diag::err_objc_missing_end)<br>
>            << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n");<br>
>        P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseStmt.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseStmt.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -890,7 +890,7 @@ StmtResult Parser::ParseCompoundStatemen<br>
>        Stmts.push_back(R.release());<br>
>    }<br>
><br>
> -  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>      if (Tok.is(tok::annot_pragma_unused)) {<br>
>        HandlePragmaUnused();<br>
>        continue;<br>
> @@ -2058,7 +2058,7 @@ StmtResult Parser::ParseMicrosoftAsmStat<br>
>    SourceLocation TokLoc = Tok.getLocation();<br>
>    do {<br>
>      // If we hit EOF, we're done, period.<br>
> -    if (Tok.is(tok::eof))<br>
> +    if (isEofOrEom())<br>
>        break;<br>
><br>
>      if (!InAsmComment && Tok.is(tok::semi)) {<br>
><br>
> Modified: cfe/trunk/lib/Parse/Parser.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/Parser.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/Parser.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -288,7 +288,7 @@ bool Parser::SkipUntil(ArrayRef<tok::Tok<br>
>      if (Toks.size() == 1 && Toks[0] == tok::eof &&<br>
>          !HasFlagsSet(Flags, StopAtSemi) &&<br>
>          !HasFlagsSet(Flags, StopAtCodeCompletion)) {<br>
> -      while (Tok.getKind() != tok::eof)<br>
> +      while (Tok.isNot(tok::eof))<br>
>          ConsumeAnyToken();<br>
>        return true;<br>
>      }<br>
> @@ -297,7 +297,15 @@ bool Parser::SkipUntil(ArrayRef<tok::Tok<br>
>      case tok::eof:<br>
>        // Ran out of tokens.<br>
>        return false;<br>
> -<br>
> +<br>
> +    case tok::annot_module_begin:<br>
> +    case tok::annot_module_end:<br>
> +    case tok::annot_module_include:<br>
> +      // Stop before we change submodules. They generally indicate a "good"<br>
> +      // place to pick up parsing again (except in the special case where<br>
> +      // we're trying to skip to EOF).<br>
> +      return false;<br>
> +<br>
>      case tok::code_completion:<br>
>        if (!HasFlagsSet(Flags, StopAtCodeCompletion))<br>
>          ConsumeToken();<br>
> @@ -574,10 +582,12 @@ namespace {<br>
>  bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {<br>
>    DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);<br>
><br>
> -  // Skip over the EOF token, flagging end of previous input for incremental<br>
> +  // Skip over the EOF token, flagging end of previous input for incremental<br>
>    // processing<br>
> -  if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))<br>
> +  if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof)) {<br>
>      ConsumeToken();<br>
> +    return false;<br>
> +  }<br>
><br>
>    Result = DeclGroupPtrTy();<br>
>    switch (Tok.getKind()) {<br>
> @@ -592,6 +602,12 @@ bool Parser::ParseTopLevelDecl(DeclGroup<br>
>      ConsumeToken();<br>
>      return false;<br>
><br>
> +  case tok::annot_module_begin:<br>
> +  case tok::annot_module_end:<br>
> +    // FIXME: Update visibility based on the submodule we're in.<br>
> +    ConsumeToken();<br>
> +    return false;<br>
> +<br>
>    case tok::eof:<br>
>      // Late template parsing can begin.<br>
>      if (getLangOpts().DelayedTemplateParsing)<br>
> @@ -1917,14 +1933,15 @@ void Parser::ParseMicrosoftIfExistsExter<br>
>    }<br>
><br>
>    // Parse the declarations.<br>
> -  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {<br>
> +  // FIXME: Support module import within __if_exists?<br>
> +  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {<br>
>      ParsedAttributesWithRange attrs(AttrFactory);<br>
>      MaybeParseCXX11Attributes(attrs);<br>
>      MaybeParseMicrosoftAttributes(attrs);<br>
>      DeclGroupPtrTy Result = ParseExternalDeclaration(attrs);<br>
>      if (Result && !getCurScope()->getParent())<br>
>        Actions.getASTConsumer().HandleTopLevelDecl(Result.get());<br>
> -  }<br>
> +  }<br>
>    Braces.consumeClose();<br>
>  }<br>
><br>
> @@ -1980,8 +1997,8 @@ bool BalancedDelimiterTracker::diagnoseO<br>
>    P.Diag(P.Tok, diag::err_bracket_depth_exceeded)<br>
>      << P.getLangOpts().BracketDepth;<br>
>    P.Diag(P.Tok, diag::note_bracket_depth);<br>
> -  P.SkipUntil(tok::eof);<br>
> -  return true;<br>
> +  P.cutOffParsing();<br>
> +  return true;<br>
>  }<br>
><br>
>  bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,<br>
><br>
> Added: cfe/trunk/test/Modules/Inputs/malformed/a1.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/a1.h?rev=195543&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/a1.h?rev=195543&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/Inputs/malformed/a1.h (added)<br>
> +++ cfe/trunk/test/Modules/Inputs/malformed/a1.h Fri Nov 22 22:06:09 2013<br>
> @@ -0,0 +1 @@<br>
> +void f() {<br>
><br>
> Added: cfe/trunk/test/Modules/Inputs/malformed/a2.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/a2.h?rev=195543&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/a2.h?rev=195543&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/Inputs/malformed/a2.h (added)<br>
> +++ cfe/trunk/test/Modules/Inputs/malformed/a2.h Fri Nov 22 22:06:09 2013<br>
> @@ -0,0 +1 @@<br>
> +}<br>
><br>
> Added: cfe/trunk/test/Modules/Inputs/malformed/b1.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/b1.h?rev=195543&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/b1.h?rev=195543&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/Inputs/malformed/b1.h (added)<br>
> +++ cfe/trunk/test/Modules/Inputs/malformed/b1.h Fri Nov 22 22:06:09 2013<br>
> @@ -0,0 +1,3 @@<br>
> +struct S {<br>
> +  #include "b2.h"<br>
> +};<br>
><br>
> Added: cfe/trunk/test/Modules/Inputs/malformed/b2.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/b2.h?rev=195543&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/b2.h?rev=195543&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/Inputs/malformed/b2.h (added)<br>
> +++ cfe/trunk/test/Modules/Inputs/malformed/b2.h Fri Nov 22 22:06:09 2013<br>
> @@ -0,0 +1 @@<br>
> +void g() {}<br>
><br>
> Added: cfe/trunk/test/Modules/Inputs/malformed/module.map<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/module.map?rev=195543&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/module.map?rev=195543&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/Inputs/malformed/module.map (added)<br>
> +++ cfe/trunk/test/Modules/Inputs/malformed/module.map Fri Nov 22 22:06:09 2013<br>
> @@ -0,0 +1,8 @@<br>
> +module a {<br>
> +  module a1 { header "a1.h" }<br>
> +  module a2 { header "a2.h" }<br>
> +}<br>
> +module b {<br>
> +  module b1 { header "b1.h" }<br>
> +  module b2 { header "b2.h" }<br>
> +}<br>
><br>
> Modified: cfe/trunk/test/Modules/auto-module-import.m<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/auto-module-import.m?rev=195543&r1=195542&r2=195543&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/auto-module-import.m?rev=195543&r1=195542&r2=195543&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/auto-module-import.m (original)<br>
> +++ cfe/trunk/test/Modules/auto-module-import.m Fri Nov 22 22:06:09 2013<br>
> @@ -83,6 +83,6 @@ int getNotInModule() {<br>
>    return not_in_module;<br>
>  }<br>
><br>
> -void includeNotAtTopLevel() {<br>
> -  #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected expression}}<br>
> -}<br>
> +void includeNotAtTopLevel() { // expected-note {{to match this '{'}}<br>
> +  #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected '}'}}<br>
> +} // expected-error {{extraneous closing brace}}<br>
><br>
> Added: cfe/trunk/test/Modules/malformed.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/malformed.cpp?rev=195543&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/malformed.cpp?rev=195543&view=auto</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/Modules/malformed.cpp (added)<br>
> +++ cfe/trunk/test/Modules/malformed.cpp Fri Nov 22 22:06:09 2013<br>
> @@ -0,0 +1,23 @@<br>
> +// RUN: rm -rf %t<br>
> +// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/malformed -DHEADER="a1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-A<br>
> +// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/malformed -DHEADER="b1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-B<br>
> +<br>
> +#define STR2(x) #x<br>
> +#define STR(x) STR2(x)<br>
> +#include STR(HEADER)<br>
> +<br>
> +// CHECK-A: While building module 'a'<br>
> +// CHECK-A: a1.h:1:{{.*}} error: expected '}'<br>
> +// CHECK-A: a1.h:1:{{.*}} note: to match this '{'<br>
> +//<br>
> +// CHECK-A: While building module 'a'<br>
> +// CHECK-A: a2.h:1:{{.*}} error: extraneous closing brace<br>
> +<br>
> +// CHECK-B: While building module 'b'<br>
> +// CHECK-B: b1.h:2:{{.*}} error: expected '}'<br>
> +// CHECK-B: b1.h:1:{{.*}} note: to match this '{'<br>
> +// CHECK-B: b1.h:3:{{.*}} error: extraneous closing brace ('}')<br>
> +//<br>
> +// CHECK-B: While building module 'b'<br>
> +// CHECK-B: b2.h:1:{{.*}} error: redefinition of 'g'<br>
> +// CHECK-B: b2.h:1:{{.*}} note: previous definition is here<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>