Removed old Stream functions from ValuePrinter.cpp.

This commit is contained in:
Boris Perovic 2015-08-17 13:33:35 +02:00 committed by sftnight
parent 1aa5329d74
commit f7cf46ab31

View File

@ -99,288 +99,6 @@ static bool isAddressValid(void* P) {
#endif
}
static void StreamValue(llvm::raw_ostream& o, const void* V, clang::QualType QT,
cling::Interpreter& interp);
static void StreamChar(llvm::raw_ostream& o, const char v) {
if (isprint(v))
o << '\'' << v << '\'';
else {
o << "\\0x";
o.write_hex(v);
}
}
static void StreamCharPtr(llvm::raw_ostream& o, const char* const v) {
if (!v) {
o << "<<<NULL>>>";
return;
}
o << '"';
const char* p = v;
for (;*p && p - v < 128; ++p) {
o << *p;
}
if (*p) o << "\"...";
else o << "\"";
}
static void StreamRef(llvm::raw_ostream& o, const void** V, clang::QualType Ty,
cling::Interpreter& interp){
const clang::ReferenceType* RTy = llvm::dyn_cast<clang::ReferenceType>(Ty);
StreamValue(o, *V, RTy->getPointeeTypeAsWritten(), interp);
}
static void StreamPtr(llvm::raw_ostream& o, const void* v) {
o << v;
}
static void StreamArr(llvm::raw_ostream& o, const void* V, clang::QualType Ty,
cling::Interpreter& interp) {
clang::ASTContext& C = interp.getCI()->getASTContext();
const clang::ArrayType* ArrTy = Ty->getAsArrayTypeUnsafe();
clang::QualType ElementTy = ArrTy->getElementType();
if (ElementTy->isCharType())
StreamCharPtr(o, (const char*)V);
else if (Ty->isConstantArrayType()) {
// Stream a constant array by streaming up to 5 elements.
const clang::ConstantArrayType* CArrTy
= C.getAsConstantArrayType(Ty);
const llvm::APInt& APSize = CArrTy->getSize();
size_t ElBytes = C.getTypeSize(ElementTy) / C.getCharWidth();
size_t Size = (size_t)APSize.getZExtValue();
o << "{ ";
for (size_t i = 0; i < Size; ++i) {
// Handle the case of constant size array of pointers. Eg. const char*[]
if (ElementTy->isPointerType())
StreamValue(o, *(const char* const *)V + i * ElBytes, ElementTy, interp);
else
StreamValue(o, (const char*)V + i * ElBytes, ElementTy, interp);
if (i + 1 < Size) {
if (i == 4) {
o << "...";
break;
}
else o << ", ";
}
}
o << " }";
} else
StreamPtr(o, V);
}
static void StreamFunction(llvm::raw_ostream& o, const void* V,
clang::QualType QT, cling::Interpreter& Interp) {
o << "Function @" << V << '\n';
clang::ASTContext& C = Interp.getCI()->getASTContext();
const Transaction* T = Interp.getLastTransaction();
assert(T->getWrapperFD() && "Must have a wrapper.");
clang::FunctionDecl* WrapperFD = T->getWrapperFD();
const clang::FunctionDecl* FD = 0;
// CE should be the setValueNoAlloc call expr.
if (const clang::CallExpr* CallE
= llvm::dyn_cast_or_null<clang::CallExpr>(
utils::Analyze::GetOrCreateLastExpr(WrapperFD,
/*foundAtPos*/0,
/*omitDS*/false,
&Interp.getSema()))) {
if (const clang::FunctionDecl* FDsetValue
= llvm::dyn_cast_or_null<clang::FunctionDecl>(CallE->getCalleeDecl())){
if (FDsetValue->getNameAsString() == "setValueNoAlloc" &&
CallE->getNumArgs() == 5) {
const clang::Expr* Arg4 = CallE->getArg(4);
while (const clang::CastExpr* CastE
= clang::dyn_cast<clang::CastExpr>(Arg4))
Arg4 = CastE->getSubExpr();
if (const clang::DeclRefExpr* DeclRefExp
= llvm::dyn_cast<clang::DeclRefExpr>(Arg4))
FD = llvm::dyn_cast<clang::FunctionDecl>(DeclRefExp->getDecl());
}
}
}
if (FD) {
clang::SourceRange SRange = FD->getSourceRange();
const char* cBegin = 0;
const char* cEnd = 0;
bool Invalid;
if (SRange.isValid()) {
clang::SourceManager& SM = C.getSourceManager();
clang::SourceLocation LocBegin = SRange.getBegin();
LocBegin = SM.getExpansionRange(LocBegin).first;
o << " at " << SM.getFilename(LocBegin);
unsigned LineNo = SM.getSpellingLineNumber(LocBegin, &Invalid);
if (!Invalid)
o << ':' << LineNo;
o << ":\n";
bool Invalid = false;
cBegin = SM.getCharacterData(LocBegin, &Invalid);
if (!Invalid) {
clang::SourceLocation LocEnd = SRange.getEnd();
LocEnd = SM.getExpansionRange(LocEnd).second;
cEnd = SM.getCharacterData(LocEnd, &Invalid);
if (Invalid)
cBegin = 0;
} else {
cBegin = 0;
}
}
if (cBegin && cEnd && cEnd > cBegin && cEnd - cBegin < 16 * 1024) {
o << llvm::StringRef(cBegin, cEnd - cBegin + 1);
} else {
const clang::FunctionDecl* FDef;
if (FD->hasBody(FDef))
FD = FDef;
FD->print(o);
//const clang::FunctionDecl* FD
// = llvm::cast<const clang::FunctionType>(Ty)->getDecl();
}
}
// type-based print() never and decl-based print() sometimes does not include
// a final newline:
o << '\n';
}
static void StreamLongDouble(llvm::raw_ostream& o, const Value* value,
clang::ASTContext& C) {
std::stringstream sstr;
sstr << value->simplisticCastAs<long double>();
o << sstr.str() << 'L';
}
static void StreamClingValue(llvm::raw_ostream& o, const Value* value) {
if (!value || !value->isValid()) {
o << "<<<invalid>>> @" << value;
} else {
clang::ASTContext& C = value->getASTContext();
clang::QualType QT = value->getType();
o << "boxes [";
o << "("
<< cling::utils::TypeName::GetFullyQualifiedName(QT, C)
<< ") ";
clang::QualType valType = QT.getDesugaredType(C).getNonReferenceType();
if (C.hasSameType(valType, C.LongDoubleTy))
StreamLongDouble(o, value, C);
else if (valType->isFloatingType())
o << value->simplisticCastAs<double>();
else if (valType->isIntegerType()) {
if (valType->hasSignedIntegerRepresentation())
o << value->simplisticCastAs<long long>();
else
o << value->simplisticCastAs<unsigned long long>();
} else if (valType->isBooleanType())
o << (value->simplisticCastAs<bool>() ? "true" : "false");
else if (!valType->isVoidType())
StreamValue(o, value->getPtr(), valType,
*const_cast<Interpreter*>(value->getInterpreter()));
o << "]";
}
}
static void StreamObj(llvm::raw_ostream& o, const void* V, clang::QualType Ty) {
if (clang::CXXRecordDecl* CXXRD = Ty->getAsCXXRecordDecl()) {
std::string QualName = CXXRD->getQualifiedNameAsString();
if (QualName == "cling::Value"){
StreamClingValue(o, (const cling::Value*)V);
return;
}
} // if CXXRecordDecl
// TODO: Print the object members.
o << "@" << V;
}
static void StreamValue(llvm::raw_ostream& o, const void* V,
clang::QualType Ty, cling::Interpreter& Interp) {
clang::ASTContext& C = Interp.getCI()->getASTContext();
if (const clang::BuiltinType *BT
= llvm::dyn_cast<clang::BuiltinType>(Ty.getCanonicalType())) {
switch (BT->getKind()) {
case clang::BuiltinType::Bool:
if (*(const bool*)V)
o << "true";
else
o << "false";
break;
case clang::BuiltinType::Char_U: // intentional fall through
case clang::BuiltinType::UChar: // intentional fall through
case clang::BuiltinType::Char_S: // intentional fall through
case clang::BuiltinType::SChar:
StreamChar(o, *(const char*)V); break;
case clang::BuiltinType::Short:
o << *(const short*)V; break;
case clang::BuiltinType::UShort:
o << *(const unsigned short*)V; break;
case clang::BuiltinType::Int:
o << *(const int*)V; break;
case clang::BuiltinType::UInt:
o << *(const unsigned int*)V; break;
case clang::BuiltinType::Long:
o << *(const long*)V; break;
case clang::BuiltinType::ULong:
o << *(const unsigned long*)V; break;
case clang::BuiltinType::LongLong:
o << *(const long long*)V; break;
case clang::BuiltinType::ULongLong:
o << *(const unsigned long long*)V; break;
case clang::BuiltinType::Float:
o << *(const float*)V; break;
case clang::BuiltinType::Double:
o << *(const double*)V; break;
case clang::BuiltinType::LongDouble: {
std::stringstream ssLD;
ssLD << *(const long double*)V;
o << ssLD.str() << 'L'; break;
}
default:
StreamObj(o, V, Ty);
}
}
else if (cling::utils::TypeName::GetFullyQualifiedName(Ty, C).compare("std::string") == 0) {
StreamObj(o, V, Ty);
o << " "; // force a space
o <<"c_str: ";
StreamCharPtr(o, ((const char*) (*(const std::string*)V).c_str()));
}
else if (Ty->isEnumeralType()) {
clang::EnumDecl* ED = Ty->getAs<clang::EnumType>()->getDecl();
uint64_t value = *(const uint64_t*)V;
bool IsFirst = true;
llvm::APSInt ValAsAPSInt = C.MakeIntValue(value, Ty);
for (clang::EnumDecl::enumerator_iterator I = ED->enumerator_begin(),
E = ED->enumerator_end(); I != E; ++I) {
if (I->getInitVal() == ValAsAPSInt) {
if (!IsFirst) {
o << " ? ";
}
o << "(" << I->getQualifiedNameAsString() << ")";
IsFirst = false;
}
}
o << " : (int) " << ValAsAPSInt.toString(/*Radix = */10);
}
else if (Ty->isReferenceType())
StreamRef(o, (const void**)&V, Ty, Interp);
else if (Ty->isPointerType()) {
clang::QualType PointeeTy = Ty->getPointeeType();
if (PointeeTy->isCharType())
StreamCharPtr(o, (const char*)V);
else if (PointeeTy->isFunctionProtoType())
StreamFunction(o, V, PointeeTy, Interp);
else
StreamPtr(o, V);
}
else if (Ty->isArrayType())
StreamArr(o, V, Ty, Interp);
else if (Ty->isFunctionType())
StreamFunction(o, V, Ty, Interp);
else
StreamObj(o, V, Ty);
}
static std::string getValueString(const Value &V) {
clang::ASTContext &C = V.getASTContext();
clang::QualType Ty = V.getType().getDesugaredType(C);
@ -444,7 +162,8 @@ static std::string getValueString(const Value &V) {
std::ostringstream strm;
strm << (const void *) &V;
return strm.str();
} else if (Ty->isPointerType() || Ty->isReferenceType()
} else if (Ty->isPointerType()
|| Ty->isReferenceType()
|| Ty->isArrayType()) {
std::ostringstream strm;
strm << V.getPtr();
@ -479,6 +198,8 @@ static std::string getCastValueString(const Value &V) {
} else if (Ty->isArrayType()) {
const clang::ArrayType* ArrTy = Ty->getAsArrayTypeUnsafe();
clang::QualType ElementTy = ArrTy->getElementType();
// Not implementing printing as string in case of char ElementTy
// Can be done like this: typeWithOptDeref << "(const char void*)";
if (Ty->isConstantArrayType()) {
const clang::ConstantArrayType* CArrTy = C.getAsConstantArrayType(Ty);
const llvm::APInt& APSize = CArrTy->getSize();