mikerice created this revision. mikerice added reviewers: rnk, cfe-commits.
When skipping code at the start of a file during PCH use, Preprocessor::Lex is not used since it consumes all preprocessor directives until it returns a real token. Using the specific Lexer (i.e. CurLexer->Lex) makes it possible to stop skipping after an #include or #pragma hdrstop. Previously the skipping code was only handling CurLexer, now all will be handled correctly. Fixes: llvm.org/PR41585 https://reviews.llvm.org/D61217 Files: lib/Lex/Preprocessor.cpp test/PCH/Inputs/pch-through-macro.h test/PCH/pch-through4.cpp test/PCH/pch-through4a.cpp Index: lib/Lex/Preprocessor.cpp =================================================================== --- lib/Lex/Preprocessor.cpp +++ lib/Lex/Preprocessor.cpp @@ -625,8 +625,23 @@ bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop; Token Tok; while (true) { - bool InPredefines = (CurLexer->getFileID() == getPredefinesFileID()); - CurLexer->Lex(Tok); + bool InPredefines = + (CurLexer && CurLexer->getFileID() == getPredefinesFileID()); + switch (CurLexerKind) { + case CLK_Lexer: + CurLexer->Lex(Tok); + break; + case CLK_TokenLexer: + CurTokenLexer->Lex(Tok); + break; + case CLK_CachingLexer: + bool IsNewToken; + CachingLex(Tok, IsNewToken); + break; + case CLK_LexAfterModuleImport: + LexAfterModuleImport(Tok); + break; + } if (Tok.is(tok::eof) && !InPredefines) { ReachedMainFileEOF = true; break; Index: test/PCH/pch-through4a.cpp =================================================================== --- test/PCH/pch-through4a.cpp +++ test/PCH/pch-through4a.cpp @@ -0,0 +1,16 @@ +// expected-no-diagnostics +// Create PCH with a through header. +// RUN: %clang_cc1 -verify -I %S -emit-pch \ +// RUN: -pch-through-header=Inputs/pch-through1.h \ +// RUN: -fms-extensions -o %t.pch -x c++-header %s + +// Create the PCH object +// RUN: %clang_cc1 -verify -I %S -emit-obj -include-pch %t.pch \ +// RUN: -pch-through-header=Inputs/pch-through1.h \ +// RUN: -fms-extensions -o %t.obj -x c++ %s + +#define Source(x,y) +#define InOut(size) Source(InOut, (size)) +void f(InOut(a) char *b, unsigned long a); +#include "Inputs/pch-through1.h" +int other; Index: test/PCH/pch-through4.cpp =================================================================== --- test/PCH/pch-through4.cpp +++ test/PCH/pch-through4.cpp @@ -0,0 +1,12 @@ +// expected-no-diagnostics +// Create PCH with #pragma hdrstop processing. +// RUN: %clang_cc1 -verify -I %S -emit-pch -pch-through-hdrstop-create \ +// RUN: -fms-extensions -o %t.pch -x c++-header %s + +// Create the PCH object +// RUN: %clang_cc1 -verify -I %S -emit-obj -include-pch %t.pch \ +// RUN: -pch-through-hdrstop-create -fms-extensions -o %t.obj -x c++ %s + +#pragma once +#include "Inputs/pch-through-macro.h" +void f(InOut(a) char *b, unsigned long a); Index: test/PCH/Inputs/pch-through-macro.h =================================================================== --- test/PCH/Inputs/pch-through-macro.h +++ test/PCH/Inputs/pch-through-macro.h @@ -0,0 +1,3 @@ +#pragma once +#define Source(x,y) +#define InOut(size) Source(InOut, (size))
Index: lib/Lex/Preprocessor.cpp =================================================================== --- lib/Lex/Preprocessor.cpp +++ lib/Lex/Preprocessor.cpp @@ -625,8 +625,23 @@ bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop; Token Tok; while (true) { - bool InPredefines = (CurLexer->getFileID() == getPredefinesFileID()); - CurLexer->Lex(Tok); + bool InPredefines = + (CurLexer && CurLexer->getFileID() == getPredefinesFileID()); + switch (CurLexerKind) { + case CLK_Lexer: + CurLexer->Lex(Tok); + break; + case CLK_TokenLexer: + CurTokenLexer->Lex(Tok); + break; + case CLK_CachingLexer: + bool IsNewToken; + CachingLex(Tok, IsNewToken); + break; + case CLK_LexAfterModuleImport: + LexAfterModuleImport(Tok); + break; + } if (Tok.is(tok::eof) && !InPredefines) { ReachedMainFileEOF = true; break; Index: test/PCH/pch-through4a.cpp =================================================================== --- test/PCH/pch-through4a.cpp +++ test/PCH/pch-through4a.cpp @@ -0,0 +1,16 @@ +// expected-no-diagnostics +// Create PCH with a through header. +// RUN: %clang_cc1 -verify -I %S -emit-pch \ +// RUN: -pch-through-header=Inputs/pch-through1.h \ +// RUN: -fms-extensions -o %t.pch -x c++-header %s + +// Create the PCH object +// RUN: %clang_cc1 -verify -I %S -emit-obj -include-pch %t.pch \ +// RUN: -pch-through-header=Inputs/pch-through1.h \ +// RUN: -fms-extensions -o %t.obj -x c++ %s + +#define Source(x,y) +#define InOut(size) Source(InOut, (size)) +void f(InOut(a) char *b, unsigned long a); +#include "Inputs/pch-through1.h" +int other; Index: test/PCH/pch-through4.cpp =================================================================== --- test/PCH/pch-through4.cpp +++ test/PCH/pch-through4.cpp @@ -0,0 +1,12 @@ +// expected-no-diagnostics +// Create PCH with #pragma hdrstop processing. +// RUN: %clang_cc1 -verify -I %S -emit-pch -pch-through-hdrstop-create \ +// RUN: -fms-extensions -o %t.pch -x c++-header %s + +// Create the PCH object +// RUN: %clang_cc1 -verify -I %S -emit-obj -include-pch %t.pch \ +// RUN: -pch-through-hdrstop-create -fms-extensions -o %t.obj -x c++ %s + +#pragma once +#include "Inputs/pch-through-macro.h" +void f(InOut(a) char *b, unsigned long a); Index: test/PCH/Inputs/pch-through-macro.h =================================================================== --- test/PCH/Inputs/pch-through-macro.h +++ test/PCH/Inputs/pch-through-macro.h @@ -0,0 +1,3 @@ +#pragma once +#define Source(x,y) +#define InOut(size) Source(InOut, (size))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits