llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty, llvm::DICompileUnit Unit) { EnumDecl *Decl = Ty->getDecl(); llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators; // Create DIEnumerator elements for each enumerator. for (EnumDecl::enumerator_iterator Enum = Decl->enumerator_begin(M->getContext()), EnumEnd = Decl->enumerator_end(M->getContext()); Enum != EnumEnd; ++Enum) { Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getNameAsString(), Enum->getInitVal().getZExtValue())); } // Return a CompositeType for the enum itself. llvm::DIArray EltArray = DebugFactory.GetOrCreateArray(&Enumerators[0], Enumerators.size()); std::string EnumName = Decl->getNameAsString(); SourceLocation DefLoc = Decl->getLocation(); llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc); SourceManager &SM = M->getContext().getSourceManager(); unsigned Line = SM.getInstantiationLineNumber(DefLoc); // Size and align of the type. uint64_t Size = M->getContext().getTypeSize(Ty); unsigned Align = M->getContext().getTypeAlign(Ty); return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type, Unit, EnumName, DefUnit, Line, Size, Align, 0, 0, llvm::DIType(), EltArray); }
void FindBadConstructsConsumer::CheckChromeEnum(SourceLocation enum_location, EnumDecl* enum_decl) { if (!options_.check_enum_last_value) return; bool got_one = false; bool is_signed = false; llvm::APSInt max_so_far; EnumDecl::enumerator_iterator iter; for (iter = enum_decl->enumerator_begin(); iter != enum_decl->enumerator_end(); ++iter) { llvm::APSInt current_value = iter->getInitVal(); if (!got_one) { max_so_far = current_value; is_signed = current_value.isSigned(); got_one = true; } else { if (is_signed != current_value.isSigned()) { // This only happens in some cases when compiling C (not C++) files, // so it is OK to bail out here. return; } if (current_value > max_so_far) max_so_far = current_value; } } for (iter = enum_decl->enumerator_begin(); iter != enum_decl->enumerator_end(); ++iter) { std::string name = iter->getNameAsString(); if (((name.size() > 4 && name.compare(name.size() - 4, 4, "Last") == 0) || (name.size() > 5 && name.compare(name.size() - 5, 5, "_LAST") == 0)) && iter->getInitVal() < max_so_far) { diagnostic().Report(iter->getLocation(), diag_bad_enum_last_value_); } } }