Drop support of #pragma cling load header.h
llvm-mirror/clang@444665e219 says: "Remove use of lookahead from _Pragma handling and from all other internal lexing steps in the preprocessor. It is not safe to use the preprocessor's token lookahead except when operating on the final sequence of tokens that would be produced by phase 4 of translation. Doing so corrupts the token lookahead cache used by the parser. (See added testcase for an example.) Lookahead should instead be viewed as a layer on top of the normal lexer. Added assertions to catch any further incorrect uses of lookahead within lexing actions." This tells us that if we try to #include the header.h while processing the
This commit is contained in:
parent
6a66cbd1df
commit
2d1a60d163
@ -126,19 +126,23 @@ namespace {
|
||||
return;
|
||||
|
||||
// Need to parse them all until the end to handle the possible
|
||||
// #include stements that will be generated
|
||||
std::vector<std::string> Files;
|
||||
Files.push_back(std::move(Literal));
|
||||
// #include statements that will be generated
|
||||
struct LibraryFileInfo {
|
||||
std::string FileName;
|
||||
SourceLocation StartLoc;
|
||||
};
|
||||
std::vector<LibraryFileInfo> FileInfos;
|
||||
FileInfos.push_back({std::move(Literal), Tok.getLocation()});
|
||||
while (GetNextLiteral(PP, Tok, Literal, kLoadFile))
|
||||
Files.push_back(std::move(Literal));
|
||||
|
||||
FileInfos.push_back({std::move(Literal), Tok.getLocation()});
|
||||
|
||||
clang::Parser& P = m_Interp.getParser();
|
||||
Parser::ParserCurTokRestoreRAII savedCurToken(P);
|
||||
// After we have saved the token reset the current one to something
|
||||
// which is safe (semi colon usually means empty decl)
|
||||
Token& CurTok = const_cast<Token&>(P.getCurToken());
|
||||
CurTok.setKind(tok::semi);
|
||||
|
||||
|
||||
Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
|
||||
// We can't PushDeclContext, because we go up and the routine that
|
||||
// pops the DeclContext assumes that we drill down always.
|
||||
@ -150,9 +154,15 @@ namespace {
|
||||
TU, m_Interp.getSema().TUScope);
|
||||
Interpreter::PushTransactionRAII pushedT(&m_Interp);
|
||||
|
||||
for (std::string& File : Files) {
|
||||
if (m_Interp.loadFile(File, true) != Interpreter::kSuccess)
|
||||
for (const LibraryFileInfo& FI : FileInfos) {
|
||||
// FIXME: Consider the case where the library static init section has
|
||||
// a call to interpreter parsing header file. It will suffer the same
|
||||
// issue as if we included the file within the pragma.
|
||||
if (m_Interp.loadLibrary(FI.FileName, true) != Interpreter::kSuccess) {
|
||||
PP.Diag(FI.StartLoc, diag::err_expected)
|
||||
<< "is not a library; did you mean #include \"" + FI.FileName + "\"";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
// RUN: cat %s | %cling -L %T -Xclang -verify 2>&1 | FileCheck %s
|
||||
|
||||
#pragma cling load("DoesNotExistPleaseRecover")
|
||||
// expected-error@input_line_13:1{{expected is not a library; did you mean #include "DoesNotExistPleaseRecover"}}
|
||||
// expected-error@input_line_13:1{{'DoesNotExistPleaseRecover' file not found}}
|
||||
|
||||
#pragma cling load("libcall_lib")
|
||||
|
@ -6,70 +6,8 @@
|
||||
// LICENSE.TXT for details.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// RUN: cat %s | %cling -I%S -Xclang -verify 2>&1 | FileCheck %s
|
||||
// RUN: cat %s | %cling -I%S -Xclang -verify 2>&1
|
||||
|
||||
// FIXME: When printing can be properly unloaded don't force it here
|
||||
"BEGIN"
|
||||
// CHECK: (const char [6]) "BEGIN"
|
||||
|
||||
#pragma cling load("P0.h", "P1.h","P2.h")
|
||||
|
||||
ValueA
|
||||
// CHECK-NEXT: (const char *) "ValueA"
|
||||
|
||||
ValueB
|
||||
// CHECK-NEXT: (const char *) "ValueB"
|
||||
|
||||
ValueC
|
||||
// CHECK-NEXT: (const char *) "ValueC"
|
||||
|
||||
.undo
|
||||
.undo
|
||||
.undo
|
||||
.undo
|
||||
|
||||
// FIXME: When print Transactions are properly parenteted remove these
|
||||
.undo
|
||||
.undo
|
||||
.undo
|
||||
|
||||
ValueA // expected-error {{use of undeclared identifier 'ValueA'}}
|
||||
|
||||
#pragma cling load "P0.h" "P1.h" "P2.h"
|
||||
ValueA
|
||||
// CHECK-NEXT: (const char *) "ValueA"
|
||||
|
||||
ValueB
|
||||
// CHECK-NEXT: (const char *) "ValueB"
|
||||
|
||||
ValueC
|
||||
// CHECK-NEXT: (const char *) "ValueC"
|
||||
|
||||
.undo
|
||||
.undo
|
||||
.undo
|
||||
.undo
|
||||
|
||||
// FIXME: When print Transactions are properly parenteted remove these
|
||||
.undo
|
||||
.undo
|
||||
.undo
|
||||
|
||||
ValueB // expected-error {{use of undeclared identifier 'ValueB'}}
|
||||
|
||||
#pragma cling(load, "P0.h", "P1.h", "P2.h")
|
||||
ValueA
|
||||
// CHECK-NEXT: (const char *) "ValueA"
|
||||
|
||||
ValueB
|
||||
// CHECK-NEXT: (const char *) "ValueB"
|
||||
|
||||
ValueC
|
||||
// CHECK-NEXT: (const char *) "ValueC"
|
||||
|
||||
|
||||
#pragma cling load "P0.h P1.h P2.h"
|
||||
ValueD
|
||||
// CHECK-NEXT: (const char *) "ValueD"
|
||||
#pragma cling load("P0.h", "P1.h","P2.h") //expected-error {{expected is not a library; did you mean #include "P0.h"}}
|
||||
|
||||
.q
|
||||
|
Loading…
x
Reference in New Issue
Block a user