Index: include/clang/Lex/Preprocessor.h =================================================================== --- include/clang/Lex/Preprocessor.h +++ include/clang/Lex/Preprocessor.h @@ -180,6 +180,31 @@ IdentifierInfo *Ident__is_target_os; // __is_target_os IdentifierInfo *Ident__is_target_environment; // __is_target_environment + // Fixed point macros (ISO/IEC JTC1 SC22 WG14 N1169) + // Fractional bits of _Accum types + IdentifierInfo *Ident__SACCUM_FBIT__; // __SACCUM_FBIT__ + IdentifierInfo *Ident__ACCUM_FBIT__; // __ACCUM_FBIT__ + IdentifierInfo *Ident__LACCUM_FBIT__; // __LACCUM_FBIT__ + IdentifierInfo *Ident__USACCUM_FBIT__; // __USACCUM_FBIT__ + IdentifierInfo *Ident__UACCUM_FBIT__; // __UACCUM_FBIT__ + IdentifierInfo *Ident__ULACCUM_FBIT__; // __ULACCUM_FBIT__ + + // Fractional bits of _Fract types + IdentifierInfo *Ident__SFRACT_FBIT__; // __SFRACT_FBIT__ + IdentifierInfo *Ident__FRACT_FBIT__; // __FRACT_FBIT__ + IdentifierInfo *Ident__LFRACT_FBIT__; // __LFRACT_FBIT__ + IdentifierInfo *Ident__USFRACT_FBIT__; // __USFRACT_FBIT__ + IdentifierInfo *Ident__UFRACT_FBIT__; // __UFRACT_FBIT__ + IdentifierInfo *Ident__ULFRACT_FBIT__; // __ULFRACT_FBIT__ + + // Integral bits of _Accum types + IdentifierInfo *Ident__SACCUM_IBIT__; // __SACCUM_IBIT__ + IdentifierInfo *Ident__ACCUM_IBIT__; // __ACCUM_IBIT__ + IdentifierInfo *Ident__LACCUM_IBIT__; // __LACCUM_IBIT__ + IdentifierInfo *Ident__USACCUM_IBIT__; // __USACCUM_IBIT__ + IdentifierInfo *Ident__UACCUM_IBIT__; // __UACCUM_IBIT__ + IdentifierInfo *Ident__ULACCUM_IBIT__; // __ULACCUM_IBIT__ + SourceLocation DATELoc, TIMELoc; // Next __COUNTER__ value, starts at 0. Index: lib/Lex/PPMacroExpansion.cpp =================================================================== --- lib/Lex/PPMacroExpansion.cpp +++ lib/Lex/PPMacroExpansion.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/Attributes.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/FixedPoint.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" @@ -355,6 +356,31 @@ Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__"); Ident__TIMESTAMP__ = RegisterBuiltinMacro(*this, "__TIMESTAMP__"); + // Fixed point macros (ISO/IEC JTC1 SC22 WG14 N1169) + // Fractional bits of _Accum types + Ident__SACCUM_FBIT__ = RegisterBuiltinMacro(*this, "__SACCUM_FBIT__"); + Ident__ACCUM_FBIT__ = RegisterBuiltinMacro(*this, "__ACCUM_FBIT__"); + Ident__LACCUM_FBIT__ = RegisterBuiltinMacro(*this, "__LACCUM_FBIT__"); + Ident__USACCUM_FBIT__ = RegisterBuiltinMacro(*this, "__USACCUM_FBIT__"); + Ident__UACCUM_FBIT__ = RegisterBuiltinMacro(*this, "__UACCUM_FBIT__"); + Ident__ULACCUM_FBIT__ = RegisterBuiltinMacro(*this, "__ULACCUM_FBIT__"); + + // Fractional bits of _Fract types + Ident__SFRACT_FBIT__ = RegisterBuiltinMacro(*this, "__SFRACT_FBIT__"); + Ident__FRACT_FBIT__ = RegisterBuiltinMacro(*this, "__FRACT_FBIT__"); + Ident__LFRACT_FBIT__ = RegisterBuiltinMacro(*this, "__LFRACT_FBIT__"); + Ident__USFRACT_FBIT__ = RegisterBuiltinMacro(*this, "__USFRACT_FBIT__"); + Ident__UFRACT_FBIT__ = RegisterBuiltinMacro(*this, "__UFRACT_FBIT__"); + Ident__ULFRACT_FBIT__ = RegisterBuiltinMacro(*this, "__ULFRACT_FBIT__"); + + // Integral bits of _Accum types + Ident__SACCUM_IBIT__ = RegisterBuiltinMacro(*this, "__SACCUM_IBIT__"); + Ident__ACCUM_IBIT__ = RegisterBuiltinMacro(*this, "__ACCUM_IBIT__"); + Ident__LACCUM_IBIT__ = RegisterBuiltinMacro(*this, "__LACCUM_IBIT__"); + Ident__USACCUM_IBIT__ = RegisterBuiltinMacro(*this, "__USACCUM_IBIT__"); + Ident__UACCUM_IBIT__ = RegisterBuiltinMacro(*this, "__UACCUM_IBIT__"); + Ident__ULACCUM_IBIT__ = RegisterBuiltinMacro(*this, "__ULACCUM_IBIT__"); + // Microsoft Extensions. if (LangOpts.MicrosoftExt) { Ident__identifier = RegisterBuiltinMacro(*this, "__identifier"); @@ -1696,6 +1722,68 @@ // __LINE__ expands to a simple numeric value. OS << (PLoc.isValid()? PLoc.getLine() : 1); Tok.setKind(tok::numeric_constant); + + // Fixed point macros + // Fractional bits of _Accum types + } else if (II == Ident__SACCUM_FBIT__) { + OS << BUILTIN_SACCUM_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__ACCUM_FBIT__) { + OS << BUILTIN_ACCUM_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__LACCUM_FBIT__) { + OS << BUILTIN_LACCUM_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__USACCUM_FBIT__) { + OS << BUILTIN_USACCUM_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__UACCUM_FBIT__) { + OS << BUILTIN_UACCUM_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__ULACCUM_FBIT__) { + OS << BUILTIN_ULACCUM_FBIT; + Tok.setKind(tok::numeric_constant); + + // Fractional bits of _Fract types + } else if (II == Ident__SFRACT_FBIT__) { + OS << BUILTIN_SFRACT_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__FRACT_FBIT__) { + OS << BUILTIN_FRACT_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__LFRACT_FBIT__) { + OS << BUILTIN_LFRACT_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__USFRACT_FBIT__) { + OS << BUILTIN_USFRACT_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__UFRACT_FBIT__) { + OS << BUILTIN_UFRACT_FBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__ULFRACT_FBIT__) { + OS << BUILTIN_ULFRACT_FBIT; + Tok.setKind(tok::numeric_constant); + + // Integral bits of _Accum types + } else if (II == Ident__SACCUM_IBIT__) { + OS << BUILTIN_SACCUM_IBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__ACCUM_IBIT__) { + OS << BUILTIN_ACCUM_IBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__LACCUM_IBIT__) { + OS << BUILTIN_LACCUM_IBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__USACCUM_IBIT__) { + OS << BUILTIN_USACCUM_IBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__UACCUM_IBIT__) { + OS << BUILTIN_UACCUM_IBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__ULACCUM_IBIT__) { + OS << BUILTIN_ULACCUM_IBIT; + Tok.setKind(tok::numeric_constant); + } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) { // C99 6.10.8: "__FILE__: The presumed name of the current source file (a // character string literal)". This can be affected by #line. Index: test/Frontend/fixed_point_builtin_macros.c =================================================================== --- /dev/null +++ test/Frontend/fixed_point_builtin_macros.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli + +#define assert(b) if (!(b)) { return 1; } + +int main() { + // Test using the recommended values for a typical desktop processor (Annex + // A.3). These are also the default values when building clang. + // Fractional bits of _Accum types + assert(__SACCUM_FBIT__ == 7); + assert(__ACCUM_FBIT__ == 15); + assert(__LACCUM_FBIT__ == 31); + assert(__USACCUM_FBIT__ == 8); + assert(__UACCUM_FBIT__ == 16); + assert(__ULACCUM_FBIT__ == 32); + + // Fractional bits of _Fract types + assert(__SFRACT_FBIT__ == 7); + assert(__FRACT_FBIT__ == 15); + assert(__LFRACT_FBIT__ == 31); + assert(__USFRACT_FBIT__ == 8); + assert(__UFRACT_FBIT__ == 16); + assert(__ULFRACT_FBIT__ == 32); + + // Integral bits of _Accum types + assert(__SACCUM_IBIT__ == 8); + assert(__ACCUM_IBIT__ == 16); + assert(__LACCUM_IBIT__ == 32); + assert(__USACCUM_IBIT__ == 8); + assert(__UACCUM_IBIT__ == 16); + assert(__ULACCUM_IBIT__ == 32); +}