Exemple #1
0
bool MocNg::ShouldRegisterMetaType(clang::QualType T)
{
    if (T->isVoidType() || (T->isReferenceType() && !T.getNonReferenceType().isConstQualified()))
        return false;

    if (registered_meta_type.count(T->getCanonicalTypeUnqualified().getTypePtr()))
        return true;

    T = T.getNonReferenceType();

    if (T->isPointerType()) {
        // registering pointer to forward declared type fails.
        const clang::CXXRecordDecl* Pointee = T->getPointeeCXXRecordDecl();
        if (Pointee && !Pointee->hasDefinition())
            return false;
        return true;
    }

    const clang::ClassTemplateSpecializationDecl* TD = llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(T->getAsCXXRecordDecl());
    if (TD) {
        if (!TD->hasDefinition())
            return false;
        for (uint I = 0; I < TD->getTemplateArgs().size(); ++I) {
            const auto &Arg = TD->getTemplateArgs().get(I);
            if (Arg.getKind() == clang::TemplateArgument::Type) {
                if (!ShouldRegisterMetaType(Arg.getAsType()))
                    return false;
            }
        }
    }
    return true;
}
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 (Ty.getAsString().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);
}