Best approach for duplicate case value error

Over the weekend, I took a look at an easy diagnostic bug. (http://llvm.org/bugs/show_bug.cgi?id=9243) Essentially, the issue comes down to how to report duplicate case values when some of the values are enums or chars. As shown today, we show the actual integer value of the case value. This is sometimes confusing.

My proposed syntax for the revised error is:
CGDecl.cpp:85:8: error: duplicate case for 'Decl::Label' (underlying value '6')
   case Decl::label: // __label__ x;
        ^
CGDecl.cpp:73:8: note: previous case defined here
   case Decl::label:

After some digging around, I couldn't find a way to get the actual text of a given source range. Is there an easy way (within Sema) to get this? I tried playing tricks with looking up enum values from the underlying integer, but that has edge cases I wouldn't want to actually check in.

The second question I had was whether we should add a warning for the use of non-enum labels when switching on an enum value. While this is certainly valid C/C++, it's probably not best practice. Are best practice style warnings something we want to include? Or is that better off in a separate tool?

Yours,
Philip Reames

Here's the c++ test case I've been using.

enum Foo {A=0,B};

int main() {
   Foo a = A;
   switch(a) {
   case A:
     break;
   };

   switch(a) {
   case A:
   case 0:
     break;
   };

   switch(a) {
   case 0:
   case 1:
     break;
   };

   switch(a) {
   case A:
   case '\0':
     break;
   };

   char b = '0';
   switch(b) {
   case 'a':
     break;
   };

#define CASE1 case 'a':
   switch(b) {
   CASE1
     break;
   };

   return 0;
}

this is what I’ve been using to dump a SourceRange:

void DumpSourceRange(SourceRange sr, SourceManager& sm) {
const char* b = sm.getCharacterData(sr.getBegin());
const char* e = sm.getCharacterData(sr.getEnd())+1; // include last character
llvm::errs() << llvm::StringRef(b, e - b) << “\n”;
}

I don’t think there’s a “Right way” to do it. If there were it would probably be a method on SourceManager though.

–Sean Silva