[PATCH] D63508: make -frewrite-includes handle __has_include wrapped in a macro

Luboš Luňák via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 18 12:00:26 PDT 2019


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 = &macroInfo->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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63508.205410.patch
Type: text/x-patch
Size: 2323 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190618/4f822636/attachment.bin>


More information about the cfe-commits mailing list