Add -ffreestanding to suppress the implicit declaration of library builtins like printf and malloc. Fixes PR3586

llvm-svn: 64566
This commit is contained in:
Douglas Gregor 2009-02-14 20:49:29 +00:00
parent 6bae7a1b2a
commit 69c7951c8e
8 changed files with 65 additions and 37 deletions

View File

@ -208,6 +208,14 @@ InheritanceViewCls("cxx-inheritance-view",
llvm::cl::value_desc("class name"),
llvm::cl::desc("View C++ inheritance for a specified class"));
//===----------------------------------------------------------------------===//
// Builtin Options
//===----------------------------------------------------------------------===//
static llvm::cl::opt<bool>
Freestanding("ffreestanding",
llvm::cl::desc("Assert that the compiler takes place in a "
"freestanding environment"));
//===----------------------------------------------------------------------===//
// Analyzer Options.
//===----------------------------------------------------------------------===//
@ -636,6 +644,9 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
if (EnableBlocks.getPosition())
Options.Blocks = EnableBlocks;
if (Freestanding)
Options.Freestanding = 1;
// Override the default runtime if the user requested it.
if (NeXTRuntime)
Options.NeXTRuntime = 1;

View File

@ -65,6 +65,10 @@
// through an ellipsis
// FIXME: gcc has nonnull
#if defined(BUILTIN) && !defined(LIBBUILTIN)
# define LIBBUILTIN(ID, TYPE, ATTRS) BUILTIN(ID, TYPE, ATTRS)
#endif
// Standard libc/libm functions:
BUILTIN(__builtin_huge_val, "d", "nc")
BUILTIN(__builtin_huge_valf, "f", "nc")
@ -182,33 +186,34 @@ BUILTIN(__sync_val_compare_and_swap,"ii*ii", "n")
BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n")
// Builtin library functions
BUILTIN(alloca, "v*z", "f:stdlib.h:")
BUILTIN(calloc, "v*zz", "f:stdlib.h:")
BUILTIN(malloc, "v*z", "f:stdlib.h:")
BUILTIN(memcpy, "v*v*vC*z", "f:string.h:")
BUILTIN(memmove, "v*v*vC*z", "f:string.h:")
BUILTIN(memset, "v*v*iz", "f:string.h:")
BUILTIN(strcat, "c*c*cC*", "f:string.h:")
BUILTIN(strchr, "c*cC*i", "f:string.h:")
BUILTIN(strcpy, "c*c*cC*", "f:string.h:")
BUILTIN(strcspn, "zcC*cC*", "f:string.h:")
BUILTIN(strlen, "zcC*", "f:string.h:")
BUILTIN(strncat, "c*c*cC*z", "f:string.h:")
BUILTIN(strncpy, "c*c*cC*z", "f:string.h:")
BUILTIN(strpbrk, "c*cC*cC*", "f:string.h:")
BUILTIN(strrchr, "c*cC*i", "f:string.h:")
BUILTIN(strspn, "zcC*cC*", "f:string.h:")
BUILTIN(strstr, "c*cC*cC*", "f:string.h:")
BUILTIN(printf, "icC*.", "f:stdio.h:p:0:")
BUILTIN(fprintf, "iP*cC*.", "f:stdio.h:p:1:")
BUILTIN(snprintf, "ic*zcC*.", "f:stdio.h:p:2:")
BUILTIN(sprintf, "ic*cC*.", "f:stdio.h:p:1:")
BUILTIN(vprintf, "icC*a", "f:stdio.h:P:0:")
BUILTIN(vfprintf, "iP*cC*a", "f:stdio.h:P:1:")
BUILTIN(vsnprintf, "ic*zcC*a", "f:stdio.h:P:2:")
BUILTIN(vsprintf, "ic*cC*a", "f:stdio.h:P:1:")
LIBBUILTIN(alloca, "v*z", "f:stdlib.h:")
LIBBUILTIN(calloc, "v*zz", "f:stdlib.h:")
LIBBUILTIN(malloc, "v*z", "f:stdlib.h:")
LIBBUILTIN(memcpy, "v*v*vC*z", "f:string.h:")
LIBBUILTIN(memmove, "v*v*vC*z", "f:string.h:")
LIBBUILTIN(memset, "v*v*iz", "f:string.h:")
LIBBUILTIN(strcat, "c*c*cC*", "f:string.h:")
LIBBUILTIN(strchr, "c*cC*i", "f:string.h:")
LIBBUILTIN(strcpy, "c*c*cC*", "f:string.h:")
LIBBUILTIN(strcspn, "zcC*cC*", "f:string.h:")
LIBBUILTIN(strlen, "zcC*", "f:string.h:")
LIBBUILTIN(strncat, "c*c*cC*z", "f:string.h:")
LIBBUILTIN(strncpy, "c*c*cC*z", "f:string.h:")
LIBBUILTIN(strpbrk, "c*cC*cC*", "f:string.h:")
LIBBUILTIN(strrchr, "c*cC*i", "f:string.h:")
LIBBUILTIN(strspn, "zcC*cC*", "f:string.h:")
LIBBUILTIN(strstr, "c*cC*cC*", "f:string.h:")
LIBBUILTIN(printf, "icC*.", "f:stdio.h:p:0:")
LIBBUILTIN(fprintf, "iP*cC*.", "f:stdio.h:p:1:")
LIBBUILTIN(snprintf, "ic*zcC*.", "f:stdio.h:p:2:")
LIBBUILTIN(sprintf, "ic*cC*.", "f:stdio.h:p:1:")
LIBBUILTIN(vprintf, "icC*a", "f:stdio.h:P:0:")
LIBBUILTIN(vfprintf, "iP*cC*a", "f:stdio.h:P:1:")
LIBBUILTIN(vsnprintf, "ic*zcC*a", "f:stdio.h:P:2:")
LIBBUILTIN(vsprintf, "ic*cC*a", "f:stdio.h:P:1:")
// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
// target-specific builtins, perhaps? What about NSLog?
// target-specific builtins, perhaps?
#undef BUILTIN
#undef LIBBUILTIN

