llunak created this revision. llunak added reviewers: vsapsai, bkramer. llunak added a project: clang. Herald added subscribers: cfe-commits, dexonsmith.
Qt5 has a wrapper macro that makes __has_include simpler to use: #ifdef __has_include 1. define QT_HAS_INCLUDE(x) __has_include(x) #else 2. define QT_HAS_INCLUDE(x) 0 #endif #if QT_HAS_INCLUDE(<chrono>) 3. include <chrono> #endif The code handling this so far ignores macros entirely. This patch handles this specific case in a crude way by checking if an identifier in #if is a macro whose first token is the checked for macro. Repository: rC Clang https://reviews.llvm.org/D63508 Files: clang/lib/Frontend/Rewrite/InclusionRewriter.cpp clang/test/Frontend/rewrite-includes-has-include-macro.c Index: clang/test/Frontend/rewrite-includes-has-include-macro.c =================================================================== --- /dev/null +++ clang/test/Frontend/rewrite-includes-has-include-macro.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -verify -E -frewrite-includes %s -o - | FileCheck -strict-whitespace %s +// expected-no-diagnostics + +#define MACRO_HAS_INCLUDE(x) __has_include(x) +#if MACRO_HAS_INCLUDE(<this_header_does_not_exist.h>) +#endif + +// CHECK: #define MACRO_HAS_INCLUDE(x) __has_include(x) +// CHECK-NEXT: #if (0)/*MACRO_HAS_INCLUDE(<this_header_does_not_exist.h>)*/ +// CHECK-NEXT: #endif Index: clang/lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -527,16 +527,28 @@ PP.LookUpIdentifierInfo(RawToken); if (RawToken.is(tok::identifier)) { + // Try to handle macros in the form of + // '#define QT_HAS_INCLUDE(x) __has_include(x)'. + const Token *ExpandedToken = &RawToken; + if (const MacroInfo *macroInfo = + PP.getMacroInfo(RawToken.getIdentifierInfo())) { + if (macroInfo->getNumTokens() > 0 && + macroInfo->getReplacementToken(0).is(tok::identifier)) { + ExpandedToken = ¯oInfo->getReplacementToken(0); + } + } + bool HasFile; SourceLocation Loc = RawToken.getLocation(); // Rewrite __has_include(x) - if (RawToken.getIdentifierInfo()->isStr("__has_include")) { + if (ExpandedToken->getIdentifierInfo()->isStr( + "__has_include")) { if (!HandleHasInclude(FileId, RawLex, nullptr, RawToken, HasFile)) continue; // Rewrite __has_include_next(x) - } else if (RawToken.getIdentifierInfo()->isStr( + } else if (ExpandedToken->getIdentifierInfo()->isStr( "__has_include_next")) { if (DirLookup) ++DirLookup;
Index: clang/test/Frontend/rewrite-includes-has-include-macro.c =================================================================== --- /dev/null +++ clang/test/Frontend/rewrite-includes-has-include-macro.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -verify -E -frewrite-includes %s -o - | FileCheck -strict-whitespace %s +// expected-no-diagnostics + +#define MACRO_HAS_INCLUDE(x) __has_include(x) +#if MACRO_HAS_INCLUDE(<this_header_does_not_exist.h>) +#endif + +// CHECK: #define MACRO_HAS_INCLUDE(x) __has_include(x) +// CHECK-NEXT: #if (0)/*MACRO_HAS_INCLUDE(<this_header_does_not_exist.h>)*/ +// CHECK-NEXT: #endif Index: clang/lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- clang/lib/Frontend/Rewrite/InclusionRewriter.cpp +++ clang/lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -527,16 +527,28 @@ PP.LookUpIdentifierInfo(RawToken); if (RawToken.is(tok::identifier)) { + // Try to handle macros in the form of + // '#define QT_HAS_INCLUDE(x) __has_include(x)'. + const Token *ExpandedToken = &RawToken; + if (const MacroInfo *macroInfo = + PP.getMacroInfo(RawToken.getIdentifierInfo())) { + if (macroInfo->getNumTokens() > 0 && + macroInfo->getReplacementToken(0).is(tok::identifier)) { + ExpandedToken = ¯oInfo->getReplacementToken(0); + } + } + bool HasFile; SourceLocation Loc = RawToken.getLocation(); // Rewrite __has_include(x) - if (RawToken.getIdentifierInfo()->isStr("__has_include")) { + if (ExpandedToken->getIdentifierInfo()->isStr( + "__has_include")) { if (!HandleHasInclude(FileId, RawLex, nullptr, RawToken, HasFile)) continue; // Rewrite __has_include_next(x) - } else if (RawToken.getIdentifierInfo()->isStr( + } else if (ExpandedToken->getIdentifierInfo()->isStr( "__has_include_next")) { if (DirLookup) ++DirLookup;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits