diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 1bc296babd3b..ae5246d7929a 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -130,6 +130,9 @@ def warn_pch_compiler_options_mismatch : Error< def warn_pch_access_control : Error< "C++ access control was %select{disabled|enabled}0 in the PCH file but " "is currently %select{disabled|enabled}1">; +def warn_pch_char_signed : Error< + "char was %select{unsigned|signed}0 in the PCH file but " + "is currently %select{unsigned|signed}1">; def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 92370cdd9efc..7c578e32f814 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -79,6 +79,7 @@ public: unsigned AccessControl : 1; // Whether C++ access control should // be enabled. + unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type private: unsigned GC : 2; // Objective-C Garbage Collection modes. We declare // this enum as unsigned because MSVC insists on making enums @@ -137,6 +138,8 @@ public: GNUInline = 0; NoInline = 0; + CharIsSigned = 1; + MainFileName = 0; } diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index f577d6b32287..a59c60b00224 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -38,7 +38,6 @@ class TargetInfo { protected: // Target values set by the ctor of the actual target implementation. Default // values are specified by the TargetInfo constructor. - bool CharIsSigned; bool TLSSupported; unsigned char PointerWidth, PointerAlign; unsigned char WCharWidth, WCharAlign; @@ -88,11 +87,6 @@ public: IntType getIntPtrType() const { return IntPtrType; } IntType getWCharType() const { return WCharType; } - /// isCharSigned - Return true if 'char' is 'signed char' or false if it is - /// treated as 'unsigned char'. This is implementation defined according to - /// C99 6.2.5p15. In our implementation, this is target-specific. - bool isCharSigned() const { return CharIsSigned; } - /// getPointerWidth - Return the width of pointers on this target, for the /// specified address space. uint64_t getPointerWidth(unsigned AddrSpace) const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1d2ddbd12882..e6dea7cca955 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -143,7 +143,7 @@ void ASTContext::InitBuiltinTypes() { // C99 6.2.5p2. InitBuiltinType(BoolTy, BuiltinType::Bool); // C99 6.2.5p3. - if (Target.isCharSigned()) + if (LangOpts.CharIsSigned) InitBuiltinType(CharTy, BuiltinType::Char_S); else InitBuiltinType(CharTy, BuiltinType::Char_U); diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 1e8ca2bd56c4..a513cb16886e 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -22,7 +22,6 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, // like PPC or SPARC. // These should be overridden by concrete targets as needed. - CharIsSigned = true; TLSSupported = true; PointerWidth = PointerAlign = 32; WCharWidth = WCharAlign = 32; diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 9e4f29ea9d72..120d52543c0c 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -257,9 +257,8 @@ class PPCTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; public: - PPCTargetInfo(const std::string& triple) : TargetInfo(triple) { - CharIsSigned = false; - } + PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {} + virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { Records = BuiltinInfo; @@ -299,6 +298,10 @@ public: return true; } } + virtual void getDefaultLangOptions(LangOptions &Opts) { + TargetInfo::getDefaultLangOptions(Opts); + Opts.CharIsSigned = false; + } virtual const char *getClobbers() const { return ""; } @@ -449,6 +452,7 @@ public: /// various language options. These may be overridden by command line /// options. virtual void getDefaultLangOptions(LangOptions &Opts) { + PPC32TargetInfo::getDefaultLangOptions(Opts); GetDarwinLanguageOptions(Opts, getTargetTriple()); } }; @@ -469,6 +473,7 @@ public: /// various language options. These may be overridden by command line /// options. virtual void getDefaultLangOptions(LangOptions &Opts) { + PPC64TargetInfo::getDefaultLangOptions(Opts); GetDarwinLanguageOptions(Opts, getTargetTriple()); } }; @@ -845,6 +850,7 @@ public: /// various language options. These may be overridden by command line /// options. virtual void getDefaultLangOptions(LangOptions &Opts) { + X86_32TargetInfo::getDefaultLangOptions(Opts); GetDarwinLanguageOptions(Opts, getTargetTriple()); } }; diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 64c81b8e373b..01729fad5e72 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -367,7 +367,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, sprintf(MacroBuf, "__POINTER_WIDTH__=%d", (int)TI.getPointerWidth(0)); DefineBuiltinMacro(Buf, MacroBuf); - if (!TI.isCharSigned()) + if (!LangOpts.CharIsSigned) DefineBuiltinMacro(Buf, "__CHAR_UNSIGNED__"); // Define fixed-sized integer types for stdint.h diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 63e4337c8861..87fc8394c8db 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -1521,6 +1521,7 @@ bool PCHReader::ParseLanguageOptions( PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline); PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline); PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control); + PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed); if ((LangOpts.getGCMode() != 0) != (Record[Idx] != 0)) { Diag(diag::warn_pch_gc_mode) << (unsigned)Record[Idx] << LangOpts.getGCMode(); diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 80e863bd7110..765fecbf852f 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -556,6 +556,8 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined. Record.push_back(LangOpts.AccessControl); // Whether C++ access control should // be enabled. + Record.push_back(LangOpts.CharIsSigned); // Whether char is a signed or + // unsigned type Record.push_back(LangOpts.getGCMode()); Record.push_back(LangOpts.getVisibilityMode()); Record.push_back(LangOpts.InstantiationDepth); diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 0324c0b01289..4d10974df2c6 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -691,7 +691,7 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end, // character constants are not sign extended in the this implementation: // '\xFF\xFF' = 65536 and '\x0\xFF' = 255, which matches GCC. if (!IsWide && NumCharsSoFar == 1 && (Value & 128) && - PP.getTargetInfo().isCharSigned()) + PP.getLangOptions().CharIsSigned) Value = (signed char)Value; } diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 709e316b8036..c98acc4deb35 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -232,7 +232,7 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // Set the value. Val = Literal.getValue(); // Set the signedness. - Val.setIsUnsigned(!TI.isCharSigned()); + Val.setIsUnsigned(!PP.getLangOptions().CharIsSigned); if (Result.Val.getBitWidth() > Val.getBitWidth()) { Result.Val = Val.extend(Result.Val.getBitWidth());