Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2663,7 +2663,7 @@ Longptr_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
code += codeline + "\n";
}
unnamedMacroOpenCurly
= cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
= cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getSourceManager(), fInterpreter->getCI()->getPreprocessor());
}

fCurExecutingMacros.push_back(fname);
Expand Down
16 changes: 16 additions & 0 deletions interpreter/cling/include/cling/Utils/SourceNormalization.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace clang {
class LangOptions;
class SourceLocation;
class SourceManager;
class Preprocessor;
}

namespace cling {
Expand All @@ -29,13 +30,28 @@ namespace utils {
/// Unnamed macros contain no function definition, but "prompt-style" code
/// surrounded by a set of curly braces.
///
/// \note Preprocessing macros are ignored
/// \param source The source code to analyze.
/// \param LangOpts - LangOptions to use for lexing.
/// \return the position of the unnamed macro's opening '{'; or
/// std::string::npos if this is not an unnamed macro.
size_t isUnnamedMacro(llvm::StringRef source,
clang::LangOptions& LangOpts);

///\brief Determine whether the source is an unnamed macro.
///
/// Unnamed macros contain no function definition, but "prompt-style" code
/// surrounded by a set of curly braces.
///
/// \note Preprocessing macros are fully evaluated
/// \param source The source code to analyze.
/// \param sm - source manager to use for lexing.
/// \param pp - preprocessor to use for lexing.
/// \return the position of the unnamed macro's opening '{'; or
/// std::string::npos if this is not an unnamed macro.
size_t isUnnamedMacro(llvm::StringRef source, clang::SourceManager& sm,
clang::Preprocessor& pp);

///\brief Determine whether the source needs to be moved into a function.
///
/// If so, move possible includes directives out of the future body of the
Expand Down
6 changes: 3 additions & 3 deletions interpreter/cling/lib/MetaProcessor/MetaProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,12 @@ namespace cling {
}

if (posOpenCurly != (size_t)-1 && !content.empty()) {
assert(content[posOpenCurly] == '{'
&& "No curly at claimed position of opening curly!");
assert(posOpenCurly < content.length() && content[posOpenCurly] == '{' &&
"No curly at claimed position of opening curly!");
// hide the curly brace:
content[posOpenCurly] = ' ';
// and the matching closing '}'
size_t posCloseCurly = content.find_last_not_of(whitespace);
size_t posCloseCurly = content.find_last_not_of(whitespace); // TODO replace instead with preprocessed one, isUnnamedMacro should return tuple start and stop, rather than researching here
if (posCloseCurly != std::string::npos) {
if (content[posCloseCurly] == ';' && content[posCloseCurly-1] == '}') {
content[posCloseCurly--] = ' '; // replace ';' and enter next if
Expand Down
24 changes: 23 additions & 1 deletion interpreter/cling/lib/Utils/SourceNormalization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"

#include <utility>

Expand Down Expand Up @@ -443,7 +444,28 @@ cling::utils::isUnnamedMacro(llvm::StringRef source,
return std::string::npos;
}


size_t cling::utils::isUnnamedMacro(llvm::StringRef source,
clang::SourceManager& sm,
clang::Preprocessor& pp) {
std::unique_ptr<llvm::MemoryBuffer> buf =
llvm::MemoryBuffer::getMemBufferCopy(source,
"unnamed_macro_candidate_buffer");
clang::FileID fid = sm.createFileID(std::move(buf));
pp.EnterSourceFile(fid, nullptr, clang::SourceLocation());
clang::Token tok;
do {
pp.Lex(tok); // Lexes while expanding macros and skipping false #if paths
// automatically
if (tok.is(tok::comment))
continue; // ignore comments
if (tok.is(tok::l_brace)) {
return sm.getFileOffset(sm.getFileLoc(tok.getLocation()));
} else {
return std::string::npos;
}
} while (tok.isNot(tok::eof));
return std::string::npos;
}

size_t cling::utils::getWrapPoint(std::string& source,
const clang::LangOptions& LangOpts) {
Expand Down
Loading