Cache all string types.
This commit is contained in:
parent
8fab0d5be8
commit
7504234e21
@ -40,17 +40,26 @@ namespace cling {
|
||||
/// Sema and Preprocessor objects.
|
||||
///
|
||||
class LookupHelper {
|
||||
private:
|
||||
std::unique_ptr<clang::Parser> m_Parser;
|
||||
Interpreter* m_Interpreter; // we do not own.
|
||||
const clang::Type* m_StringTy;
|
||||
public:
|
||||
|
||||
enum StringType {
|
||||
kStdString,
|
||||
kWCharString,
|
||||
kUTF16Str,
|
||||
kUTF32Str,
|
||||
kNumCachedStrings,
|
||||
kNotAString = kNumCachedStrings,
|
||||
};
|
||||
enum DiagSetting {
|
||||
NoDiagnostics,
|
||||
WithDiagnostics
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<clang::Parser> m_Parser;
|
||||
Interpreter* m_Interpreter; // we do not own.
|
||||
const clang::Type* m_StringTy[kNumCachedStrings];
|
||||
|
||||
public:
|
||||
LookupHelper(clang::Parser* P, Interpreter* interp);
|
||||
~LookupHelper();
|
||||
|
||||
@ -224,9 +233,8 @@ namespace cling {
|
||||
bool hasFunction(const clang::Decl* scopeDecl, llvm::StringRef funcName,
|
||||
DiagSetting diagOnOff) const;
|
||||
|
||||
|
||||
///\brief Retrieve the QualType of `std::string`.
|
||||
const clang::Type* getStringType();
|
||||
///\brief Retrieve the StringType of given Type.
|
||||
StringType getStringType(const clang::Type* Type);
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
@ -38,7 +38,10 @@ namespace cling {
|
||||
// pin *tor here so that we can have clang::Parser defined and be able to call
|
||||
// the dtor on the OwningPtr
|
||||
LookupHelper::LookupHelper(clang::Parser* P, Interpreter* interp)
|
||||
: m_Parser(P), m_Interpreter(interp), m_StringTy(nullptr) {}
|
||||
: m_Parser(P), m_Interpreter(interp) {
|
||||
// Always properly initialized in getStringType
|
||||
// ::memset(m_StringTy, 0, sizeof(m_StringTy));
|
||||
}
|
||||
|
||||
LookupHelper::~LookupHelper() {}
|
||||
|
||||
@ -1898,14 +1901,39 @@ namespace cling {
|
||||
diagOnOff);
|
||||
}
|
||||
|
||||
const Type* LookupHelper::getStringType() {
|
||||
static const clang::Type* getType(LookupHelper* LH, llvm::StringRef Type) {
|
||||
QualType Qt = LH->findType(Type, LookupHelper::WithDiagnostics);
|
||||
assert(!Qt.isNull() && "Type should exist");
|
||||
return Qt.getTypePtr();
|
||||
}
|
||||
|
||||
LookupHelper::StringType
|
||||
LookupHelper::getStringType(const clang::Type* Type) {
|
||||
assert(Type && "Type cannot be null");
|
||||
const Transaction*& Cache = m_Interpreter->getStdStringTransaction();
|
||||
if (!Cache || !m_StringTy) {
|
||||
if (!Cache || !m_StringTy[kStdString]) {
|
||||
if (!Cache) ::memset(m_StringTy, 0, sizeof(m_StringTy));
|
||||
|
||||
QualType Qt = findType("std::string", WithDiagnostics);
|
||||
if ((m_StringTy = Qt.isNull() ? nullptr : Qt.getTypePtr()))
|
||||
Cache = m_Interpreter->getLatestTransaction();
|
||||
m_StringTy[kStdString] = Qt.isNull() ? nullptr : Qt.getTypePtr();
|
||||
if (!m_StringTy[kStdString]) return kNotAString;
|
||||
|
||||
Cache = m_Interpreter->getLatestTransaction();
|
||||
m_StringTy[kWCharString] = getType(this, "std::wstring");
|
||||
|
||||
const clang::LangOptions& LO = m_Interpreter->getCI()->getLangOpts();
|
||||
if (LO.CPlusPlus11) {
|
||||
m_StringTy[kUTF16Str] = getType(this, "std::u16string");
|
||||
m_StringTy[kUTF32Str] = getType(this, "std::u32string");
|
||||
}
|
||||
}
|
||||
return m_StringTy;
|
||||
|
||||
ASTContext& Ctx = m_Interpreter->getSema().getASTContext();
|
||||
for (unsigned I = 0; I < kNumCachedStrings; ++I) {
|
||||
if (m_StringTy[I] && Ctx.hasSameType(Type, m_StringTy[I]))
|
||||
return StringType(I);
|
||||
}
|
||||
return kNotAString;
|
||||
}
|
||||
|
||||
} // end namespace cling
|
||||
|
@ -754,6 +754,22 @@ static std::string printFunctionValue(const Value &V, const void *ptr, clang::Qu
|
||||
return o.str();
|
||||
}
|
||||
|
||||
static std::string printStringType(const Value &V, const clang::Type* Type) {
|
||||
switch (V.getInterpreter()->getLookupHelper().getStringType(Type)) {
|
||||
case LookupHelper::kStdString:
|
||||
return executePrintValue<std::string>(V, *(std::string*)V.getPtr());
|
||||
case LookupHelper::kWCharString:
|
||||
return executePrintValue<std::wstring>(V, *(std::wstring*)V.getPtr());
|
||||
case LookupHelper::kUTF16Str:
|
||||
return executePrintValue<std::u16string>(V, *(std::u16string*)V.getPtr());
|
||||
case LookupHelper::kUTF32Str:
|
||||
return executePrintValue<std::u32string>(V, *(std::u32string*)V.getPtr());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static std::string printUnpackedClingValue(const Value &V) {
|
||||
// Find the Type for `std::string`. We are guaranteed to have that declared
|
||||
// when this function is called; RuntimePrintValue.h #includes it.
|
||||
@ -776,11 +792,10 @@ static std::string printUnpackedClingValue(const Value &V) {
|
||||
} else if (clang::CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl()) {
|
||||
if (CXXRD->isLambda())
|
||||
return printAddress(V.getPtr(), '@');
|
||||
if (const clang::Type* StrTy =
|
||||
V.getInterpreter()->getLookupHelper().getStringType()) {
|
||||
if (C.hasSameType(CXXRD->getTypeForDecl(), StrTy))
|
||||
return executePrintValue<std::string>(V, *(std::string*)V.getPtr());
|
||||
}
|
||||
|
||||
std::string Str = printStringType(V, CXXRD->getTypeForDecl());
|
||||
if (!Str.empty())
|
||||
return Str;
|
||||
} else if (const clang::BuiltinType *BT
|
||||
= llvm::dyn_cast<clang::BuiltinType>(Td.getCanonicalType().getTypePtr())) {
|
||||
switch (BT->getKind()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user