File indexing completed on 2024-04-06 12:31:50
0001 #include "ClassDumper.h"
0002 #include "CmsSupport.h"
0003 #include <iostream>
0004 #include <fstream>
0005 #include <iterator>
0006 #include <string>
0007 #include <algorithm>
0008 using namespace clang;
0009 using namespace clang::ento;
0010 using namespace llvm;
0011
0012 namespace clangcms {
0013
0014 void ClassDumper::checkASTDecl(const clang::CXXRecordDecl *RD,
0015 clang::ento::AnalysisManager &mgr,
0016 clang::ento::BugReporter &BR,
0017 std::string tname) const {
0018 const char *sfile = BR.getSourceManager().getPresumedLoc(RD->getLocation()).getFilename();
0019 if (!RD->hasDefinition())
0020 return;
0021 std::string rname = RD->getQualifiedNameAsString();
0022 support::fixAnonNS(rname, sfile);
0023 clang::LangOptions LangOpts;
0024 LangOpts.CPlusPlus = true;
0025 clang::PrintingPolicy Policy(LangOpts);
0026 std::string crname("class '");
0027 const ClassTemplateSpecializationDecl *SD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD);
0028 if (SD) {
0029 std::string buf;
0030 llvm::raw_string_ostream os(buf);
0031 SD->getNameForDiagnostic(os, Policy, true);
0032 crname = crname + os.str() + "'";
0033 support::writeLog(crname, tname);
0034 for (unsigned J = 0, F = SD->getTemplateArgs().size(); J != F; ++J) {
0035 if (SD->getTemplateArgs().get(J).getKind() == clang::TemplateArgument::Type) {
0036 std::string taname;
0037 auto tt = SD->getTemplateArgs().get(J).getAsType().getTypePtr();
0038 if (tt->isRecordType()) {
0039 auto TAD = tt->getAsCXXRecordDecl();
0040 if (TAD)
0041 taname = TAD->getQualifiedNameAsString();
0042 support::fixAnonNS(taname, sfile);
0043 std::string sdname = SD->getQualifiedNameAsString();
0044 support::fixAnonNS(sdname, sfile);
0045 std::string cfname = "templated data class '" + sdname + "' template type class '" + taname + "'";
0046 support::writeLog(crname + " " + cfname, tname);
0047 }
0048 if (tt->isPointerType() || tt->isReferenceType()) {
0049 auto TAD = tt->getPointeeCXXRecordDecl();
0050 if (TAD)
0051 taname = TAD->getQualifiedNameAsString();
0052 support::fixAnonNS(taname, sfile);
0053 std::string sdname = SD->getQualifiedNameAsString();
0054 support::fixAnonNS(sdname, sfile);
0055 std::string cfname = "templated data class '" + sdname + "' template type class '" + taname + "'";
0056 std::string cbname = "templated data class 'bare_ptr' template type class '" + taname + "'";
0057 support::writeLog(crname + " " + cfname, tname);
0058 support::writeLog(crname + " " + cbname, tname);
0059 }
0060 }
0061 }
0062
0063 } else {
0064
0065 crname = crname + rname + "'";
0066 support::writeLog(crname, tname);
0067 }
0068
0069
0070 for (auto I = RD->field_begin(), E = RD->field_end(); I != E; ++I) {
0071 clang::QualType qual;
0072 clang::QualType type = I->getType();
0073 if (type.getTypePtr()->isAnyPointerType())
0074 qual = type.getTypePtr()->getPointeeType();
0075 else
0076 qual = type.getNonReferenceType();
0077 if (!qual.getTypePtr()->isRecordType())
0078 continue;
0079 if (const CXXRecordDecl *TRD = qual.getTypePtr()->getAsCXXRecordDecl()) {
0080 std::string fname = TRD->getQualifiedNameAsString();
0081 support::fixAnonNS(fname, sfile);
0082 const ClassTemplateSpecializationDecl *SD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(TRD);
0083 if (SD) {
0084 std::string buf;
0085 llvm::raw_string_ostream os(buf);
0086 SD->getNameForDiagnostic(os, Policy, true);
0087 std::string cfname = "member data class '" + os.str() + "'";
0088 support::writeLog(crname + " " + cfname, tname);
0089
0090 for (unsigned J = 0, F = SD->getTemplateArgs().size(); J != F; ++J) {
0091 if (SD->getTemplateArgs().get(J).getKind() == clang::TemplateArgument::Type) {
0092 std::string taname;
0093 const clang::Type *tt = SD->getTemplateArgs().get(J).getAsType().getTypePtr();
0094 if (tt->isRecordType()) {
0095 const clang::CXXRecordDecl *TAD = tt->getAsCXXRecordDecl();
0096 if (TAD)
0097 taname = TAD->getQualifiedNameAsString();
0098 support::fixAnonNS(taname, sfile);
0099 std::string sdname = SD->getQualifiedNameAsString();
0100 support::fixAnonNS(sdname, sfile);
0101 std::string cfname =
0102 "templated member data class '" + sdname + "' template type class '" + taname + "'";
0103 support::writeLog(crname + " " + cfname, tname);
0104 }
0105 if (tt->isPointerType() || tt->isReferenceType()) {
0106 const clang::CXXRecordDecl *TAD = tt->getPointeeCXXRecordDecl();
0107 if (TAD)
0108 taname = TAD->getQualifiedNameAsString();
0109 support::fixAnonNS(taname, sfile);
0110 std::string sdname = SD->getQualifiedNameAsString();
0111 support::fixAnonNS(sdname, sfile);
0112 std::string cfname =
0113 "templated member data class '" + sdname + "' template type class '" + taname + "'";
0114 std::string cbname = "templated member data class 'bare_ptr' template type class '" + taname + "'";
0115 support::writeLog(crname + " " + cfname, tname);
0116 support::writeLog(crname + " " + cbname, tname);
0117 }
0118 }
0119 }
0120 } else {
0121 if (type.getTypePtr()->isRecordType()) {
0122 std::string cfname = "member data class '" + fname + "' ";
0123 support::writeLog(crname + " " + cfname, tname);
0124 }
0125 if (type.getTypePtr()->isAnyPointerType()) {
0126 std::string cfname = "templated member data class 'bare_ptr' template type class '" + fname + "'";
0127 support::writeLog(crname + " " + cfname, tname);
0128 }
0129 }
0130 }
0131 }
0132
0133
0134
0135 for (auto J = RD->bases_begin(), F = RD->bases_end(); J != F; ++J) {
0136 auto BRD = J->getType()->getAsCXXRecordDecl();
0137 if (!BRD)
0138 continue;
0139 std::string bname = BRD->getQualifiedNameAsString();
0140 support::fixAnonNS(bname, sfile);
0141 std::string cbname = "base class '" + bname + "'";
0142 support::writeLog(crname + " " + cbname, tname);
0143 }
0144
0145 }
0146
0147 void ClassDumperCT::checkASTDecl(const clang::ClassTemplateDecl *TD,
0148 clang::ento::AnalysisManager &mgr,
0149 clang::ento::BugReporter &BR) const {
0150 const char *sfile = BR.getSourceManager().getPresumedLoc(TD->getLocation()).getFilename();
0151 if (!support::isCmsLocalFile(sfile))
0152 return;
0153 std::string crname("class '");
0154 std::string pname = "classes.txt.dumperct.unsorted";
0155 std::string tname = TD->getTemplatedDecl()->getQualifiedNameAsString();
0156
0157 if (tname == "edm::Wrapper" || tname == "edm::RunCache" || tname == "edm::LuminosityBlockCache" ||
0158 tname == "edm::GlobalCache") {
0159 for (auto I = TD->spec_begin(), E = TD->spec_end(); I != E; ++I) {
0160 for (unsigned J = 0, F = I->getTemplateArgs().size(); J != F; ++J) {
0161 auto D = I->getTemplateArgs().get(J).getAsType()->getAsCXXRecordDecl();
0162 if (D) {
0163 ClassDumper dumper;
0164 dumper.checkASTDecl(D, mgr, BR, pname);
0165 std::string taname = D->getQualifiedNameAsString();
0166 support::fixAnonNS(taname, sfile);
0167 std::string tdname = TD->getQualifiedNameAsString();
0168 support::fixAnonNS(tdname, sfile);
0169 std::string cfname = "templated class '" + tdname + "' template type class '" + taname + "'";
0170 support::writeLog(cfname, pname);
0171 }
0172 auto E = I->getTemplateArgs().get(J).getAsType()->getPointeeCXXRecordDecl();
0173 if (E) {
0174 ClassDumper dumper;
0175 dumper.checkASTDecl(E, mgr, BR, pname);
0176 std::string taname = E->getQualifiedNameAsString();
0177 support::fixAnonNS(taname, sfile);
0178 std::string tdname = TD->getQualifiedNameAsString();
0179 support::fixAnonNS(tdname, sfile);
0180 std::string cfname = "templated class '" + tdname + "' template type class '" + taname + "'";
0181 support::writeLog(cfname, pname);
0182 std::string cbname = "templated class 'bare_ptr' template type class '" + taname + "'";
0183 support::writeLog(crname + " " + cbname, pname);
0184 }
0185 }
0186 }
0187 }
0188 }
0189
0190 void ClassDumperFT::checkASTDecl(const clang::FunctionTemplateDecl *TD,
0191 clang::ento::AnalysisManager &mgr,
0192 clang::ento::BugReporter &BR) const {
0193 const char *sfile = BR.getSourceManager().getPresumedLoc(TD->getLocation()).getFilename();
0194 if (!support::isCmsLocalFile(sfile))
0195 return;
0196 std::string crname("class '");
0197 std::string pname = "classes.txt.dumperft.unsorted";
0198 if (TD->getTemplatedDecl()->getQualifiedNameAsString().find("typelookup::className") != std::string::npos) {
0199 for (auto I = TD->spec_begin(), E = TD->spec_end(); I != E; ++I) {
0200 auto *SD = (*I);
0201 for (unsigned J = 0, F = SD->getTemplateSpecializationArgs()->size(); J != F; ++J) {
0202 auto D = SD->getTemplateSpecializationArgs()->get(J).getAsType()->getAsCXXRecordDecl();
0203 if (D) {
0204 ClassDumper dumper;
0205 dumper.checkASTDecl(D, mgr, BR, pname);
0206 std::string taname = D->getQualifiedNameAsString();
0207 support::fixAnonNS(taname, sfile);
0208 std::string sdname = SD->getQualifiedNameAsString();
0209 support::fixAnonNS(sdname, sfile);
0210 std::string cfname = "templated function '" + sdname + "' template type class '" + taname + "'";
0211 support::writeLog(cfname, pname);
0212 }
0213 auto E = SD->getTemplateSpecializationArgs()->get(J).getAsType()->getPointeeCXXRecordDecl();
0214 if (E) {
0215 ClassDumper dumper;
0216 dumper.checkASTDecl(E, mgr, BR, pname);
0217 std::string taname = E->getQualifiedNameAsString();
0218 support::fixAnonNS(taname, sfile);
0219 std::string sdname = SD->getQualifiedNameAsString();
0220 support::fixAnonNS(sdname, sfile);
0221 std::string cfname = "templated function '" + sdname + "' template type class '" + taname + "'";
0222 support::writeLog(cfname, pname);
0223 std::string cbname = "templated function 'bare_ptr' template type class '" + taname + "'";
0224 support::writeLog(crname + " " + cbname, pname);
0225 }
0226 }
0227 }
0228 }
0229 }
0230
0231 void ClassDumperInherit::checkASTDecl(const clang::CXXRecordDecl *RD,
0232 clang::ento::AnalysisManager &mgr,
0233 clang::ento::BugReporter &BR) const {
0234 return;
0235 }
0236
0237 }