r195543 - Generate a marker token when entering or leaving a submodule when building a
Richard Smith
richard-llvm at metafoo.co.uk
Fri Nov 22 20:06:10 PST 2013
Author: rsmith
Date: Fri Nov 22 22:06:09 2013
New Revision: 195543
URL: http://llvm.org/viewvc/llvm-project?rev=195543&view=rev
Log:
Generate a marker token when entering or leaving a submodule when building a
module. Use the marker to diagnose cases where we try to transition between
submodules when not at the top level (most likely because a closing brace was
missing at the end of a header file, but is also possible if submodule headers
attempt to do something fundamentally non-modular, like our .def files).
Added:
cfe/trunk/test/Modules/Inputs/malformed/
cfe/trunk/test/Modules/Inputs/malformed/a1.h
cfe/trunk/test/Modules/Inputs/malformed/a2.h
cfe/trunk/test/Modules/Inputs/malformed/b1.h
cfe/trunk/test/Modules/Inputs/malformed/b2.h
cfe/trunk/test/Modules/Inputs/malformed/module.map
cfe/trunk/test/Modules/malformed.cpp
Modified:
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/PPLexerChange.cpp
cfe/trunk/lib/Lex/Preprocessor.cpp
cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseInit.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/test/Modules/auto-module-import.m
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri Nov 22 22:06:09 2013
@@ -667,8 +667,10 @@ ANNOTATION(pragma_opencl_extension)
ANNOTATION(pragma_openmp)
ANNOTATION(pragma_openmp_end)
-// Annotation for module import translated from #include etc.
+// Annotations for module import translated from #include etc.
ANNOTATION(module_include)
+ANNOTATION(module_begin)
+ANNOTATION(module_end)
#undef ANNOTATION
#undef TESTING_KEYWORD
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Nov 22 22:06:09 2013
@@ -276,22 +276,26 @@ class Preprocessor : public RefCountedBa
CLK_LexAfterModuleImport
} CurLexerKind;
+ /// \brief True if the current lexer is for a submodule.
+ bool CurIsSubmodule;
+
/// IncludeMacroStack - This keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
/// CurLexer/CurTokenLexer.
struct IncludeStackInfo {
enum CurLexerKind CurLexerKind;
+ bool IsSubmodule;
Lexer *TheLexer;
PTHLexer *ThePTHLexer;
PreprocessorLexer *ThePPLexer;
TokenLexer *TheTokenLexer;
const DirectoryLookup *TheDirLookup;
- IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P,
- PreprocessorLexer* PPL,
- TokenLexer* TL, const DirectoryLookup *D)
- : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL),
- TheTokenLexer(TL), TheDirLookup(D) {}
+ IncludeStackInfo(enum CurLexerKind K, bool SM, Lexer *L, PTHLexer *P,
+ PreprocessorLexer *PPL, TokenLexer *TL,
+ const DirectoryLookup *D)
+ : CurLexerKind(K), IsSubmodule(SM), TheLexer(L), ThePTHLexer(P),
+ ThePPLexer(PPL), TheTokenLexer(TL), TheDirLookup(D) {}
};
std::vector<IncludeStackInfo> IncludeMacroStack;
@@ -662,7 +666,7 @@ public:
/// start lexing tokens from it instead of the current buffer. Emit an error
/// and don't enter the file on error.
void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
- SourceLocation Loc);
+ SourceLocation Loc, bool IsSubmodule = false);
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
/// tokens from it instead of the current buffer. Args specifies the
@@ -1155,6 +1159,9 @@ private:
IdentifierInfo *Ident__abnormal_termination,
*Ident___abnormal_termination,
*Ident_AbnormalTermination;
+
+ const char *getCurLexerEndPos();
+
public:
void PoisonSEHIdentifiers(bool Poison = true); // Borland
@@ -1265,6 +1272,7 @@ private:
void PushIncludeMacroStack() {
IncludeMacroStack.push_back(IncludeStackInfo(CurLexerKind,
+ CurIsSubmodule,
CurLexer.take(),
CurPTHLexer.take(),
CurPPLexer,
@@ -1280,6 +1288,7 @@ private:
CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
CurLexerKind = IncludeMacroStack.back().CurLexerKind;
+ CurIsSubmodule = IncludeMacroStack.back().IsSubmodule;
IncludeMacroStack.pop_back();
}
@@ -1380,11 +1389,13 @@ private:
/// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
- void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
+ void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir,
+ bool IsSubmodule = false);
/// EnterSourceFileWithPTH - Add a lexer to the top of the include stack and
/// start getting tokens from it using the PTH cache.
- void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
+ void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir,
+ bool IsSubmodule = false);
/// \brief Set the file ID for the preprocessor predefines.
void setPredefinesFileID(FileID FID) {
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Nov 22 22:06:09 2013
@@ -73,7 +73,7 @@ class Parser : public CodeCompletionHand
SourceLocation PrevTokLocation;
unsigned short ParenCount, BracketCount, BraceCount;
-
+
/// Actions - These are the callbacks we invoke as we parse various constructs
/// in the file.
Sema &Actions;
@@ -408,6 +408,14 @@ private:
Tok.setKind(tok::eof);
}
+ /// \brief Determine if we're at the end of the file or at a transition
+ /// between modules.
+ bool isEofOrEom() {
+ tok::TokenKind Kind = Tok.getKind();
+ return Kind == tok::eof || Kind == tok::annot_module_begin ||
+ Kind == tok::annot_module_end || Kind == tok::annot_module_include;
+ }
+
/// \brief Handle the annotation token produced for #pragma unused(...)
void HandlePragmaUnused();
Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Fri Nov 22 22:06:09 2013
@@ -657,7 +657,9 @@ static void PrintPreprocessedTokens(Prep
// -traditional-cpp the lexer keeps /all/ whitespace, including comments.
SourceLocation StartLoc = Tok.getLocation();
Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
- } else if (Tok.is(tok::annot_module_include)) {
+ } else if (Tok.is(tok::annot_module_include) ||
+ Tok.is(tok::annot_module_begin) ||
+ Tok.is(tok::annot_module_end)) {
// PrintPPOutputPPCallbacks::InclusionDirective handles producing
// appropriate output here. Ignore this token entirely.
PP.Lex(Tok);
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Nov 22 22:06:09 2013
@@ -1389,6 +1389,19 @@ bool Preprocessor::ConcatenateIncludeNam
return true;
}
+/// \brief Push a token onto the token stream containing an annotation.
+static void EnterAnnotationToken(Preprocessor &PP,
+ SourceLocation Begin, SourceLocation End,
+ tok::TokenKind Kind, void *AnnotationVal) {
+ Token *Tok = new Token[1];
+ Tok[0].startToken();
+ Tok[0].setKind(Kind);
+ Tok[0].setLocation(Begin);
+ Tok[0].setAnnotationEndLoc(End);
+ Tok[0].setAnnotationValue(AnnotationVal);
+ PP.EnterTokenStream(Tok, 1, true, true);
+}
+
/// HandleIncludeDirective - The "\#include" tokens have just been read, read
/// the file to be included from the lexer, then include it! This is a common
/// routine with functionality shared between \#include, \#include_next and
@@ -1590,7 +1603,7 @@ void Preprocessor::HandleIncludeDirectiv
// include directive maps to.
bool BuildingImportedModule
= Path[0].first->getName() == getLangOpts().CurrentModule;
-
+
if (!BuildingImportedModule && getLangOpts().ObjC2) {
// If we're not building the imported module, warn that we're going
// to automatically turn this inclusion directive into a module import.
@@ -1639,13 +1652,8 @@ void Preprocessor::HandleIncludeDirectiv
// make the module visible.
// FIXME: Produce this as the current token directly, rather than
// allocating a new token for it.
- Token *Tok = new Token[1];
- Tok[0].startToken();
- Tok[0].setKind(tok::annot_module_include);
- Tok[0].setLocation(HashLoc);
- Tok[0].setAnnotationEndLoc(End);
- Tok[0].setAnnotationValue(Imported);
- EnterTokenStream(Tok, 1, true, true);
+ EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include,
+ Imported);
}
return;
}
@@ -1692,8 +1700,23 @@ void Preprocessor::HandleIncludeDirectiv
FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);
assert(!FID.isInvalid() && "Expected valid file ID");
- // Finally, if all is good, enter the new file!
- EnterSourceFile(FID, CurDir, FilenameTok.getLocation());
+ // Determine if we're switching to building a new submodule, and which one.
+ ModuleMap::KnownHeader BuildingModule;
+ if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty()) {
+ Module *RequestingModule = getModuleForLocation(FilenameLoc);
+ BuildingModule =
+ HeaderInfo.getModuleMap().findModuleForHeader(File, RequestingModule);
+ }
+
+ // If all is good, enter the new file!
+ EnterSourceFile(FID, CurDir, FilenameTok.getLocation(),
+ static_cast<bool>(BuildingModule));
+
+ // If we're walking into another part of the same module, let the parser
+ // know that any future declarations are within that other submodule.
+ if (BuildingModule)
+ EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
+ BuildingModule.getModule());
}
/// HandleIncludeNextDirective - Implements \#include_next.
Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Fri Nov 22 22:06:09 2013
@@ -69,7 +69,7 @@ PreprocessorLexer *Preprocessor::getCurr
/// EnterSourceFile - Add a source file to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
- SourceLocation Loc) {
+ SourceLocation Loc, bool IsSubmodule) {
assert(!CurTokenLexer && "Cannot #include a file inside a macro!");
++NumEnteredSourceFiles;
@@ -78,7 +78,7 @@ void Preprocessor::EnterSourceFile(FileI
if (PTH) {
if (PTHLexer *PL = PTH->CreateLexer(FID)) {
- EnterSourceFileWithPTH(PL, CurDir);
+ EnterSourceFileWithPTH(PL, CurDir, IsSubmodule);
return;
}
}
@@ -101,14 +101,16 @@ void Preprocessor::EnterSourceFile(FileI
CodeCompletionFileLoc.getLocWithOffset(CodeCompletionOffset);
}
- EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir);
+ EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir,
+ IsSubmodule);
return;
}
/// EnterSourceFileWithLexer - Add a source file to the top of the include stack
/// and start lexing tokens from it instead of the current buffer.
void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,
- const DirectoryLookup *CurDir) {
+ const DirectoryLookup *CurDir,
+ bool IsSubmodule) {
// Add the current lexer to the include stack.
if (CurPPLexer || CurTokenLexer)
@@ -117,6 +119,7 @@ void Preprocessor::EnterSourceFileWithLe
CurLexer.reset(TheLexer);
CurPPLexer = TheLexer;
CurDirLookup = CurDir;
+ CurIsSubmodule = IsSubmodule;
if (CurLexerKind != CLK_LexAfterModuleImport)
CurLexerKind = CLK_Lexer;
@@ -133,7 +136,8 @@ void Preprocessor::EnterSourceFileWithLe
/// EnterSourceFileWithPTH - Add a source file to the top of the include stack
/// and start getting tokens from it using the PTH cache.
void Preprocessor::EnterSourceFileWithPTH(PTHLexer *PL,
- const DirectoryLookup *CurDir) {
+ const DirectoryLookup *CurDir,
+ bool IsSubmodule) {
if (CurPPLexer || CurTokenLexer)
PushIncludeMacroStack();
@@ -141,6 +145,7 @@ void Preprocessor::EnterSourceFileWithPT
CurDirLookup = CurDir;
CurPTHLexer.reset(PL);
CurPPLexer = CurPTHLexer.get();
+ CurIsSubmodule = IsSubmodule;
if (CurLexerKind != CLK_LexAfterModuleImport)
CurLexerKind = CLK_PTHLexer;
@@ -244,6 +249,29 @@ void Preprocessor::PropagateLineStartLea
// but it might if they're empty?
}
+/// \brief Determine the location to use as the end of the buffer for a lexer.
+///
+/// If the file ends with a newline, form the EOF token on the newline itself,
+/// rather than "on the line following it", which doesn't exist. This makes
+/// diagnostics relating to the end of file include the last file that the user
+/// actually typed, which is goodness.
+const char *Preprocessor::getCurLexerEndPos() {
+ const char *EndPos = CurLexer->BufferEnd;
+ if (EndPos != CurLexer->BufferStart &&
+ (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {
+ --EndPos;
+
+ // Handle \n\r and \r\n:
+ if (EndPos != CurLexer->BufferStart &&
+ (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&
+ EndPos[-1] != EndPos[0])
+ --EndPos;
+ }
+
+ return EndPos;
+}
+
+
/// HandleEndOfFile - This callback is invoked when the lexer hits the end of
/// the current file. This either returns the EOF token or pops a level off
/// the include stack and keeps going.
@@ -342,7 +370,19 @@ bool Preprocessor::HandleEndOfFile(Token
FileID ExitedFID;
if (Callbacks && !isEndOfMacro && CurPPLexer)
ExitedFID = CurPPLexer->getFileID();
-
+
+ // If this file corresponded to a submodule, notify the parser that we've
+ // left that submodule.
+ bool LeavingSubmodule = CurIsSubmodule && CurLexer;
+ if (LeavingSubmodule) {
+ const char *EndPos = getCurLexerEndPos();
+ Result.startToken();
+ CurLexer->BufferPtr = EndPos;
+ CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
+ Result.setAnnotationEndLoc(Result.getLocation());
+ Result.setAnnotationValue(0);
+ }
+
// We're done with the #included file.
RemoveTopOfLexerStack();
@@ -357,27 +397,13 @@ bool Preprocessor::HandleEndOfFile(Token
PPCallbacks::ExitFile, FileType, ExitedFID);
}
- // Client should lex another token.
- return false;
+ // Client should lex another token unless we generated an EOM.
+ return LeavingSubmodule;
}
- // If the file ends with a newline, form the EOF token on the newline itself,
- // rather than "on the line following it", which doesn't exist. This makes
- // diagnostics relating to the end of file include the last file that the user
- // actually typed, which is goodness.
+ // If this is the end of the main file, form an EOF token.
if (CurLexer) {
- const char *EndPos = CurLexer->BufferEnd;
- if (EndPos != CurLexer->BufferStart &&
- (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {
- --EndPos;
-
- // Handle \n\r and \r\n:
- if (EndPos != CurLexer->BufferStart &&
- (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&
- EndPos[-1] != EndPos[0])
- --EndPos;
- }
-
+ const char *EndPos = getCurLexerEndPos();
Result.startToken();
CurLexer->BufferPtr = EndPos;
CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Fri Nov 22 22:06:09 2013
@@ -67,8 +67,8 @@ Preprocessor::Preprocessor(IntrusiveRefC
CodeComplete(0), CodeCompletionFile(0), CodeCompletionOffset(0),
LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),
CodeCompletionReached(0), SkipMainFilePreamble(0, true), CurPPLexer(0),
- CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0),
- MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),
+ CurDirLookup(0), CurLexerKind(CLK_Lexer), CurIsSubmodule(false),
+ Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),
DeserialMIChainHead(0) {
OwnsHeaderSearch = OwnsHeaders;
Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Fri Nov 22 22:06:09 2013
@@ -580,6 +580,9 @@ bool Parser::ConsumeAndStoreUntil(tok::T
switch (Tok.getKind()) {
case tok::eof:
+ case tok::annot_module_begin:
+ case tok::annot_module_end:
+ case tok::annot_module_include:
// Ran out of tokens.
return false;
@@ -965,6 +968,9 @@ bool Parser::ConsumeAndStoreInitializer(
goto consume_token;
case tok::eof:
+ case tok::annot_module_begin:
+ case tok::annot_module_end:
+ case tok::annot_module_include:
// Ran out of tokens.
return false;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Nov 22 22:06:09 2013
@@ -1561,6 +1561,9 @@ void Parser::SkipMalformedDecl() {
break;
case tok::eof:
+ case tok::annot_module_begin:
+ case tok::annot_module_end:
+ case tok::annot_module_include:
return;
default:
@@ -3371,7 +3374,7 @@ void Parser::ParseStructUnionBody(Source
SmallVector<Decl *, 32> FieldDecls;
// While we still have something to read, read the declarations in the struct.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// Each iteration of this loop reads one struct-declaration.
// Check for extraneous top-level semicolon.
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Nov 22 22:06:09 2013
@@ -195,7 +195,7 @@ void Parser::ParseInnerNamespace(std::ve
ParsedAttributes& attrs,
BalancedDelimiterTracker &Tracker) {
if (index == Ident.size()) {
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX11Attributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
@@ -318,7 +318,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSp
BalancedDelimiterTracker T(*this, tok::l_brace);
T.consumeOpen();
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX11Attributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
@@ -2452,7 +2452,7 @@ ExprResult Parser::ParseCXXMemberInitial
// a top-level comma always ends the initializer expression.
const Token &Next = NextToken();
if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||
- Next.is(tok::eof)) {
+ Next.is(tok::eof)) {
if (IsFunction)
Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
<< 1 /* delete */;
@@ -2597,7 +2597,7 @@ void Parser::ParseCXXMemberSpecification
if (TagDecl) {
// While we still have something to read, read the member-declarations.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// Each iteration of this loop reads one member-declaration.
if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
@@ -3420,7 +3420,7 @@ void Parser::ParseMicrosoftIfExistsClass
return;
}
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// __if_exists, __if_not_exists can nest.
if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
Modified: cfe/trunk/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseInit.cpp (original)
+++ cfe/trunk/lib/Parse/ParseInit.cpp Fri Nov 22 22:06:09 2013
@@ -512,7 +512,7 @@ bool Parser::ParseMicrosoftIfExistsBrace
return false;
}
- while (Tok.isNot(tok::eof)) {
+ while (!isEofOrEom()) {
trailingComma = false;
// If we know that this cannot be a designation, just parse the nested
// initializer directly.
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Nov 22 22:06:09 2013
@@ -423,7 +423,7 @@ void Parser::ParseObjCInterfaceDeclList(
}
// If we got to the end of the file, exit the loop.
- if (Tok.is(tok::eof))
+ if (isEofOrEom())
break;
// Code completion within an Objective-C interface.
@@ -1289,7 +1289,7 @@ void Parser::ParseObjCClassInstanceVaria
BalancedDelimiterTracker T(*this, tok::l_brace);
T.consumeOpen();
// While we still have something to read, read the instance variables.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
// Each iteration of this loop reads one objc-instance-variable-decl.
// Check for extraneous top-level semicolon.
@@ -1582,7 +1582,7 @@ Parser::ParseObjCAtImplementationDeclara
{
ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
- while (!ObjCImplParsing.isFinished() && Tok.isNot(tok::eof)) {
+ while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX11Attributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
@@ -1612,7 +1612,7 @@ Parser::ParseObjCAtEndDeclaration(Source
Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
if (!Finished) {
finish(P.Tok.getLocation());
- if (P.Tok.is(tok::eof)) {
+ if (P.isEofOrEom()) {
P.Diag(P.Tok, diag::err_objc_missing_end)
<< FixItHint::CreateInsertion(P.Tok.getLocation(), "\n at end\n");
P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Nov 22 22:06:09 2013
@@ -890,7 +890,7 @@ StmtResult Parser::ParseCompoundStatemen
Stmts.push_back(R.release());
}
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
if (Tok.is(tok::annot_pragma_unused)) {
HandlePragmaUnused();
continue;
@@ -2058,7 +2058,7 @@ StmtResult Parser::ParseMicrosoftAsmStat
SourceLocation TokLoc = Tok.getLocation();
do {
// If we hit EOF, we're done, period.
- if (Tok.is(tok::eof))
+ if (isEofOrEom())
break;
if (!InAsmComment && Tok.is(tok::semi)) {
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Fri Nov 22 22:06:09 2013
@@ -288,7 +288,7 @@ bool Parser::SkipUntil(ArrayRef<tok::Tok
if (Toks.size() == 1 && Toks[0] == tok::eof &&
!HasFlagsSet(Flags, StopAtSemi) &&
!HasFlagsSet(Flags, StopAtCodeCompletion)) {
- while (Tok.getKind() != tok::eof)
+ while (Tok.isNot(tok::eof))
ConsumeAnyToken();
return true;
}
@@ -297,7 +297,15 @@ bool Parser::SkipUntil(ArrayRef<tok::Tok
case tok::eof:
// Ran out of tokens.
return false;
-
+
+ case tok::annot_module_begin:
+ case tok::annot_module_end:
+ case tok::annot_module_include:
+ // Stop before we change submodules. They generally indicate a "good"
+ // place to pick up parsing again (except in the special case where
+ // we're trying to skip to EOF).
+ return false;
+
case tok::code_completion:
if (!HasFlagsSet(Flags, StopAtCodeCompletion))
ConsumeToken();
@@ -574,10 +582,12 @@ namespace {
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
- // Skip over the EOF token, flagging end of previous input for incremental
+ // Skip over the EOF token, flagging end of previous input for incremental
// processing
- if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
+ if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof)) {
ConsumeToken();
+ return false;
+ }
Result = DeclGroupPtrTy();
switch (Tok.getKind()) {
@@ -592,6 +602,12 @@ bool Parser::ParseTopLevelDecl(DeclGroup
ConsumeToken();
return false;
+ case tok::annot_module_begin:
+ case tok::annot_module_end:
+ // FIXME: Update visibility based on the submodule we're in.
+ ConsumeToken();
+ return false;
+
case tok::eof:
// Late template parsing can begin.
if (getLangOpts().DelayedTemplateParsing)
@@ -1917,14 +1933,15 @@ void Parser::ParseMicrosoftIfExistsExter
}
// Parse the declarations.
- while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+ // FIXME: Support module import within __if_exists?
+ while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX11Attributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
DeclGroupPtrTy Result = ParseExternalDeclaration(attrs);
if (Result && !getCurScope()->getParent())
Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
- }
+ }
Braces.consumeClose();
}
@@ -1980,8 +1997,8 @@ bool BalancedDelimiterTracker::diagnoseO
P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
<< P.getLangOpts().BracketDepth;
P.Diag(P.Tok, diag::note_bracket_depth);
- P.SkipUntil(tok::eof);
- return true;
+ P.cutOffParsing();
+ return true;
}
bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
Added: cfe/trunk/test/Modules/Inputs/malformed/a1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/a1.h?rev=195543&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/malformed/a1.h (added)
+++ cfe/trunk/test/Modules/Inputs/malformed/a1.h Fri Nov 22 22:06:09 2013
@@ -0,0 +1 @@
+void f() {
Added: cfe/trunk/test/Modules/Inputs/malformed/a2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/a2.h?rev=195543&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/malformed/a2.h (added)
+++ cfe/trunk/test/Modules/Inputs/malformed/a2.h Fri Nov 22 22:06:09 2013
@@ -0,0 +1 @@
+}
Added: cfe/trunk/test/Modules/Inputs/malformed/b1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/b1.h?rev=195543&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/malformed/b1.h (added)
+++ cfe/trunk/test/Modules/Inputs/malformed/b1.h Fri Nov 22 22:06:09 2013
@@ -0,0 +1,3 @@
+struct S {
+ #include "b2.h"
+};
Added: cfe/trunk/test/Modules/Inputs/malformed/b2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/b2.h?rev=195543&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/malformed/b2.h (added)
+++ cfe/trunk/test/Modules/Inputs/malformed/b2.h Fri Nov 22 22:06:09 2013
@@ -0,0 +1 @@
+void g() {}
Added: cfe/trunk/test/Modules/Inputs/malformed/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/malformed/module.map?rev=195543&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/malformed/module.map (added)
+++ cfe/trunk/test/Modules/Inputs/malformed/module.map Fri Nov 22 22:06:09 2013
@@ -0,0 +1,8 @@
+module a {
+ module a1 { header "a1.h" }
+ module a2 { header "a2.h" }
+}
+module b {
+ module b1 { header "b1.h" }
+ module b2 { header "b2.h" }
+}
Modified: cfe/trunk/test/Modules/auto-module-import.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/auto-module-import.m?rev=195543&r1=195542&r2=195543&view=diff
==============================================================================
--- cfe/trunk/test/Modules/auto-module-import.m (original)
+++ cfe/trunk/test/Modules/auto-module-import.m Fri Nov 22 22:06:09 2013
@@ -83,6 +83,6 @@ int getNotInModule() {
return not_in_module;
}
-void includeNotAtTopLevel() {
- #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected expression}}
-}
+void includeNotAtTopLevel() { // expected-note {{to match this '{'}}
+ #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected '}'}}
+} // expected-error {{extraneous closing brace}}
Added: cfe/trunk/test/Modules/malformed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/malformed.cpp?rev=195543&view=auto
==============================================================================
--- cfe/trunk/test/Modules/malformed.cpp (added)
+++ cfe/trunk/test/Modules/malformed.cpp Fri Nov 22 22:06:09 2013
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// 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
+// 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
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+#include STR(HEADER)
+
+// CHECK-A: While building module 'a'
+// CHECK-A: a1.h:1:{{.*}} error: expected '}'
+// CHECK-A: a1.h:1:{{.*}} note: to match this '{'
+//
+// CHECK-A: While building module 'a'
+// CHECK-A: a2.h:1:{{.*}} error: extraneous closing brace
+
+// CHECK-B: While building module 'b'
+// CHECK-B: b1.h:2:{{.*}} error: expected '}'
+// CHECK-B: b1.h:1:{{.*}} note: to match this '{'
+// CHECK-B: b1.h:3:{{.*}} error: extraneous closing brace ('}')
+//
+// CHECK-B: While building module 'b'
+// CHECK-B: b2.h:1:{{.*}} error: redefinition of 'g'
+// CHECK-B: b2.h:1:{{.*}} note: previous definition is here
More information about the cfe-commits
mailing list