From 279fc73896036900366fa1596ec4d624b9db1c05 Mon Sep 17 00:00:00 2001 From: Boris Perovic Date: Fri, 14 Aug 2015 22:49:01 +0200 Subject: [PATCH] Minor fixes around printValue, based on comments after the integration. --- core/base/inc/TString.h | 1 + core/base/src/TString.cxx | 9 ++ interpreter/cling/Module.mk | 2 +- .../cling/Interpreter/RuntimePrintValue.h | 124 +++++++++--------- .../cling/lib/Interpreter/ValuePrinter.cpp | 10 +- 5 files changed, 84 insertions(+), 62 deletions(-) diff --git a/core/base/inc/TString.h b/core/base/inc/TString.h index 1aa947f9f81661..99cb36a6bee5e8 100644 --- a/core/base/inc/TString.h +++ b/core/base/inc/TString.h @@ -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 diff --git a/core/base/src/TString.cxx b/core/base/src/TString.cxx index c40218c456e3e0..5d3ff4e0c32cea 100644 --- a/core/base/src/TString.cxx +++ b/core/base/src/TString.cxx @@ -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(); +} diff --git a/interpreter/cling/Module.mk b/interpreter/cling/Module.mk index ac3bee97425722..7499ec44787b8b 100644 --- a/interpreter/cling/Module.mk +++ b/interpreter/cling/Module.mk @@ -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 \ diff --git a/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h b/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h index adff7e0ace59bd..9c4e60fa10f1db 100644 --- a/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h +++ b/interpreter/cling/include/cling/Interpreter/RuntimePrintValue.h @@ -12,10 +12,6 @@ #include #include "Value.h" -#ifndef _Bool -#define _Bool bool -#endif - namespace cling { // void pointer @@ -66,25 +62,27 @@ namespace cling { // cling::Value std::string printValue(const Value &value); - // Maps declaration - template - auto printValue_impl(const CollectionType &obj, short) + namespace internal { + // Maps declaration + template + 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 - auto printValue_impl(const CollectionType &obj, int) + // Collections like vector, set, deque etc. declaration + template + 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 - std::string printValue_impl(const T &obj, long); + // General fallback - print object address declaration + template + std::string printValue_impl(const T &obj, long); + } // Collections and general fallback entry function template @@ -99,7 +97,7 @@ 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 + ", "; } @@ -107,54 +105,60 @@ namespace cling { return str + " }"; } - // Maps - template - auto printValue_impl(const CollectionType &obj, short) + namespace internal { + // Maps + template + 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 - auto printValue_impl(const CollectionType &obj, int) + // Collections like vector, set, deque etc. + template + 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 - std::string printValue_impl(const T &obj, long) { - return "@" + printValue((void *) &obj); + // General fallback - print object address + template + std::string printValue_impl(const T &obj, long) { + return "@" + printValue((void *) &obj); + } } } diff --git a/interpreter/cling/lib/Interpreter/ValuePrinter.cpp b/interpreter/cling/lib/Interpreter/ValuePrinter.cpp index fbcc9c730ba9ac..8cadaa71b92006 100644 --- a/interpreter/cling/lib/Interpreter/ValuePrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ValuePrinter.cpp @@ -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()) { @@ -445,11 +447,15 @@ 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 << "*)"; } @@ -457,7 +463,6 @@ static std::string getCastValueString(const Value &V) { return strm.str(); } - static std::string printEnumValue(const Value &V){ std::stringstream enumString; clang::ASTContext& C = V.getASTContext(); @@ -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; @@ -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