Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2462,6 +2462,13 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left, const FormatToken &Right) { + // if in a #define and a keyword is being defined e.g. #define true (1) + // ensure the space between the keyword and '(' is preserved + if (Line.InPPDirective && Right.is(tok::l_paren) && + !Left.is(tok::identifier) && Left.Previous && + Left.Previous->is(tok::identifier) && Left.Previous->Previous && + Left.Previous->Previous->is(tok::hash)) + return true; if (Left.is(tok::kw_return) && Right.isNot(tok::semi)) return true; if (Left.is(Keywords.kw_assert) && Style.Language == FormatStyle::LK_Java) Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -13423,6 +13423,25 @@ guessLanguage("foo.h", "#define FOO ({ foo(); ({ NSString *s; }) })")); } +TEST_F(FormatTest, MacroKeyWordsAndParents) { + + format::FormatStyle Style = format::getLLVMStyle(); + verifyFormat("#define TRUE ((foo)1)", Style); + verifyFormat("#define throw ((foo)1)", Style); + verifyFormat("#define true ((foo)1)", Style); + verifyFormat("#define false ((foo)1)", Style); + verifyFormat("#define sizeof ((foo)1)", Style); + verifyFormat("#define new ((foo)1)", Style); + verifyFormat("#define delete ((foo)1)", Style); + verifyFormat("#define for ((foo)1)", Style); + verifyFormat("#define override ((foo)1)", Style); + verifyFormat("#define else ((foo)1)", Style); + verifyFormat("#define true 1", Style); + verifyFormat("#define true foo", Style); + verifyFormat("#define true foo()", Style); + verifyFormat("#define NO_LENGTH (~(uint64_t)0)", Style); +} + } // end namespace } // end namespace format } // end namespace clang