summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-14 01:52:53 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-14 01:52:53 +0000
commit538c3d845986a43014574d6a21a030281c266fdb (patch)
treee304449e0a82e5dedd173f7d0bec8e9c618a6625 /clang/lib
parente68c0fcfb239eef2c8468bb8c32e97fe9f58e7be (diff)
downloadbcm5719-llvm-538c3d845986a43014574d6a21a030281c266fdb.tar.gz
bcm5719-llvm-538c3d845986a43014574d6a21a030281c266fdb.zip
Make it possible for builtins to expression FILE* arguments, so that
we can define builtins such as fprintf, vfprintf, and __builtin___fprintf_chk. Give a nice error message when we need to implicitly declare a function like fprintf. llvm-svn: 64526
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Builtins.cpp31
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp5
-rw-r--r--clang/lib/Sema/Sema.cpp2
-rw-r--r--clang/lib/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/SemaChecking.cpp6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp14
6 files changed, 44 insertions, 16 deletions
diff --git a/clang/lib/AST/Builtins.cpp b/clang/lib/AST/Builtins.cpp
index e7ec1372a8e..e345898b79c 100644
--- a/clang/lib/AST/Builtins.cpp
+++ b/clang/lib/AST/Builtins.cpp
@@ -87,6 +87,7 @@ Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
/// 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,
+ Builtin::Context::GetBuiltinTypeError &Error,
bool AllowTypeModifiers = true) {
// Modifiers.
bool Long = false, LongLong = false, Signed = false, Unsigned = false;
@@ -202,10 +203,23 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
Str = End;
- QualType ElementType = DecodeTypeFromStr(Str, Context, false);
+ QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false);
Type = Context.getVectorType(ElementType, NumElements);
break;
}
+ case 'P': {
+ IdentifierInfo *II = &Context.Idents.get("FILE");
+ DeclContext::lookup_result Lookup
+ = Context.getTranslationUnitDecl()->lookup(II);
+ if (Lookup.first != Lookup.second && isa<TypeDecl>(*Lookup.first)) {
+ Type = Context.getTypeDeclType(cast<TypeDecl>(*Lookup.first));
+ break;
+ }
+ else {
+ Error = Builtin::Context::GE_Missing_FILE;
+ return QualType();
+ }
+ }
}
if (!AllowTypeModifiers)
@@ -231,16 +245,21 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
}
/// GetBuiltinType - Return the type for the specified builtin.
-QualType Builtin::Context::GetBuiltinType(unsigned id,
- ASTContext &Context) const {
+QualType Builtin::Context::GetBuiltinType(unsigned id, ASTContext &Context,
+ GetBuiltinTypeError &Error) const {
const char *TypeStr = GetRecord(id).Type;
llvm::SmallVector<QualType, 8> ArgTypes;
- QualType ResType = DecodeTypeFromStr(TypeStr, Context);
+ Error = GE_None;
+ QualType ResType = DecodeTypeFromStr(TypeStr, Context, Error);
+ if (Error != GE_None)
+ return QualType();
while (TypeStr[0] && TypeStr[0] != '.') {
- QualType Ty = DecodeTypeFromStr(TypeStr, Context);
-
+ QualType Ty = DecodeTypeFromStr(TypeStr, Context, Error);
+ if (Error != GE_None)
+ return QualType();
+
// Do array -> pointer decay. The builtin should use the decayed type.
if (Ty->isArrayType())
Ty = Context.getArrayDecayedType(Ty);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 03de730f655..ba77e44288c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -852,7 +852,10 @@ llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
Name += 10;
// Get the type for the builtin.
- QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context);
+ Builtin::Context::GetBuiltinTypeError Error;
+ QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context, Error);
+ assert(Error == Builtin::Context::GE_None && "Can't get builtin type");
+
const llvm::FunctionType *Ty =
cast<llvm::FunctionType>(getTypes().ConvertType(Type));
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 45ef03506f2..4666250c4a7 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -133,9 +133,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
KnownFunctionIDs[id_NSLog] = &IT.get("NSLog");
KnownFunctionIDs[id_asprintf] = &IT.get("asprintf");
- KnownFunctionIDs[id_fprintf] = &IT.get("fprintf");
KnownFunctionIDs[id_vasprintf] = &IT.get("vasprintf");
- KnownFunctionIDs[id_vfprintf] = &IT.get("vfprintf");
StdNamespace = 0;
TUScope = 0;
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index db0837710f6..f202ad409a1 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -182,9 +182,7 @@ public:
enum {
id_NSLog,
id_asprintf,
- id_fprintf,
id_vasprintf,
- id_vfprintf,
id_num_known_functions
};
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index ab712554965..7ecc304fc90 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -87,12 +87,10 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
} else if (FnInfo == KnownFunctionIDs[id_NSLog]) {
format_idx = 0;
HasVAListArg = false;
- } else if (FnInfo == KnownFunctionIDs[id_asprintf] ||
- FnInfo == KnownFunctionIDs[id_fprintf]) {
+ } else if (FnInfo == KnownFunctionIDs[id_asprintf]) {
format_idx = 1;
HasVAListArg = false;
- } else if (FnInfo == KnownFunctionIDs[id_vasprintf] ||
- FnInfo == KnownFunctionIDs[id_vfprintf]) {
+ } else if (FnInfo == KnownFunctionIDs[id_vasprintf]) {
format_idx = 1;
HasVAListArg = true;
} else {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3c02d4b2946..16e8691f10b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -298,7 +298,19 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
if (Context.BuiltinInfo.hasVAListUse(BID))
InitBuiltinVaListType();
- QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
+ Builtin::Context::GetBuiltinTypeError Error;
+ QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context, Error);
+ switch (Error) {
+ case Builtin::Context::GE_None:
+ // Okay
+ break;
+
+ case Builtin::Context::GE_Missing_FILE:
+ if (ForRedeclaration)
+ Diag(Loc, diag::err_implicit_decl_requires_stdio)
+ << Context.BuiltinInfo.GetName(BID);
+ return 0;
+ }
if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
Diag(Loc, diag::ext_implicit_lib_function_decl)
OpenPOWER on IntegriCloud