[cfe-commits] r84390 - /cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Daniel Dunbar daniel at zuster.org
Sat Oct 17 19:09:17 PDT 2009


Author: ddunbar
Date: Sat Oct 17 21:09:17 2009
New Revision: 84390

URL: http://llvm.org/viewvc/llvm-project?rev=84390&view=rev
Log:
Simplify HandleFormatAttr.
 - I have this crazy dream that one day someone will invent a miraculous tool so
   that developers, instead of hand optimizing their source code to obscure its
   intent and decrease its maleability, will instead write what they mean, and
   this strange and wonderful tool -- which I imagine would be called something
   fancy sounding like "an optimizing compiler" -- will make their code fast
   *for* them. With all the saved time, developers could maybe even focus on
   making the magic "optimizing compiler" better!!

 - No intended functionality change, all though I expect the universe to mock me
   for snarkiness.

Modified:
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=84390&r1=84389&r2=84390&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sat Oct 17 21:09:17 2009
@@ -1202,6 +1202,35 @@
   d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
 }
 
+enum FormatAttrKind {
+  CFStringFormat,
+  NSStringFormat,
+  StrftimeFormat,
+  SupportedFormat,
+  InvalidFormat
+};
+
+/// getFormatAttrKind - Map from format attribute names to supported format
+/// types.
+static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
+  // Check for formats that get handled specially.
+  if (Format == "NSString")
+    return NSStringFormat;
+  if (Format == "CFString")
+    return CFStringFormat;
+  if (Format == "strftime")
+    return StrftimeFormat;
+
+  // Otherwise, check for supported formats.
+  if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
+      Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
+      Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
+      Format == "zcmn_err")
+    return SupportedFormat;
+
+  return InvalidFormat;
+}
+
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1226,40 +1255,17 @@
   unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
   unsigned FirstIdx = 1;
 
-  const char *Format = Attr.getParameterName()->getName();
-  unsigned FormatLen = Attr.getParameterName()->getLength();
+  llvm::StringRef Format = Attr.getParameterName()->getNameStr();
 
   // Normalize the argument, __foo__ becomes foo.
-  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
-      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
-    Format += 2;
-    FormatLen -= 4;
-  }
-
-  bool Supported = false;
-  bool is_NSString = false;
-  bool is_strftime = false;
-  bool is_CFString = false;
-
-  switch (FormatLen) {
-  default: break;
-  case 5: Supported = !memcmp(Format, "scanf", 5); break;
-  case 6: Supported = !memcmp(Format, "printf", 6); break;
-  case 7: Supported = !memcmp(Format, "printf0", 7) ||
-                      !memcmp(Format, "strfmon", 7) ||
-                      !memcmp(Format, "cmn_err", 7); break;
-  case 8:
-    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
-                (is_NSString = !memcmp(Format, "NSString", 8)) ||
-                !memcmp(Format, "vcmn_err", 8) ||
-                !memcmp(Format, "zcmn_err", 8) ||
-                (is_CFString = !memcmp(Format, "CFString", 8));
-    break;
-  }
+  if (Format.startswith("__") && Format.endswith("__"))
+    Format = Format.substr(2, Format.size() - 4);
 
-  if (!Supported) {
+  // Check for supported formats.
+  FormatAttrKind Kind = getFormatAttrKind(Format);
+  if (Kind == InvalidFormat) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
-      << "format" << Attr.getParameterName()->getName();
+      << "format" << Attr.getParameterName()->getNameStr();
     return;
   }
 
@@ -1296,13 +1302,13 @@
   // make sure the format string is really a string
   QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
 
-  if (is_CFString) {
+  if (Kind == CFStringFormat) {
     if (!isCFStringType(Ty, S.Context)) {
       S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
         << "a CFString" << IdxExpr->getSourceRange();
       return;
     }
-  } else if (is_NSString) {
+  } else if (Kind == NSStringFormat) {
     // FIXME: do we need to check if the type is NSString*?  What are the
     // semantics?
     if (!isNSStringType(Ty, S.Context)) {
@@ -1340,7 +1346,7 @@
 
   // strftime requires FirstArg to be 0 because it doesn't read from any
   // variable the input is just the current time + the format string.
-  if (is_strftime) {
+  if (Kind == StrftimeFormat) {
     if (FirstArg != 0) {
       S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
         << FirstArgExpr->getSourceRange();
@@ -1353,8 +1359,8 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
-                            Idx.getZExtValue(), FirstArg.getZExtValue()));
+  d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(),
+                                          FirstArg.getZExtValue()));
 }
 
 static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,





More information about the cfe-commits mailing list