//===---------------------------------------------------------------------===// // Random Notes //===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===// Extensions: * "#define_target X Y" This preprocessor directive works exactly the same was as #define, but it notes that 'X' is a target-specific preprocessor directive. When used, a diagnostic is emitted indicating that the translation unit is non-portable. If a target-define is #undef'd before use, no diagnostic is emitted. If 'X' were previously a normal #define macro, the macro is tainted. If 'X' is subsequently #defined as a non-target-specific define, the taint bit is cleared. * "#define_other_target X" The preprocessor directive takes a single identifier argument. It notes that this identifier is a target-specific #define for some target other than the current one. Use of this identifier will result in a diagnostic. If 'X' is later #undef'd or #define'd, the taint bit is cleared. If 'X' is already defined, X is marked as a target-specific define. //===---------------------------------------------------------------------===// To time GCC preprocessing speed without output, use: "time gcc -MM file" This is similar to -Eonly. //===---------------------------------------------------------------------===// Interesting fact: clang -Eonly INPUTS/carbon-header-C-E.c is much faster than: wc -w INPUTS/carbon-header-C-E.c !! //===---------------------------------------------------------------------===// The 'portability' model in clang is sufficient to catch translation units (or their parts) that are not portable, but it doesn't help if the system headers are non-portable and not fixed. An alternative model that would be easy to use is a 'tainting' scheme. Consider: inline int foo() { #ifdef __i386__ return 1; #else return 2; #endif } It would be trivial to mark 'foo' as being non-portable (tainted) instead of marking the entire translation unit. Then, if foo is never called/used by the current translation unit, the t-u wouldn't be marked non-portable. However, there is no good way to handle stuff like: extern int X, Y; #ifndef __POWERPC__ #define X Y #endif int bar() { return X; } When compiling for powerpc, the #define is skipped, so it doesn't know that bar uses a #define that is set on some other target. In practice, limited cases could be handled by scanning the skipped region of a #if, but the fully general case cannot be implemented efficiently. We probably have to do something like this in the future. The C++ header contains a lot of code like this: static const int digits10 = __LDBL_DIG__; static const int min_exponent = __LDBL_MIN_EXP__; static const int min_exponent10 = __LDBL_MIN_10_EXP__; static const float_denorm_style has_denorm = bool(__LDBL_DENORM_MIN__) ? denorm_present : denorm_absent; ... since this isn't being used in an #ifdef, it should be easy enough to taint the decl for these ivars. //===---------------------------------------------------------------------===//