trick/trick_source/codegen/Interface_Code_Gen/EnumVisitor.cpp
Alex Lin ba75f6ff37 ICG does not compile using llvm 3.9 #339
The call getRBraceLoc to find the ending source location of things is gone.  Replaced
it with getting the source range and get the end of that range.  Also the way to
get clang/llvm 3.9 to process c++11 code required some reordering of calls in main as
well as adding some more features to be turned on.
2016-10-28 13:21:21 -05:00

100 lines
3.5 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <sstream>
#include <algorithm>
#include "llvm/Support/CommandLine.h"
#include "EnumVisitor.hh"
#include "EnumValues.hh"
#include "Utilities.hh"
extern llvm::cl::opt< int > debug_level ;
EnumVisitor::EnumVisitor( clang::CompilerInstance & in_ci , HeaderSearchDirs & in_hsd ) :
ci(in_ci) , hsd(in_hsd) {
//eval = new EnumValues() ;
}
bool EnumVisitor::VisitDecl(clang::Decl *d) {
//std::cout << "\nEnum Decl = " << d->getDeclKindName() << "" << std::endl ;
return true ;
}
bool EnumVisitor::VisitType(clang::Type *t) {
//std::cout << "\nEnum Type = " << t->getTypeClassName() << "" << std::endl ;
return true;
}
bool EnumVisitor::VisitEnumDecl(clang::EnumDecl *ed) {
eval.setFileName(getFileName(ci , ed->getSourceRange().getEnd(), hsd)) ;
return true;
}
bool EnumVisitor::VisitEnumType(clang::EnumType *et) {
clang::TagDecl * td = et->getDecl() ;
eval.setName(td->getName().str()) ;
if ( debug_level >= 3 ) {
std::cout << "EnumVisitor VisitEnumType " << std::endl ;
std::cout << "eval.getName() = " << eval.getName() << std::endl ;
std::cout << "td->getName() = " << td->getName().str() << std::endl ;
}
if ( eval.getName().empty() ) {
std::string enum_type_name = et->desugar().getAsString() ;
size_t pos ;
// If this enumeration is anonymous return an error condition
if ((pos = enum_type_name.find("<anonymous")) != std::string::npos or
(pos = enum_type_name.find("(anonymous")) != std::string::npos) {
eval.setName("") ;
return false ;
}
if ((pos = enum_type_name.find("enum ")) != std::string::npos ) {
enum_type_name.erase(pos , 5) ;
}
// Strip off containing namespace/class names. They will be added back later.
if ((pos = enum_type_name.find_last_of(":")) != std::string::npos ) {
eval.setName(enum_type_name.substr(pos + 1)) ;
} else {
eval.setName(enum_type_name) ;
}
//std::cout << "\nReplaced Enum name = " << eval->getName() << "" << std::endl ;
}
const clang::DeclContext * Ctx = td->getDeclContext() ;
typedef clang::SmallVector<const clang::DeclContext *, 8> ContextsTy;
ContextsTy Contexts;
// Collect contexts.
while (Ctx && clang::isa<clang::NamedDecl>(Ctx)) {
Contexts.push_back(Ctx);
Ctx = Ctx->getParent();
};
for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend(); I != E; ++I) {
if (const clang::NamespaceDecl *nd = clang::dyn_cast<clang::NamespaceDecl>(*I)) {
if (! nd->isAnonymousNamespace()) {
//std::cout << "namespace " << nd->getIdentifier()->getName().str() << std::endl ;
eval.addNamespace(nd->getIdentifier()->getName().str()) ;
}
} else if (const clang::RecordDecl *rd = clang::dyn_cast<clang::RecordDecl>(*I)) {
if (rd->getIdentifier()) {
//std::cout << "in class " << rd->getName().str() << std::endl ;
eval.addContainerClass(rd->getName().str()) ;
}
}
}
return true ;
}
bool EnumVisitor::VisitEnumConstantDecl(clang::EnumConstantDecl *ecd) {
//std::cout << ecd->getName().str() << " = " << ecd->getInitVal().getSExtValue() << std::endl ;
eval.addEnum(ecd->getName().str() , ecd->getInitVal().getSExtValue()) ;
return true ;
}
EnumValues * EnumVisitor::get_enum_data() {
return &eval ;
}