ATTRIBUTES for classes with non-locally typedef'd members is wrong

Interesting case.  I found that we should process the canonical type names where
we were not before.  This resolves all typedefs and should be be more
accurate in the future.  When we process the canonical type we need to ignore
the processing of the non-canonical type.  We set a flag after
the canonical type is processed to ignore any type that is processed after.

refs #198
This commit is contained in:
Alex Lin 2016-03-10 10:42:59 -06:00
parent 0f76eec7a1
commit 1754995396
3 changed files with 49 additions and 4 deletions

View File

@ -37,6 +37,7 @@ FieldDescription::FieldDescription(
is_record(0) ,
is_static(0) ,
has_type(0) ,
has_dims(0) ,
num_dims(0) ,
array_sizes() {} ;
@ -385,6 +386,14 @@ bool FieldDescription::hasType() {
return has_type ;
}
void FieldDescription::setHasDims( bool yes_no ) {
has_dims = yes_no ;
}
bool FieldDescription::hasDims() {
return has_dims ;
}
unsigned int FieldDescription::getNumDims() {
return num_dims ;
}

View File

@ -77,6 +77,8 @@ class FieldDescription : public ConstructValues {
bool isVirtualInherited() ;
void setHasType( bool yes_no ) ;
bool hasType() ;
void setHasDims( bool yes_no ) ;
bool hasDims() ;
void setAccess( clang::AccessSpecifier in_val ) ;
clang::AccessSpecifier getAccess() ;
@ -158,6 +160,9 @@ class FieldDescription : public ConstructValues {
/** Have we resolved the type for this parameter? */
bool has_type ;
/** Have we resolved the dimensions for this parameter? */
bool has_dims ;
/** map of strings to io numbers. One copy for all fields */
static std::map<std::string , unsigned int> io_map ;

View File

@ -130,7 +130,9 @@ bool FieldVisitor::VisitBuiltinType(clang::BuiltinType *bt) {
bool FieldVisitor::VisitConstantArrayType(clang::ConstantArrayType *cat) {
//cat->dump() ; std::cout << std::endl ;
fdes->addArrayDim(cat->getSize().getZExtValue()) ;
if ( ! fdes->hasDims() ) {
fdes->addArrayDim(cat->getSize().getZExtValue()) ;
}
return true;
}
@ -209,16 +211,31 @@ bool FieldVisitor::VisitFieldDecl( clang::FieldDecl *field ) {
fdes->setBitFieldStart( 32 - (field_offset_bits % 32) - fdes->getBitFieldWidth()) ;
fdes->setBitFieldByteOffset((field_offset_bits / 32) * 4 ) ;
}
clang::QualType qt = field->getType() ;
// If the current type is not canonical because of typedefs, traverse the canonical type
if ( !qt.isCanonical() ) {
clang::QualType ct = qt.getCanonicalType() ;
TraverseType(ct) ;
// Traversing the canonical type will set the has_type flag. Set the has_dims flag too so
// when we continue parsing the AST and the non-canonical type, we don't double add dimensions.
fdes->setHasDims(true) ;
}
return true ;
}
bool FieldVisitor::VisitElaboratedType(clang::ElaboratedType *et) {
if ( debug_level >= 4 ) {
std::cout << "FieldVisitor VisitElaboratedType" << std::endl ;
}
//et->dump() ; std::cout << std::endl ;
return true ;
}
bool FieldVisitor::VisitPointerType(clang::PointerType *p) {
fdes->addArrayDim(-1) ;
if ( ! fdes->hasDims() ) {
fdes->addArrayDim(-1) ;
}
return true;
}
@ -244,8 +261,17 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
//std::cout << "hasNameForLinkage " << rt->getDecl()->hasNameForLinkage() << std::endl ;
if ( rt->getDecl()->hasNameForLinkage() ) {
if ( rt->getDecl()->getDeclName() ) {
//std::cout << "getDeclName " << rt->getDecl()->getDeclName().getAsString() << std::endl ;
fdes->setTypeName(rt->getDecl()->getQualifiedNameAsString()) ;
std::string type_name = rt->getDecl()->getQualifiedNameAsString() ;
// Handle the string class differently than regular records.
if ( ! type_name.compare("std::basic_string") || !type_name.compare("std::__1::basic_string")) {
fdes->setEnumString("TRICK_STRING") ;
fdes->setTypeName("std::string") ;
fdes->setHasType(true) ;
return true ;
} else {
//std::cout << "getDeclName " << type_name << std::endl ;
fdes->setTypeName(type_name) ;
}
} else {
//std::cout << "getTypedefNameForAnonDecl " << rt->getDecl()->getTypedefNameForAnonDecl() << std::endl ;
fdes->setTypeName(rt->getDecl()->getTypedefNameForAnonDecl()->getQualifiedNameAsString()) ;
@ -453,6 +479,11 @@ bool FieldVisitor::VisitTypedefType(clang::TypedefType *tt) {
fdes->setHasType(true) ;
} else if ( tt->isRecordType() ) {
if ( debug_level >= 4 ) {
std::cout << "FieldVisitor isRecordType" << std::endl ;
}
std::string type_name = tt->desugar().getAsString() ;
if ((pos = type_name.find("class ")) != std::string::npos ) {
type_name.erase(pos , 6) ;