#include #include #include "llvm/Support/CommandLine.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/ASTContext.h" #include "ClassTemplateVisitor.hh" #include "ClassVisitor.hh" #include "EnumVisitor.hh" #include "EnumValues.hh" #include "PrintAttributes.hh" #include "Utilities.hh" extern llvm::cl::opt< int > debug_level ; ClassTemplateVisitor::ClassTemplateVisitor( clang::CompilerInstance & in_ci , CommentSaver & in_cs , HeaderSearchDirs & in_hsd, PrintAttributes & in_pa ) : ci(in_ci) , cs(in_cs) , hsd(in_hsd), pa(in_pa) {} /* We want to process enumerations out of template definitions */ bool ClassTemplateVisitor::TraverseDecl(clang::Decl *d) { if (!d) return true; if (d->isImplicit()) return true; if ( debug_level >=2 ) { std::cout << "ClassTemplateVisitor TraverseDecl " << d->getDeclKindName() << std::endl ; } switch ( d->getKind() ) { case clang::Decl::CXXRecord : { TraverseCXXRecordDecl(static_cast(d)) ; clang::CXXRecordDecl * crd = static_cast(d) ; /* The definition of the record must exist before we can process it. The definition is NULL when this is only a forward declaration of a class. We also only want to process embedded classes that have public access. */ clang::RecordDecl * rd = crd->getDefinition() ; if ( rd != NULL ) { //d->dump() ; //std::cout << "access = " << rd->getAccess() << std::endl << std::endl ; if ( rd->getAccess() == clang::AS_protected || rd->getAccess() == clang::AS_private ) { // protected and private embedded classes cannot be used outside of their class // in our auto-generated code. Keep a set of all classes of this type so we can // test against them. ClassValues temp_cv ; temp_cv.getNamespacesAndClasses(crd->getDeclContext()) ; //std::cout << "marking private " << temp_cv.getFullyQualifiedName() + crd->getNameAsString() << std::endl ; CXXRecordVisitor::addPrivateEmbeddedClass(temp_cv.getFullyQualifiedName() + crd->getNameAsString()) ; } else { TraverseCXXRecordDecl(static_cast(d)) ; } } } break ; case clang::Decl::Enum : { clang::EnumDecl * ed = static_cast(d) ; /* This is an embedded enumeration within a class template. Only process it if is public */ if ( ed->getAccess() == clang::AS_public ) { if ( debug_level >=2 ) { ed->dump() ; std::cout << std::endl ; } EnumVisitor evis(ci, hsd) ; evis.TraverseDecl(ed) ; evis.get_enum_data()->setHasDefinition(false) ; pa.printEnum(evis.get_enum_data()) ; } } break ; default : break ; } return true ; } bool ClassTemplateVisitor::VisitDecl(clang::Decl *d) { if ( debug_level >=2 ) { std::cout << "\nClassTemplateVisitor Decl = " << d->getDeclKindName() << std::endl ; } return true ; } bool ClassTemplateVisitor::VisitType(clang::Type *t) { if ( debug_level >=2 ) { std::cout << "\nClassTemplateVisitor Type = " << t->getTypeClassName() << std::endl ; } return true; }