forked from OSchip/llvm-project
Switched FormatAttr to using an IdentifierArgument instead of a StringArgument since that is a more accurate modeling.
llvm-svn: 189851
This commit is contained in:
parent
3c78578f33
commit
f58070baed
|
@ -382,7 +382,7 @@ def MinSize : InheritableAttr {
|
|||
|
||||
def Format : InheritableAttr {
|
||||
let Spellings = [GNU<"format">, CXX11<"gnu", "format">];
|
||||
let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
|
||||
let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
|
||||
IntArgument<"FirstArg">];
|
||||
}
|
||||
|
||||
|
|
|
@ -1840,9 +1840,9 @@ public:
|
|||
unsigned AttrSpellingListIndex);
|
||||
DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
|
||||
unsigned AttrSpellingListIndex);
|
||||
FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
|
||||
int FormatIdx, int FirstArg,
|
||||
unsigned AttrSpellingListIndex);
|
||||
FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range,
|
||||
IdentifierInfo *Format, int FormatIdx,
|
||||
int FirstArg, unsigned AttrSpellingListIndex);
|
||||
SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
|
||||
unsigned AttrSpellingListIndex);
|
||||
|
||||
|
|
|
@ -2141,7 +2141,7 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
|
|||
}
|
||||
|
||||
Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) {
|
||||
return llvm::StringSwitch<FormatStringType>(Format->getType())
|
||||
return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
|
||||
.Case("scanf", FST_Scanf)
|
||||
.Cases("printf", "printf0", FST_Printf)
|
||||
.Cases("NSString", "CFString", FST_NSString)
|
||||
|
|
|
@ -9755,7 +9755,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
|
|||
FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType())
|
||||
fmt = "NSString";
|
||||
FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
|
||||
fmt, FormatIdx+1,
|
||||
&Context.Idents.get(fmt),
|
||||
FormatIdx+1,
|
||||
HasVAListArg ? 0 : FormatIdx+2));
|
||||
}
|
||||
}
|
||||
|
@ -9763,7 +9764,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
|
|||
HasVAListArg)) {
|
||||
if (!FD->getAttr<FormatAttr>())
|
||||
FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
|
||||
"scanf", FormatIdx+1,
|
||||
&Context.Idents.get("scanf"),
|
||||
FormatIdx+1,
|
||||
HasVAListArg ? 0 : FormatIdx+2));
|
||||
}
|
||||
|
||||
|
@ -9803,7 +9805,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
|
|||
// target-specific builtins, perhaps?
|
||||
if (!FD->getAttr<FormatAttr>())
|
||||
FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
|
||||
"printf", 2,
|
||||
&Context.Idents.get("printf"), 2,
|
||||
Name->isStr("vasprintf") ? 0 : 3));
|
||||
}
|
||||
|
||||
|
|
|
@ -3177,8 +3177,9 @@ static void handleInitPriorityAttr(Sema &S, Decl *D,
|
|||
Attr.getAttributeSpellingListIndex()));
|
||||
}
|
||||
|
||||
FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
|
||||
int FormatIdx, int FirstArg,
|
||||
FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
|
||||
IdentifierInfo *Format, int FormatIdx,
|
||||
int FirstArg,
|
||||
unsigned AttrSpellingListIndex) {
|
||||
// Check whether we already have an equivalent format attribute.
|
||||
for (specific_attr_iterator<FormatAttr>
|
||||
|
@ -3197,8 +3198,8 @@ FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
|
|||
}
|
||||
}
|
||||
|
||||
return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, FirstArg,
|
||||
AttrSpellingListIndex);
|
||||
return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
|
||||
FirstArg, AttrSpellingListIndex);
|
||||
}
|
||||
|
||||
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
|
||||
|
@ -3229,8 +3230,11 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
|||
StringRef Format = II->getName();
|
||||
|
||||
// Normalize the argument, __foo__ becomes foo.
|
||||
if (Format.startswith("__") && Format.endswith("__"))
|
||||
if (Format.startswith("__") && Format.endswith("__")) {
|
||||
Format = Format.substr(2, Format.size() - 4);
|
||||
// If we've modified the string name, we need a new identifier for it.
|
||||
II = &S.Context.Idents.get(Format);
|
||||
}
|
||||
|
||||
// Check for supported formats.
|
||||
FormatAttrKind Kind = getFormatAttrKind(Format);
|
||||
|
@ -3336,7 +3340,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
|||
return;
|
||||
}
|
||||
|
||||
FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
|
||||
FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II,
|
||||
Idx.getZExtValue(),
|
||||
FirstArg.getZExtValue(),
|
||||
Attr.getAttributeSpellingListIndex());
|
||||
|
|
|
@ -619,7 +619,8 @@ static bool getPrintfFormatArgumentNum(const CallExpr *CE,
|
|||
|
||||
const FormatAttr *Format = *i;
|
||||
ArgNum = Format->getFormatIdx() - 1;
|
||||
if ((Format->getType() == "printf") && CE->getNumArgs() > ArgNum)
|
||||
if ((Format->getType()->getName() == "printf") &&
|
||||
CE->getNumArgs() > ArgNum)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ inline void f6() __attribute__((gnu_inline));
|
|||
inline void f7 [[gnu::gnu_inline]] ();
|
||||
|
||||
// arguments printing
|
||||
// CHECK: __attribute__((format("printf", 2, 3)));
|
||||
// CHECK: __attribute__((format(printf, 2, 3)));
|
||||
void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
// CHECK: int m __attribute__((aligned(4
|
||||
|
|
|
@ -1005,6 +1005,7 @@ void EmitClangAttrExprArgsList(RecordKeeper &Records, raw_ostream &OS) {
|
|||
.Case("DefaultIntArgument", true)
|
||||
.Case("IntArgument", true)
|
||||
.Case("ExprArgument", true)
|
||||
.Case("StringArgument", true)
|
||||
.Case("UnsignedArgument", true)
|
||||
.Case("VariadicUnsignedArgument", true)
|
||||
.Case("VariadicExprArgument", true)
|
||||
|
|
Loading…
Reference in New Issue