diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-02-14 01:52:53 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-02-14 01:52:53 +0000 |
| commit | 538c3d845986a43014574d6a21a030281c266fdb (patch) | |
| tree | e304449e0a82e5dedd173f7d0bec8e9c618a6625 /clang/lib | |
| parent | e68c0fcfb239eef2c8468bb8c32e97fe9f58e7be (diff) | |
| download | bcm5719-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.cpp | 31 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 14 |
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) |

