From 611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 17 Jul 2011 15:40:56 +0000 Subject: Vendor import of clang trunk r135360: http://llvm.org/svn/llvm-project/cfe/trunk@135360 --- lib/Frontend/InitPreprocessor.cpp | 170 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 162 insertions(+), 8 deletions(-) (limited to 'lib/Frontend/InitPreprocessor.cpp') diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 147a8df0..9428cd5 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -221,6 +221,125 @@ static void DefineExactWidthIntType(TargetInfo::IntType Ty, ConstSuffix); } +/// \brief Add definitions required for a smooth interaction between +/// Objective-C++ automatic reference counting and libc++. +static void AddObjCXXARCLibcxxDefines(const LangOptions &LangOpts, + MacroBuilder &Builder) { + Builder.defineMacro("_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF"); + + std::string Result; + { + // Provide overloads of the function std::__1::addressof() that accept + // references to lifetime-qualified objects. libc++'s (more general) + // std::__1::addressof() template fails to instantiate with such types, + // because it attempts to convert the object to a char& before + // dereferencing. + llvm::raw_string_ostream Out(Result); + + Out << "#pragma clang diagnostic push\n" + << "#pragma clang diagnostic ignored \"-Wc++0x-extensions\"\n" + << "namespace std { inline namespace __1 {\n" + << "\n"; + + Out << "template \n" + << "inline __attribute__ ((__visibility__(\"hidden\"), " + << "__always_inline__))\n" + << "__attribute__((objc_ownership(strong))) _Tp*\n" + << "addressof(__attribute__((objc_ownership(strong))) _Tp& __x) {\n" + << " return &__x;\n" + << "}\n" + << "\n"; + + if (LangOpts.ObjCRuntimeHasWeak) { + Out << "template \n" + << "inline __attribute__ ((__visibility__(\"hidden\")," + << "__always_inline__))\n" + << "__attribute__((objc_ownership(weak))) _Tp*\n" + << "addressof(__attribute__((objc_ownership(weak))) _Tp& __x) {\n" + << " return &__x;\n" + << "};\n" + << "\n"; + } + + Out << "template \n" + << "inline __attribute__ ((__visibility__(\"hidden\")," + << "__always_inline__))\n" + << "__attribute__((objc_ownership(autoreleasing))) _Tp*\n" + << "addressof(__attribute__((objc_ownership(autoreleasing))) _Tp& __x) " + << "{\n" + << " return &__x;\n" + << "}\n" + << "\n"; + + Out << "template \n" + << "inline __attribute__ ((__visibility__(\"hidden\"), " + << "__always_inline__))\n" + << "__unsafe_unretained _Tp* addressof(__unsafe_unretained _Tp& __x)" + << " {\n" + << " return &__x;\n" + << "}\n"; + + Out << "\n" + << "} }\n" + << "#pragma clang diagnostic pop\n" + << "\n"; + } + Builder.append(Result); +} + +/// \brief Add definitions required for a smooth interaction between +/// Objective-C++ automated reference counting and libstdc++ (4.2). +static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts, + MacroBuilder &Builder) { + Builder.defineMacro("_GLIBCXX_PREDEFINED_OBJC_ARC_IS_SCALAR"); + + std::string Result; + { + // Provide specializations for the __is_scalar type trait so that + // lifetime-qualified objects are not considered "scalar" types, which + // libstdc++ uses as an indicator of the presence of trivial copy, assign, + // default-construct, and destruct semantics (none of which hold for + // lifetime-qualified objects in ARC). + llvm::raw_string_ostream Out(Result); + + Out << "namespace std {\n" + << "\n" + << "struct __true_type;\n" + << "struct __false_type;\n" + << "\n"; + + Out << "template struct __is_scalar;\n" + << "\n"; + + Out << "template\n" + << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n" + << " enum { __value = 0 };\n" + << " typedef __false_type __type;\n" + << "};\n" + << "\n"; + + if (LangOpts.ObjCRuntimeHasWeak) { + Out << "template\n" + << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n" + << " enum { __value = 0 };\n" + << " typedef __false_type __type;\n" + << "};\n" + << "\n"; + } + + Out << "template\n" + << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))" + << " _Tp> {\n" + << " enum { __value = 0 };\n" + << " typedef __false_type __type;\n" + << "};\n" + << "\n"; + + Out << "}\n"; + } + Builder.append(Result); +} + static void InitializeStandardPredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, @@ -240,11 +359,18 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, } else { if (LangOpts.GNUMode) Builder.defineMacro("__cplusplus"); - else - // C++ [cpp.predefined]p1: + else { + // C++0x [cpp.predefined]p1: + // The name_ _cplusplus is defined to the value 201103L when compiling a + // C++ translation unit. + if (LangOpts.CPlusPlus0x) + Builder.defineMacro("__cplusplus", "201103L"); + // C++03 [cpp.predefined]p1: // The name_ _cplusplus is defined to the value 199711L when compiling a // C++ translation unit. - Builder.defineMacro("__cplusplus", "199711L"); + else + Builder.defineMacro("__cplusplus", "199711L"); + } } if (LangOpts.ObjC1) @@ -312,7 +438,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // darwin_constant_cfstrings controls this. This is also dependent // on other things like the runtime I believe. This is set even for C code. - Builder.defineMacro("__CONSTANT_CFSTRINGS__"); + if (!LangOpts.NoConstantCFStrings) + Builder.defineMacro("__CONSTANT_CFSTRINGS__"); if (LangOpts.ObjC2) Builder.defineMacro("OBJC_NEW_PROPERTIES"); @@ -487,6 +614,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.FastRelaxedMath) Builder.defineMacro("__FAST_RELAXED_MATH__"); + if (LangOpts.ObjCAutoRefCount) { + Builder.defineMacro("__weak", "__attribute__((objc_ownership(weak)))"); + Builder.defineMacro("__strong", "__attribute__((objc_ownership(strong)))"); + Builder.defineMacro("__autoreleasing", + "__attribute__((objc_ownership(autoreleasing)))"); + Builder.defineMacro("__unsafe_unretained", + "__attribute__((objc_ownership(none)))"); + } + // Get other target #defines. TI.getTargetDefines(LangOpts, Builder); } @@ -560,6 +696,7 @@ void clang::InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &InitOpts, const HeaderSearchOptions &HSOpts, const FrontendOptions &FEOpts) { + const LangOptions &LangOpts = PP.getLangOptions(); std::string PredefineBuffer; PredefineBuffer.reserve(4080); llvm::raw_string_ostream Predefines(PredefineBuffer); @@ -575,10 +712,27 @@ void clang::InitializePreprocessor(Preprocessor &PP, Builder.append("# 1 \"\" 3"); // Install things like __POWERPC__, __GNUC__, etc into the macro table. - if (InitOpts.UsePredefines) - InitializePredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(), - FEOpts, Builder); - + if (InitOpts.UsePredefines) { + InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts, Builder); + + // Install definitions to make Objective-C++ ARC work well with various + // C++ Standard Library implementations. + if (LangOpts.ObjC1 && LangOpts.CPlusPlus && LangOpts.ObjCAutoRefCount) { + switch (InitOpts.ObjCXXARCStandardLibrary) { + case ARCXX_nolib: + break; + + case ARCXX_libcxx: + AddObjCXXARCLibcxxDefines(LangOpts, Builder); + break; + + case ARCXX_libstdcxx: + AddObjCXXARCLibstdcxxDefines(LangOpts, Builder); + break; + } + } + } + // Even with predefines off, some macros are still predefined. // These should all be defined in the preprocessor according to the // current language configuration. -- cgit v1.1