diff --git a/lib/Interpreter/ValuePrinter.cpp b/lib/Interpreter/ValuePrinter.cpp index 1276825e..9f8a8b51 100644 --- a/lib/Interpreter/ValuePrinter.cpp +++ b/lib/Interpreter/ValuePrinter.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/Frontend/CompilerInstance.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ExecutionEngine/GenericValue.h" @@ -62,7 +63,7 @@ extern "C" void cling_PrintValue(void* /*cling::Value**/ V) { static void StreamValue(llvm::raw_ostream& o, const void* V, clang::QualType QT, - clang::ASTContext& C); + cling::Interpreter& interp); static void StreamChar(llvm::raw_ostream& o, const char v) { if (isprint(v)) @@ -88,9 +89,9 @@ static void StreamCharPtr(llvm::raw_ostream& o, const char* const v) { } static void StreamRef(llvm::raw_ostream& o, const void** V, clang::QualType Ty, - clang::ASTContext& C){ + cling::Interpreter& interp){ const clang::ReferenceType* RTy = llvm::dyn_cast(Ty); - StreamValue(o, *V, RTy->getPointeeTypeAsWritten(), C); + StreamValue(o, *V, RTy->getPointeeTypeAsWritten(), interp); } static void StreamPtr(llvm::raw_ostream& o, const void* v) { @@ -98,7 +99,8 @@ static void StreamPtr(llvm::raw_ostream& o, const void* v) { } static void StreamArr(llvm::raw_ostream& o, const void* V, clang::QualType Ty, - clang::ASTContext& C) { + cling::Interpreter& interp) { + clang::ASTContext& C = interp.getCI()->getASTContext(); const clang::ArrayType* ArrTy = Ty->getAsArrayTypeUnsafe(); clang::QualType ElementTy = ArrTy->getElementType(); if (ElementTy->isCharType()) @@ -112,7 +114,7 @@ static void StreamArr(llvm::raw_ostream& o, const void* V, clang::QualType Ty, size_t Size = (size_t)APSize.getZExtValue(); o << "{ "; for (size_t i = 0; i < Size; ++i) { - StreamValue(o, (const char*) V + i * ElBytes, ElementTy, C); + StreamValue(o, (const char*) V + i * ElBytes, ElementTy, interp); if (i + 1 < Size) { if (i == 4) { o << "..."; @@ -126,28 +128,45 @@ static void StreamArr(llvm::raw_ostream& o, const void* V, clang::QualType Ty, StreamPtr(o, V); } -static void StreamFunction(llvm::raw_ostream& o, Value* V) { - o << "Function @" << V->getPtr() << '\n'; +static void StreamFunction(llvm::raw_ostream& o, const void* V, + clang::QualType QT, cling::Interpreter& Interp) { + o << "Function @" << V << '\n'; - Interpreter* interp = V->getInterpreter(); - const Transaction* T = interp->getLastTransaction(); + clang::ASTContext& C = Interp.getCI()->getASTContext(); + const Transaction* T = Interp.getLastTransaction(); assert(T->getWrapperFD() && "Must have a wrapper."); clang::FunctionDecl* WrapperFD = T->getWrapperFD(); - clang::Expr* ExprAttachedTo - = utils::Analyze::GetOrCreateLastExpr(WrapperFD, /*foundAtPos*/0, - /*omitDS*/false, &interp->getSema()); - const clang::DeclRefExpr* DeclRefExp - = llvm::dyn_cast_or_null(ExprAttachedTo); + const clang::FunctionDecl* FD = 0; - if (DeclRefExp) - FD = llvm::dyn_cast_or_null(DeclRefExp->getDecl()); + // CE should be the setValueNoAlloc call expr. + if (const clang::CallExpr* CallE + = llvm::dyn_cast_or_null( + utils::Analyze::GetOrCreateLastExpr(WrapperFD, + /*foundAtPos*/0, + /*omitDS*/false, + &Interp.getSema()))) { + if (const clang::FunctionDecl* FDsetValue + = llvm::dyn_cast_or_null(CallE->getCalleeDecl())){ + if (FDsetValue->getNameAsString() == "setValueNoAlloc" && + CallE->getNumArgs() == 5) { + const clang::Expr* Arg4 = CallE->getArg(4); + while (const clang::CastExpr* CastE + = clang::dyn_cast(Arg4)) + Arg4 = CastE->getSubExpr(); + if (const clang::DeclRefExpr* DeclRefExp + = llvm::dyn_cast(Arg4)) + FD = llvm::dyn_cast(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 = V->getASTContext().getSourceManager(); + clang::SourceManager& SM = C.getSourceManager(); clang::SourceLocation LocBegin = SRange.getBegin(); LocBegin = SM.getExpansionRange(LocBegin).first; o << " at " << SM.getFilename(LocBegin); @@ -177,10 +196,6 @@ static void StreamFunction(llvm::raw_ostream& o, Value* V) { //const clang::FunctionDecl* FD // = llvm::cast(Ty)->getDecl(); } - } else { - o << ":\n"; - // type-based printing: - V->getType().print(o, V->getASTContext().getPrintingPolicy()); } // type-based print() never and decl-based print() sometimes does not include // a final newline: @@ -217,7 +232,8 @@ static void StreamClingValue(llvm::raw_ostream& o, const Value* value) { } else if (valType->isBooleanType()) o << (value->simplisticCastAs() ? "true" : "false"); else if (!valType->isVoidType()) - StreamValue(o, value->getPtr(), valType, value->getASTContext()); + StreamValue(o, value->getPtr(), valType, + *const_cast(value->getInterpreter())); o << "]"; } } @@ -236,7 +252,8 @@ static void StreamObj(llvm::raw_ostream& o, const void* V, clang::QualType Ty) { } static void StreamValue(llvm::raw_ostream& o, const void* V, - clang::QualType Ty, clang::ASTContext& C) { + clang::QualType Ty, cling::Interpreter& Interp) { + clang::ASTContext& C = Interp.getCI()->getASTContext(); if (const clang::BuiltinType *BT = llvm::dyn_cast(Ty.getCanonicalType())) { switch (BT->getKind()) { @@ -304,18 +321,20 @@ static void StreamValue(llvm::raw_ostream& o, const void* V, o << " : (int) " << ValAsAPSInt.toString(/*Radix = */10); } else if (Ty->isReferenceType()) - StreamRef(o, (const void**)&V, Ty, C); + 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, C); + StreamArr(o, V, Ty, Interp); else if (Ty->isFunctionType()) - StreamFunction(o, const_cast((const cling::Value*)V)); + StreamFunction(o, V, Ty, Interp); else StreamObj(o, V, Ty); } @@ -325,6 +344,7 @@ namespace valuePrinterInternal { void printValue_Default(llvm::raw_ostream& o, const Value& V) { clang::ASTContext& C = V.getASTContext(); clang::QualType Ty = V.getType().getDesugaredType(C); + Interpreter& Interp = *const_cast(V.getInterpreter()); if (const clang::BuiltinType *BT = llvm::dyn_cast(Ty.getCanonicalType())) { switch (BT->getKind()) { @@ -337,7 +357,7 @@ namespace valuePrinterInternal { case clang::BuiltinType::Long: // intentional fall through case clang::BuiltinType::LongLong: { long long res = V.getLL(); - StreamValue(o, (const void*)&res, Ty, C); + StreamValue(o, (const void*)&res, Ty, Interp); } break; case clang::BuiltinType::UChar: // intentional fall through @@ -346,37 +366,37 @@ namespace valuePrinterInternal { case clang::BuiltinType::ULong: // intentional fall through case clang::BuiltinType::ULongLong: { unsigned long long res = V.getULL(); - StreamValue(o, (const void*)&res, Ty, C); + StreamValue(o, (const void*)&res, Ty, Interp); } break; case clang::BuiltinType::Float: { float res = V.getFloat(); - StreamValue(o, (const void*)&res, Ty, C); + StreamValue(o, (const void*)&res, Ty, Interp); } break; case clang::BuiltinType::Double: { double res = V.getDouble(); - StreamValue(o, (const void*)&res, Ty, C); + StreamValue(o, (const void*)&res, Ty, Interp); } break; case clang::BuiltinType::LongDouble: { long double res = V.getLongDouble(); - StreamValue(o, (const void*)&res, Ty, C); + StreamValue(o, (const void*)&res, Ty, Interp); } break; default: - StreamValue(o, V.getPtr(), Ty, C); + StreamValue(o, V.getPtr(), Ty, Interp); break; } } else if (Ty->isIntegralOrEnumerationType()) { long long res = V.getLL(); - StreamValue(o, &res, Ty, C); + StreamValue(o, &res, Ty, Interp); } else if (Ty->isFunctionType()) - StreamValue(o, &V, Ty, C); + StreamValue(o, &V, Ty, Interp); else - StreamValue(o, V.getPtr(), Ty, C); + StreamValue(o, V.getPtr(), Ty, Interp); } void printType_Default(llvm::raw_ostream& o, const Value& V) { diff --git a/test/Prompt/ValuePrinter/Assignments.C b/test/Prompt/ValuePrinter/Assignments.C index 439ef7ae..4e6efaa5 100644 --- a/test/Prompt/ValuePrinter/Assignments.C +++ b/test/Prompt/ValuePrinter/Assignments.C @@ -55,7 +55,7 @@ std::string sarr[3] = {"A", "B", "C"} // CHECK: (std::string [3]) { @0x{{[0-9A-F typedef void (*F_t)(int); .rawInput F_t fp = 0; -fp // CHECK: (F_t) 0x0 +fp // CHECK: (F_t) Function @0x0 #include -fp = (F_t)printf // (F_t) 0x{{[0-9A-Fa-f]{6,12}.}} +fp = (F_t)printf // CHECK: (F_t) Function @0x{{[0-9A-Fa-f]{6,12}.}} .q