Back to home page

Project CMSSW displayed by LXR

 
 

    


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       // Dump the class name
0065       crname = crname + rname + "'";
0066       support::writeLog(crname, tname);
0067     }
0068 
0069     // Dump the class member classes
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           // Recurse the template args
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     // Dump the base classes
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   }  //end class
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   }  //end class
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   }  //end class
0230 
0231   void ClassDumperInherit::checkASTDecl(const clang::CXXRecordDecl *RD,
0232                                         clang::ento::AnalysisManager &mgr,
0233                                         clang::ento::BugReporter &BR) const {
0234     return;
0235   }  //end of class
0236 
0237 }  // namespace clangcms