diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 1452a61a21c7..2f7ce69ee391 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -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 +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; diff --git a/clang/include/clang/AST/Builtins.def b/clang/include/clang/AST/Builtins.def index 3cfe2d340f26..ed658b8d0229 100644 --- a/clang/include/clang/AST/Builtins.def +++ b/clang/include/clang/AST/Builtins.def @@ -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 diff --git a/clang/include/clang/AST/Builtins.h b/clang/include/clang/AST/Builtins.h index 6fbd16624abf..dfc44c50cd2c 100644 --- a/clang/include/clang/AST/Builtins.h +++ b/clang/include/clang/AST/Builtins.h @@ -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". diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 96c79aa8aa4a..12fffb332d4d 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -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. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 652fcdf8080c..f724524f028a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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); } diff --git a/clang/lib/AST/Builtins.cpp b/clang/lib/AST/Builtins.cpp index 92b05975f552..cf2954de2f6f 100644 --- a/clang/lib/AST/Builtins.cpp +++ b/clang/lib/AST/Builtins.cpp @@ -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 { diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index ad7d6d579743..3e724eb39693 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -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" }; diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 18fe9fadda3c..2e4c2064ead5 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -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))