]> granicus.if.org Git - clang/commitdiff
Add position of conversion specifier character to 'ConversionSpecifier'.
authorTed Kremenek <kremenek@apple.com>
Thu, 28 Jan 2010 02:46:17 +0000 (02:46 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 28 Jan 2010 02:46:17 +0000 (02:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94739 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/Analyses/PrintfFormatString.h
lib/Analysis/PrintfFormatString.cpp

index d8630e8edb52f5566ac69ed6212d229c3bb62296..45d1055be66e8958f9f1d531f1c2fcb58d655503 100644 (file)
@@ -59,7 +59,15 @@ public:
    ObjCEnd = ObjCObjArg
   };
 
-  ConversionSpecifier(Kind k) : kind(k) {}
+  ConversionSpecifier()
+    : Position(0), kind(InvalidSpecifier) {}
+
+  ConversionSpecifier(const char *pos, Kind k)
+    : Position(pos), kind(k) {}
+
+  const char *getConversionStart() const {
+    return Position;
+  }
   
   bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
   bool isIntArg() const { return kind >= dArg && kind <= iArg; }
@@ -68,7 +76,8 @@ public:
   Kind getKind() const { return kind; }
   
 private:
-  const Kind kind;
+  const char *Position;
+  Kind kind;
 };
 
 enum LengthModifier {
@@ -115,19 +124,19 @@ private:
 };
 
 class FormatSpecifier {
-  unsigned conversionSpecifier : 6;
   unsigned lengthModifier : 5;
   unsigned flags : 5;
+  ConversionSpecifier conversionSpecifier;
   OptionalAmount FieldWidth;
   OptionalAmount Precision;
 public:
-  FormatSpecifier() : conversionSpecifier(0), lengthModifier(0), flags(0) {}
+  FormatSpecifier() : lengthModifier(0), flags(0) {}
   
   static FormatSpecifier Parse(const char *beg, const char *end);
 
   // Methods for incrementally constructing the FormatSpecifier.
-  void setConversionSpecifier(ConversionSpecifier cs) {
-    conversionSpecifier = (unsigned) cs.getKind();
+  void setConversionSpecifier(const ConversionSpecifier &CS) {
+    conversionSpecifier = CS;    
   }
   void setLengthModifier(LengthModifier lm) {
     lengthModifier = (unsigned) lm;
@@ -140,8 +149,8 @@ public:
 
   // Methods for querying the format specifier.
 
-  ConversionSpecifier getConversionSpecifier() const {
-    return (ConversionSpecifier::Kind) conversionSpecifier;
+  const ConversionSpecifier &getConversionSpecifier() const {
+    return conversionSpecifier;
   }
 
   LengthModifier getLengthModifier() const {
@@ -187,7 +196,9 @@ public:
   
   virtual bool HandleFormatSpecifier(const FormatSpecifier &FS,
                                      const char *startSpecifier,
-                                     const char *endSpecifier) { return false; }
+                                     unsigned specifierLen) {
+    return true;
+  }
 };
   
 bool ParseFormatString(FormatStringHandler &H,
index 81752e9c4c349db8af478d1112fa5e78600f2dad..544956ac411b265e239e87c0e311d7f6545a1f2c 100644 (file)
@@ -189,39 +189,42 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H,
   }
   
   // Finally, look for the conversion specifier.
-  ConversionSpecifier::Kind cs;
-  switch (*I) {
+  const char *conversionPosition = I++;
+  ConversionSpecifier::Kind k;
+  switch (*conversionPosition) {
     default:
-      H.HandleInvalidConversionSpecifier(I);
+      H.HandleInvalidConversionSpecifier(conversionPosition);
       return true;      
     // C99: 7.19.6.1 (section 8).
-    case 'd': cs = ConversionSpecifier::dArg; break;
-    case 'i': cs = ConversionSpecifier::iArg; break;
-    case 'o': cs = ConversionSpecifier::oArg; break;
-    case 'u': cs = ConversionSpecifier::uArg; break;
-    case 'x': cs = ConversionSpecifier::xArg; break;
-    case 'X': cs = ConversionSpecifier::XArg; break;
-    case 'f': cs = ConversionSpecifier::fArg; break;
-    case 'F': cs = ConversionSpecifier::FArg; break;
-    case 'e': cs = ConversionSpecifier::eArg; break;
-    case 'E': cs = ConversionSpecifier::EArg; break;
-    case 'g': cs = ConversionSpecifier::gArg; break;
-    case 'G': cs = ConversionSpecifier::GArg; break;
-    case 'a': cs = ConversionSpecifier::aArg; break;
-    case 'A': cs = ConversionSpecifier::AArg; break;
-    case 'c': cs = ConversionSpecifier::IntAsCharArg; break;
-    case 's': cs = ConversionSpecifier::CStrArg;      break;
-    case 'p': cs = ConversionSpecifier::VoidPtrArg;   break;
-    case 'n': cs = ConversionSpecifier::OutIntPtrArg; break;
-    case '%': cs = ConversionSpecifier::PercentArg;   break;      
+    case 'd': k = ConversionSpecifier::dArg; break;
+    case 'i': k = ConversionSpecifier::iArg; break;
+    case 'o': k = ConversionSpecifier::oArg; break;
+    case 'u': k = ConversionSpecifier::uArg; break;
+    case 'x': k = ConversionSpecifier::xArg; break;
+    case 'X': k = ConversionSpecifier::XArg; break;
+    case 'f': k = ConversionSpecifier::fArg; break;
+    case 'F': k = ConversionSpecifier::FArg; break;
+    case 'e': k = ConversionSpecifier::eArg; break;
+    case 'E': k = ConversionSpecifier::EArg; break;
+    case 'g': k = ConversionSpecifier::gArg; break;
+    case 'G': k = ConversionSpecifier::GArg; break;
+    case 'a': k = ConversionSpecifier::aArg; break;
+    case 'A': k = ConversionSpecifier::AArg; break;
+    case 'c': k = ConversionSpecifier::IntAsCharArg; break;
+    case 's': k = ConversionSpecifier::CStrArg;      break;
+    case 'p': k = ConversionSpecifier::VoidPtrArg;   break;
+    case 'n': k = ConversionSpecifier::OutIntPtrArg; break;
+    case '%': k = ConversionSpecifier::PercentArg;   break;      
     // Objective-C.
-    case '@': cs = ConversionSpecifier::ObjCObjArg; break;      
+    case '@': k = ConversionSpecifier::ObjCObjArg; break;      
   }
-  FS.setConversionSpecifier(cs);
+  FS.setConversionSpecifier(ConversionSpecifier(conversionPosition, k));
   return FormatSpecifierResult(Start, FS);
 }
 
-bool ParseFormatSring(FormatStringHandler &H, const char *I, const char *E) {
+namespace clang { namespace analyze_printf {
+bool ParseFormatString(FormatStringHandler &H,
+                       const char *I, const char *E) {
   // Keep looking for a format specifier until we have exhausted the string.
   while (I != E) {
     const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E);
@@ -233,11 +236,13 @@ bool ParseFormatSring(FormatStringHandler &H, const char *I, const char *E) {
     if (!FSR.hasValue())
       break;    
     // We have a format specifier.  Pass it to the callback.
-    if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(), I))
+    if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(),
+                                 I - FSR.getStart()))
       return false;
   }  
   assert(I == E && "Format string not exhausted");      
   return false;
 }
+}}
 
 FormatStringHandler::~FormatStringHandler() {}