diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
commit | 5563df30b9c8d1fe87a54baae0d6bd86642563f4 (patch) | |
tree | 3fdd91eae574e32453a4baf462961c742df2691a /lib/Sema/SemaDeclAttr.cpp | |
parent | e5557c18e5d41b4b62f2af8a24af20eba40b0225 (diff) | |
download | FreeBSD-src-5563df30b9c8d1fe87a54baae0d6bd86642563f4.zip FreeBSD-src-5563df30b9c8d1fe87a54baae0d6bd86642563f4.tar.gz |
Update clang to r84949.
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 50ebb49..341d49e 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1202,6 +1202,35 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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,38 +1255,15 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { unsigned NumArgs = getFunctionOrMethodNumArgs(d); unsigned FirstIdx = 1; - const char *Format = Attr.getParameterName()->getName(); - unsigned FormatLen = Attr.getParameterName()->getLength(); + llvm::StringRef Format = Attr.getParameterName()->getName(); // 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(); return; @@ -1296,13 +1302,13 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { // 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 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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, @@ -1496,20 +1502,17 @@ static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); return; } - const char *Str = Name->getName(); - unsigned Len = Name->getLength(); + + llvm::StringRef Str = Attr.getParameterName()->getName(); // Normalize the attribute name, __foo__ becomes foo. - if (Len > 4 && Str[0] == '_' && Str[1] == '_' && - Str[Len - 2] == '_' && Str[Len - 1] == '_') { - Str += 2; - Len -= 4; - } + if (Str.startswith("__") && Str.endswith("__")) + Str = Str.substr(2, Str.size() - 4); unsigned DestWidth = 0; bool IntegerMode = true; bool ComplexMode = false; - switch (Len) { + switch (Str.size()) { case 2: switch (Str[0]) { case 'Q': DestWidth = 8; break; @@ -1531,13 +1534,13 @@ static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { case 4: // FIXME: glibc uses 'word' to define register_t; this is narrower than a // pointer on PIC16 and other embedded platforms. - if (!memcmp(Str, "word", 4)) + if (Str == "word") DestWidth = S.Context.Target.getPointerWidth(0); - if (!memcmp(Str, "byte", 4)) + else if (Str == "byte") DestWidth = S.Context.Target.getCharWidth(); break; case 7: - if (!memcmp(Str, "pointer", 7)) + if (Str == "pointer") DestWidth = S.Context.Target.getPointerWidth(0); break; } |