View File

@ -34,7 +34,8 @@ enum ID {
struct Info {
const char *Name, *Type, *Attributes;
bool Suppressed;
bool operator==(const Info &RHS) const {
return !strcmp(Name, RHS.Name) &&
!strcmp(Type, RHS.Type) &&
@ -54,7 +55,8 @@ public:
/// InitializeBuiltins - Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target);
void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target,
bool Freestanding = false);
/// Builtin::GetName - Return the identifier name for the specified builtin,
/// e.g. "__builtin_abs".

View File

@ -47,6 +47,7 @@ public:
unsigned Exceptions : 1; // Support exception handling.
unsigned NeXTRuntime : 1; // Use NeXT runtime.
unsigned Freestanding : 1; // Freestanding implementation
unsigned ThreadsafeStatics : 1; // Whether static initializers are protected
// by locks.
@ -68,7 +69,7 @@ public:
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0;
CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0;
Exceptions = NeXTRuntime = 0;
Exceptions = NeXTRuntime = Freestanding = 0;
LaxVectorConversions = 1;
// FIXME: The default should be 1.

View File

@ -39,7 +39,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
{
if (size_reserve > 0) Types.reserve(size_reserve);
InitBuiltinTypes();
BuiltinInfo.InitializeBuiltins(idents, Target);
BuiltinInfo.InitializeBuiltins(idents, Target, LangOpts.Freestanding);
TUDecl = TranslationUnitDecl::Create(*this);
}

View File

@ -19,8 +19,8 @@
using namespace clang;
static const Builtin::Info BuiltinInfo[] = {
{ "not a builtin function", 0, 0 },
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
{ "not a builtin function", 0, 0, false },
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, false },
#include "clang/AST/Builtins.def"
};
@ -36,17 +36,25 @@ const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
const TargetInfo &Target) {
const TargetInfo &Target,
bool Freestanding) {
// Step #1: mark all target-independent builtins with their ID's.
for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
if (!BuiltinInfo[i].Suppressed &&
(!Freestanding ||
!strchr(BuiltinInfo[i].Attributes, 'f')))
Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
// Step #2: Get target builtins.
Target.getTargetBuiltins(TSRecords, NumTSRecords);
// Step #3: Register target-specific builtins.
for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
if (!TSRecords[i].Suppressed &&
(!Freestanding ||
(BuiltinInfo[i].Attributes &&
!strchr(BuiltinInfo[i].Attributes, 'f'))))
Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
}
std::string Builtin::Context::getHeaderName(unsigned ID) const {

View File

@ -296,7 +296,7 @@ public:
};
const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, false },
#include "clang/AST/PPCBuiltins.def"
};
@ -438,7 +438,7 @@ public:
namespace {
// Namespace for x86 abstract base class
const Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, false },
#include "clang/AST/X86Builtins.def"
};

View File

@ -787,6 +787,7 @@ class OptionParser:
self.f_encodingOption = self.addOption(JoinedOption('-fencoding=', self.fGroup))
self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions', self.Clang_fGroup))
self.f_extdirsOption = self.addOption(JoinedOption('-fextdirs=', self.fGroup))
self.f_freestandingOption = self.addOption(FlagOption('-ffreestanding', self.Clang_fGroup))
self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime', self.Clang_fGroup))
self.f_indirectVirtualCallsOption = self.addOption(FlagOption('-findirect-virtual-calls', self.fGroup))
self.f_laxVectorConversionsOption = self.addOption(FlagOption('-flax-vector-conversions', self.Clang_fGroup))