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; }
// updates S.Ok; and, depending on Kind, possibly S.FnAccumulatorOk or S.FnOutConverterOk void RSExportReduce::checkVoidReturn(StateOfAnalyzeTranslationUnit &S, FnIdent Kind, clang::FunctionDecl *Fn) { slangAssert(Fn); const clang::QualType ReturnTy = Fn->getReturnType().getCanonicalType(); if (!ReturnTy->isVoidType()) { S.RSC.ReportError(Fn->getLocation(), "%0 must return void not '%1'") << S.DiagnosticDescription(getKey(Kind), Fn->getName()) << ReturnTy.getAsString(); notOk(S, Kind); } }