예제 #1
0
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_);
    }
  }
}
예제 #3
0
bool EnumVisitor::VisitEnumDecl(EnumDecl *ED) {

  if (ED->hasAttr<FFIBindingAttr>()) {

    if (FFIBindingsUtils::getInstance()->isOnBlacklist("enum " +
                                                       ED->getNameAsString()) ||
        FFIBindingsUtils::getInstance()->isInResolvedDecls(
            "enum " + ED->getNameAsString())) {
      return true;
    }
    std::string EnumDeclaration;
    std::vector<std::string> elements;

    EnumDeclaration = "enum " + ED->getNameAsString() + " {";

    int length = 0;
    for (EnumDecl::enumerator_iterator EI = ED->enumerator_begin();
         EI != ED->enumerator_end(); ++EI) {
      elements.push_back(EI->getNameAsString());
      length++;
    }

    for (int i = 0; i < length; i++) {
      if (i < length - 1) {
        EnumDeclaration += elements[i] + ", ";
      } else {
        EnumDeclaration += elements[i] + "};\n";
      }
    }

    (*output) << EnumDeclaration; // print the enumeration
    (*output) << "\n";
    FFIBindingsUtils::getInstance()->getResolvedDecls()->insert(
        "enum " + ED->getNameAsString());
  }
  return true;
}