Polish the implementation. Each pragma equivalent must use different source location.

This commit is contained in:
Vassil Vassilev 2014-04-02 15:24:15 +02:00 committed by sftnight
parent 26d409e472
commit 76c4024d1d
2 changed files with 25 additions and 3 deletions

View File

@ -176,6 +176,13 @@ namespace cling {
/// ///
mutable std::vector<ClangInternalState*> m_StoredStates; mutable std::vector<ClangInternalState*> m_StoredStates;
///\ brief The last pragma pop point we faked. This helps emulating clang's
/// logic when it comes to pragma handling and diagnostic states.
/// NOTE: this approach continues to add up states, which can be a
/// performance penalty.
///
unsigned m_LastCustomPragmaDiagPopPoint;
///\brief: FIXME: workaround until JIT supports exceptions ///\brief: FIXME: workaround until JIT supports exceptions
static jmp_buf* m_JumpBuf; static jmp_buf* m_JumpBuf;

View File

@ -871,7 +871,7 @@ namespace cling {
} }
Interpreter::CompilationResult Interpreter::CompilationResult
Interpreter::EvaluateInternal(const std::string& input, Interpreter::EvaluateInternal(const std::string& input,
const CompilationOptions& CO, const CompilationOptions& CO,
Value* V, /* = 0 */ Value* V, /* = 0 */
Transaction** T /* = 0 */) { Transaction** T /* = 0 */) {
@ -884,9 +884,16 @@ namespace cling {
// Disable warnings which doesn't make sense when using the prompt // Disable warnings which doesn't make sense when using the prompt
// This gets reset with the clang::Diagnostics().Reset(/*soft*/=false) // This gets reset with the clang::Diagnostics().Reset(/*soft*/=false)
// using clang's API we simulate:
// #pragma warning push
// #pragma warning ignore ...
// #pragma warning ignore ...
// #pragma warning pop
SourceLocation Loc = m_IncrParser->getLastMemoryBufferEndLoc(); SourceLocation Loc = m_IncrParser->getLastMemoryBufferEndLoc();
DiagnosticsEngine& Diags = getCI()->getDiagnostics(); DiagnosticsEngine& Diags = getCI()->getDiagnostics();
Diags.pushMappings(Loc); Diags.pushMappings(Loc);
// The source locations of #pragma warning ignore must be greater than
// the ones from #pragma push
Loc = Loc.getLocWithOffset(1); Loc = Loc.getLocWithOffset(1);
Diags.setDiagnosticMapping(clang::diag::warn_unused_expr, Diags.setDiagnosticMapping(clang::diag::warn_unused_expr,
clang::diag::MAP_IGNORE, Loc); clang::diag::MAP_IGNORE, Loc);
@ -896,8 +903,16 @@ namespace cling {
clang::diag::MAP_IGNORE, Loc); clang::diag::MAP_IGNORE, Loc);
Diags.setDiagnosticMapping(clang::diag::ext_return_has_expr, Diags.setDiagnosticMapping(clang::diag::ext_return_has_expr,
clang::diag::MAP_IGNORE, Loc); clang::diag::MAP_IGNORE, Loc);
Loc = Loc.getLocWithOffset(1);
if (Transaction* lastT = m_IncrParser->Compile(Wrapper, CO)) { if (Transaction* lastT = m_IncrParser->Compile(Wrapper, CO)) {
Loc = m_IncrParser->getLastMemoryBufferEndLoc().getLocWithOffset(1);
// if the location was the same we are in recursive calls and to avoid an
// assert in clang we should increment by a value.
if (SourceLocation::getFromRawEncoding(m_LastCustomPragmaDiagPopPoint)
== Loc)
// Nested #pragma pop-s must be on different source locations.
Loc = Loc.getLocWithOffset(1);
m_LastCustomPragmaDiagPopPoint = Loc.getRawEncoding();
Diags.popMappings(Loc); Diags.popMappings(Loc);
assert((lastT->getState() == Transaction::kCommitted assert((lastT->getState() == Transaction::kCommitted
|| lastT->getState() == Transaction::kRolledBack) || lastT->getState() == Transaction::kRolledBack)
@ -913,7 +928,7 @@ namespace cling {
return Interpreter::kFailure; return Interpreter::kFailure;
} }
Diags.popMappings(Loc); Diags.popMappings(Loc.getLocWithOffset(1));
return Interpreter::kSuccess; return Interpreter::kSuccess;
} }