Skip to content

Commit

Permalink
Minor fixes around printValue, based on comments after the integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
Boris Perovic committed Aug 14, 2015
1 parent 35df380 commit 279fc73
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 62 deletions.
1 change: 1 addition & 0 deletions core/base/inc/TString.h
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ namespace llvm {
namespace cling {
std::string printValue(const TString &val);
std::string printValue(const TSubString &val);
std::string printValue(const std::string_view &val);
}

#endif
9 changes: 9 additions & 0 deletions core/base/src/TString.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2633,3 +2633,12 @@ std::string cling::printValue(const TSubString &val) {
TString s = TString::Format("\"%.*s\"[%d]", (int)val.Length(), val.Data(), (int)val.Length());
return s.Data();
}

////////////////////////////////////////////////////////////////////////////////
/// Print a TString in the cling interpreter:

std::string cling::printValue(const std::string_view &val) {
std::string str(val);
TString s = TString::Format("\"%s\"[%d]", str.c_str(), (int)val.length());
return s.Data();
}
2 changes: 1 addition & 1 deletion interpreter/cling/Module.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ CLINGETC_CLING := DynamicExprInfo.h DynamicLookupRuntimeUniverse.h \
CLINGETC_LLVM := llvm/ADT/IntrusiveRefCntPtr.h \
llvm/ADT/StringRef.h \
llvm/ADT/SmallVector.h \
llvm/ADT/iterator_range.h \
llvm/ADT/iterator_range.h \
llvm/Config/llvm-config.h \
llvm/Support/AlignOf.h \
llvm/Support/Allocator.h \
Expand Down
124 changes: 64 additions & 60 deletions interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
#include <string>
#include "Value.h"

#ifndef _Bool
#define _Bool bool
#endif

namespace cling {

// void pointer
Expand Down Expand Up @@ -66,25 +62,27 @@ namespace cling {
// cling::Value
std::string printValue(const Value &value);

// Maps declaration
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, short)
namespace internal {
// Maps declaration
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, short)
-> decltype(
++(obj.begin()), obj.end(),
obj.begin()->first, obj.begin()->second,
std::string());
obj.begin()->first, obj.begin()->second,
std::string());

// Collections like vector, set, deque etc. declaration
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, int)
// Collections like vector, set, deque etc. declaration
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, int)
-> decltype(
++(obj.begin()), obj.end(),
*(obj.begin()),
std::string());
*(obj.begin()),
std::string());

// General fallback - print object address declaration
template<typename T>
std::string printValue_impl(const T &obj, long);
// General fallback - print object address declaration
template<typename T>
std::string printValue_impl(const T &obj, long);
}

// Collections and general fallback entry function
template<typename CollectionType>
Expand All @@ -99,62 +97,68 @@ namespace cling {
std::string printValue(const T (&obj)[N]) {
std::string str = "{ ";

for(int i = 0; i < N; ++i) {
for (int i = 0; i < N; ++i) {
str = str + printValue(obj[i]);
if (i < N-1) str = str + ", ";
}

return str + " }";
}

// Maps
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, short)
namespace internal {
// Maps
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, short)
-> decltype(
++(obj.begin()), obj.end(),
obj.begin()->first, obj.begin()->second,
std::string())
{
std::string str = "{ ";

auto iter = obj.begin();
auto iterEnd = obj.end();
while (iter != iterEnd) {
str = str + printValue(iter->first);
str = str + " => ";
str = str + printValue(iter->second);
++iter;
if (iter != iterEnd) str = str + ", ";
++(obj.begin()), obj.end(),
obj.begin()->first, obj.begin()->second,
std::string())
{
std::string str = "{ ";

auto iter = obj.begin();
auto iterEnd = obj.end();
while (iter != iterEnd) {
str = str + printValue(iter->first);
str = str + " => ";
str = str + printValue(iter->second);
++iter;
if (iter != iterEnd) {
str = str + ", ";
}
}

return str + " }";
}

return str + " }";
}

// Collections like vector, set, deque etc.
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, int)
// Collections like vector, set, deque etc.
template<typename CollectionType>
auto printValue_impl(const CollectionType &obj, int)
-> decltype(
++(obj.begin()), obj.end(),
*(obj.begin()),
std::string())
{
std::string str = "{ ";

auto iter = obj.begin();
auto iterEnd = obj.end();
while (iter != iterEnd) {
str = str + printValue(*iter);
++iter;
if (iter != iterEnd) str = str + ", ";
++(obj.begin()), obj.end(),
*(obj.begin()),
std::string())
{
std::string str = "{ ";

auto iter = obj.begin();
auto iterEnd = obj.end();
while (iter != iterEnd) {
str = str + printValue(*iter);
++iter;
if (iter != iterEnd) {
str = str + ", ";
}
}

return str + " }";
}

return str + " }";
}

// General fallback - print object address
template<typename T>
std::string printValue_impl(const T &obj, long) {
return "@" + printValue((void *) &obj);
// General fallback - print object address
template<typename T>
std::string printValue_impl(const T &obj, long) {
return "@" + printValue((void *) &obj);
}
}

}
Expand Down
10 changes: 9 additions & 1 deletion interpreter/cling/lib/Interpreter/ValuePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,10 @@ static std::string getCastValueString(const Value &V) {
typeWithOptDeref << "(" << type << ")";
} else if (Ty->isPointerType()) {
if (Ty->getPointeeType()->isCharType()) {
// Print char pointers as strings.
typeWithOptDeref << "(" << type << ")";
} else {
// Fallback to void pointer for other pointers and print the address.
typeWithOptDeref << "(void*)";
}
} else if (Ty->isArrayType()) {
Expand All @@ -445,19 +447,22 @@ static std::string getCastValueString(const Value &V) {
const llvm::APInt& APSize = CArrTy->getSize();
size_t size = (size_t)APSize.getZExtValue();

// typeWithOptDeref example for int[40] array: "((int(&)[40])*(void*)0x5c8f260)"
typeWithOptDeref << "(" << ElementTy.getAsString() << "(&)[" << size << "])*(void*)";
} else {
typeWithOptDeref << "(void*)";
}
} else {
// In other cases, dereference the address of the object.
// If no overload or specific template matches,
// the general template will be used which only prints the address.
typeWithOptDeref << "*(" << type << "*)";
}

strm << typeWithOptDeref.str() << getValueString(V) << suffix.str();
return strm.str();
}


static std::string printEnumValue(const Value &V){
std::stringstream enumString;
clang::ASTContext& C = V.getASTContext();
Expand Down Expand Up @@ -766,6 +771,8 @@ namespace valuePrinterInternal {

std::string printValue_New(const Value& V) {
static bool includedRuntimePrintValue = false; // initialized only once as a static function variable
// Include "RuntimePrintValue.h" only on the first printing.
// This keeps the interpreter lightweight and reduces the startup time.
if(!includedRuntimePrintValue) {
V.getInterpreter()->declare("#include \"cling/Interpreter/RuntimePrintValue.h\"");
includedRuntimePrintValue = true;
Expand All @@ -774,6 +781,7 @@ namespace valuePrinterInternal {
clang::QualType Ty = V.getType().getDesugaredType(C);

if(Ty-> isNullPtrType()) {
// special case nullptr_t
return "@0x0";
} else if (Ty->isEnumeralType()) {
// special case enum printing, using compiled information
Expand Down

0 comments on commit 279fc73

Please sign in to comment.