summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Builtins.cpp35
-rw-r--r--clang/lib/Sema/Sema.cpp15
-rw-r--r--clang/lib/Sema/Sema.h12
-rw-r--r--clang/lib/Sema/SemaChecking.cpp52
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
5 files changed, 60 insertions, 56 deletions
diff --git a/clang/lib/AST/Builtins.cpp b/clang/lib/AST/Builtins.cpp
index b675c729738..e7ec1372a8e 100644
--- a/clang/lib/AST/Builtins.cpp
+++ b/clang/lib/AST/Builtins.cpp
@@ -49,6 +49,41 @@ void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
}
+std::string Builtin::Context::getHeaderName(unsigned ID) const {
+ char *Name = strchr(GetRecord(ID).Attributes, 'f');
+ if (!Name)
+ return 0;
+ ++Name;
+
+ if (*Name != ':')
+ return 0;
+
+ ++Name;
+ char *NameEnd = strchr(Name, ':');
+ assert(NameEnd && "Missing ':' after header name");
+ return std::string(Name, NameEnd);
+}
+
+bool
+Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
+ bool &HasVAListArg) {
+ char *Printf = strpbrk(GetRecord(ID).Attributes, "pP");
+ if (!Printf)
+ return false;
+
+ HasVAListArg = (*Printf == 'P');
+
+ ++Printf;
+ assert(*Printf == ':' && "p or P specifier must have be followed by a ':'");
+ ++Printf;
+
+ char *PrintfEnd = strchr(Printf, ':');
+ assert(PrintfEnd && "printf specifier must end with a ':'");
+
+ FormatIdx = strtol(Printf, 0, 10);
+ return true;
+}
+
/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
/// pointer over the consumed characters. This returns the resultant type.
static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 8667ee28e25..45ef03506f2 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -131,22 +131,11 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
// do extra checking.
IdentifierTable &IT = PP.getIdentifierTable();
- KnownFunctionIDs[id_printf] = &IT.get("printf");
- KnownFunctionIDs[id_fprintf] = &IT.get("fprintf");
- KnownFunctionIDs[id_sprintf] = &IT.get("sprintf");
- KnownFunctionIDs[id_sprintf_chk] = &IT.get("__builtin___sprintf_chk");
- KnownFunctionIDs[id_snprintf] = &IT.get("snprintf");
- KnownFunctionIDs[id_snprintf_chk] = &IT.get("__builtin___snprintf_chk");
- KnownFunctionIDs[id_asprintf] = &IT.get("asprintf");
KnownFunctionIDs[id_NSLog] = &IT.get("NSLog");
- KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf");
+ KnownFunctionIDs[id_asprintf] = &IT.get("asprintf");
+ KnownFunctionIDs[id_fprintf] = &IT.get("fprintf");
KnownFunctionIDs[id_vasprintf] = &IT.get("vasprintf");
KnownFunctionIDs[id_vfprintf] = &IT.get("vfprintf");
- KnownFunctionIDs[id_vsprintf] = &IT.get("vsprintf");
- KnownFunctionIDs[id_vsprintf_chk] = &IT.get("__builtin___vsprintf_chk");
- KnownFunctionIDs[id_vsnprintf] = &IT.get("vsnprintf");
- KnownFunctionIDs[id_vsnprintf_chk] = &IT.get("__builtin___vsnprintf_chk");
- KnownFunctionIDs[id_vprintf] = &IT.get("vprintf");
StdNamespace = 0;
TUScope = 0;
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index fdd4c304fb2..db0837710f6 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -183,18 +183,8 @@ public:
id_NSLog,
id_asprintf,
id_fprintf,
- id_printf,
- id_snprintf,
- id_snprintf_chk,
- id_sprintf,
- id_sprintf_chk,
id_vasprintf,
- id_vfprintf,
- id_vsnprintf,
- id_vsnprintf_chk,
- id_vsprintf,
- id_vsprintf_chk,
- id_vprintf,
+ id_vfprintf,
id_num_known_functions
};
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index e058861283f..ab712554965 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -77,40 +77,30 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
// more efficient. For example, just map function ids to custom
// handlers.
- // Search the KnownFunctionIDs for the identifier.
- unsigned i = 0, e = id_num_known_functions;
- for (; i != e; ++i) { if (KnownFunctionIDs[i] == FnInfo) break; }
- if (i == e) return move(TheCallResult);
-
// Printf checking.
- if (i <= id_vprintf) {
- // Retrieve the index of the format string parameter and determine
- // if the function is passed a va_arg argument.
- unsigned format_idx = 0;
- bool HasVAListArg = false;
-
- switch (i) {
- default: assert(false && "No format string argument index.");
- case id_NSLog: format_idx = 0; break;
- case id_asprintf: format_idx = 1; break;
- case id_fprintf: format_idx = 1; break;
- case id_printf: format_idx = 0; break;
- case id_snprintf: format_idx = 2; break;
- case id_snprintf_chk: format_idx = 4; break;
- case id_sprintf: format_idx = 1; break;
- case id_sprintf_chk: format_idx = 3; break;
- case id_vasprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vfprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vsnprintf: format_idx = 2; HasVAListArg = true; break;
- case id_vsnprintf_chk: format_idx = 4; HasVAListArg = true; break;
- case id_vsprintf: format_idx = 1; HasVAListArg = true; break;
- case id_vsprintf_chk: format_idx = 3; HasVAListArg = true; break;
- case id_vprintf: format_idx = 0; HasVAListArg = true; break;
- }
-
- CheckPrintfArguments(TheCall, HasVAListArg, format_idx);
+ unsigned format_idx = 0;
+ bool HasVAListArg = false;
+ if (FDecl->getBuiltinID() &&
+ Context.BuiltinInfo.isPrintfLike(FDecl->getBuiltinID(), format_idx,
+ HasVAListArg)) {
+ // Found a printf builtin.
+ } else if (FnInfo == KnownFunctionIDs[id_NSLog]) {
+ format_idx = 0;
+ HasVAListArg = false;
+ } else if (FnInfo == KnownFunctionIDs[id_asprintf] ||
+ FnInfo == KnownFunctionIDs[id_fprintf]) {
+ format_idx = 1;
+ HasVAListArg = false;
+ } else if (FnInfo == KnownFunctionIDs[id_vasprintf] ||
+ FnInfo == KnownFunctionIDs[id_vfprintf]) {
+ format_idx = 1;
+ HasVAListArg = true;
+ } else {
+ return move(TheCallResult);
}
+ CheckPrintfArguments(TheCall, HasVAListArg, format_idx);
+
return move(TheCallResult);
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d0997b03ebe..3c02d4b2946 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -304,7 +304,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
Diag(Loc, diag::ext_implicit_lib_function_decl)
<< Context.BuiltinInfo.GetName(BID)
<< R;
- if (Context.BuiltinInfo.getHeaderName(BID) &&
+ if (!Context.BuiltinInfo.getHeaderName(BID).empty() &&
Diags.getDiagnosticMapping(diag::ext_implicit_lib_function_decl)
!= diag::MAP_IGNORE)
Diag(Loc, diag::note_please_include_header)
OpenPOWER on IntegriCloud