[clang] b1b24d7 - [clang][ExtractAPI] Fix quirks in interaction with submodules (#105868)

via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 27 05:50:45 PDT 2024


Author: Daniel Grumberg
Date: 2024-08-27T13:50:41+01:00
New Revision: b1b24d751776d5fd2218a5cb43a8d103bf59fa32

URL: https://github.com/llvm/llvm-project/commit/b1b24d751776d5fd2218a5cb43a8d103bf59fa32
DIFF: https://github.com/llvm/llvm-project/commit/b1b24d751776d5fd2218a5cb43a8d103bf59fa32.diff

LOG: [clang][ExtractAPI] Fix quirks in interaction with submodules (#105868)

Extension SGFs require the module system to be enabled in order to discover which module defines the extended external type.
This patch ensures the following:
- Associate symbols with their top level module name, and that only top level modules are considered as modules for emitting extension SGFs.
- Ensure we don't drop macro definitions that came from a submodule. To this end look at all defined macros in `PPCalbacks::EndOfMainFile` instead of relying on `PPCallbacks::MacroDefined` being called to detect a macro definition.

Added: 
    clang/test/ExtractAPI/submodule-macro.m

Modified: 
    clang/include/clang/ExtractAPI/DeclarationFragments.h
    clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
    clang/lib/ExtractAPI/DeclarationFragments.cpp
    clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
    clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
    clang/test/ExtractAPI/bool.c
    clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
    clang/test/ExtractAPI/emit-symbol-graph/single_file.c
    clang/test/ExtractAPI/macros.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 535da90b98284b..4ac744459031eb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -411,9 +411,9 @@ class DeclarationFragmentsBuilder {
   /// Build DeclarationFragments for a macro.
   ///
   /// \param Name name of the macro.
-  /// \param MD the associated MacroDirective.
+  /// \param MI the associated MacroInfo.
   static DeclarationFragments getFragmentsForMacro(StringRef Name,
-                                                   const MacroDirective *MD);
+                                                   const MacroInfo *MI);
 
   /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
   static DeclarationFragments

diff  --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 67659f5a25037c..b09b8b44d9abaa 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -213,7 +213,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
 
   StringRef getOwningModuleName(const Decl &D) {
     if (auto *OwningModule = D.getImportedOwningModule())
-      return OwningModule->Name;
+      return OwningModule->getTopLevelModule()->Name;
 
     return {};
   }

diff  --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 6b85c7db90349e..d77bb1d424f7cf 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1327,14 +1327,12 @@ DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization(
 
 DeclarationFragments
 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
-                                                  const MacroDirective *MD) {
+                                                  const MacroInfo *MI) {
   DeclarationFragments Fragments;
   Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
       .appendSpace();
   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
 
-  auto *MI = MD->getMacroInfo();
-
   if (MI->isFunctionLike()) {
     Fragments.append("(", DeclarationFragments::FragmentKind::Text);
     unsigned numParameters = MI->getNumParams();

diff  --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index d6335854cbf262..0adc23280fd6c0 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -286,78 +286,59 @@ class MacroCallback : public PPCallbacks {
   MacroCallback(const SourceManager &SM, APISet &API, Preprocessor &PP)
       : SM(SM), API(API), PP(PP) {}
 
-  void MacroDefined(const Token &MacroNameToken,
-                    const MacroDirective *MD) override {
-    auto *MacroInfo = MD->getMacroInfo();
+  void EndOfMainFile() override {
+    for (const auto &M : PP.macros()) {
+      auto *II = M.getFirst();
+      auto MD = PP.getMacroDefinition(II);
+      auto *MI = MD.getMacroInfo();
 
-    if (MacroInfo->isBuiltinMacro())
-      return;
+      if (!MI)
+        continue;
 
-    auto SourceLoc = MacroNameToken.getLocation();
-    if (SM.isWrittenInBuiltinFile(SourceLoc) ||
-        SM.isWrittenInCommandLineFile(SourceLoc))
-      return;
+      // Ignore header guard macros
+      if (MI->isUsedForHeaderGuard())
+        continue;
 
-    PendingMacros.emplace_back(MacroNameToken, MD);
-  }
+      // Ignore builtin macros and ones defined via the command line.
+      if (MI->isBuiltinMacro())
+        continue;
 
-  // If a macro gets undefined at some point during preprocessing of the inputs
-  // it means that it isn't an exposed API and we should therefore not add a
-  // macro definition for it.
-  void MacroUndefined(const Token &MacroNameToken, const MacroDefinition &MD,
-                      const MacroDirective *Undef) override {
-    // If this macro wasn't previously defined we don't need to do anything
-    // here.
-    if (!Undef)
-      return;
-
-    llvm::erase_if(PendingMacros, [&MD, this](const PendingMacro &PM) {
-      return MD.getMacroInfo()->isIdenticalTo(*PM.MD->getMacroInfo(), PP,
-                                              /*Syntactically*/ false);
-    });
-  }
+      auto DefLoc = MI->getDefinitionLoc();
 
-  void EndOfMainFile() override {
-    for (auto &PM : PendingMacros) {
-      // `isUsedForHeaderGuard` is only set when the preprocessor leaves the
-      // file so check for it here.
-      if (PM.MD->getMacroInfo()->isUsedForHeaderGuard())
+      if (SM.isWrittenInBuiltinFile(DefLoc) ||
+          SM.isWrittenInCommandLineFile(DefLoc))
         continue;
 
-      if (!shouldMacroBeIncluded(PM))
+      auto AssociatedModuleMacros = MD.getModuleMacros();
+      StringRef OwningModuleName;
+      if (!AssociatedModuleMacros.empty())
+        OwningModuleName = AssociatedModuleMacros.back()
+                               ->getOwningModule()
+                               ->getTopLevelModuleName();
+
+      if (!shouldMacroBeIncluded(DefLoc, OwningModuleName))
         continue;
 
-      StringRef Name = PM.MacroNameToken.getIdentifierInfo()->getName();
-      PresumedLoc Loc = SM.getPresumedLoc(PM.MacroNameToken.getLocation());
+      StringRef Name = II->getName();
+      PresumedLoc Loc = SM.getPresumedLoc(DefLoc);
       SmallString<128> USR;
-      index::generateUSRForMacro(Name, PM.MacroNameToken.getLocation(), SM,
-                                 USR);
-
+      index::generateUSRForMacro(Name, DefLoc, SM, USR);
       API.createRecord<extractapi::MacroDefinitionRecord>(
           USR, Name, SymbolReference(), Loc,
-          DeclarationFragmentsBuilder::getFragmentsForMacro(Name, PM.MD),
+          DeclarationFragmentsBuilder::getFragmentsForMacro(Name, MI),
           DeclarationFragmentsBuilder::getSubHeadingForMacro(Name),
-          SM.isInSystemHeader(PM.MacroNameToken.getLocation()));
+          SM.isInSystemHeader(DefLoc));
     }
-
-    PendingMacros.clear();
   }
 
-protected:
-  struct PendingMacro {
-    Token MacroNameToken;
-    const MacroDirective *MD;
-
-    PendingMacro(const Token &MacroNameToken, const MacroDirective *MD)
-        : MacroNameToken(MacroNameToken), MD(MD) {}
-  };
-
-  virtual bool shouldMacroBeIncluded(const PendingMacro &PM) { return true; }
+  virtual bool shouldMacroBeIncluded(const SourceLocation &MacroLoc,
+                                     StringRef ModuleName) {
+    return true;
+  }
 
   const SourceManager &SM;
   APISet &API;
   Preprocessor &PP;
-  llvm::SmallVector<PendingMacro> PendingMacros;
 };
 
 class APIMacroCallback : public MacroCallback {
@@ -366,9 +347,10 @@ class APIMacroCallback : public MacroCallback {
                    LocationFileChecker &LCF)
       : MacroCallback(SM, API, PP), LCF(LCF) {}
 
-  bool shouldMacroBeIncluded(const PendingMacro &PM) override {
+  bool shouldMacroBeIncluded(const SourceLocation &MacroLoc,
+                             StringRef ModuleName) override {
     // Do not include macros from external files
-    return LCF(PM.MacroNameToken.getLocation());
+    return LCF(MacroLoc) || API.ProductName == ModuleName;
   }
 
 private:

diff  --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 1bce9c59b19791..030509d3787595 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -928,8 +928,8 @@ bool SymbolGraphSerializer::traverseObjCCategoryRecord(
     return true;
 
   auto *CurrentModule = ModuleForCurrentSymbol;
-  if (Record->isExtendingExternalModule())
-    ModuleForCurrentSymbol = &ExtendedModules[Record->Interface.Source];
+  if (auto ModuleExtendedByRecord = Record->getExtendedExternalModule())
+    ModuleForCurrentSymbol = &ExtendedModules[*ModuleExtendedByRecord];
 
   if (!walkUpFromObjCCategoryRecord(Record))
     return false;

diff  --git a/clang/test/ExtractAPI/bool.c b/clang/test/ExtractAPI/bool.c
index efab6dfeef03b2..7a4d34acb0d269 100644
--- a/clang/test/ExtractAPI/bool.c
+++ b/clang/test/ExtractAPI/bool.c
@@ -2,8 +2,8 @@
 // RUN: split-file %s %t
 // RUN: sed -e "s at INPUT_DIR@%{/t:regex_replacement}@g" \
 // RUN: %t/reference.output.json.in >> %t/reference.output.json
-// RUN: %clang -extract-api --pretty-sgf -target arm64-apple-macosx \
-// RUN: %t/input.h -o %t/output.json
+// RUN: %clang_cc1 -extract-api --product-name=BoolTest --pretty-sgf -triple arm64-apple-macosx \
+// RUN:   %t/input.h -o %t/output.json
 
 // Generator version is not consistent across test runs, normalize it.
 // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
@@ -15,7 +15,7 @@
 bool Foo;
 
 bool IsFoo(bool Bar);
-/// expected-no-diagnostics
+// expected-no-diagnostics
 
 //--- reference.output.json.in
 {
@@ -28,7 +28,7 @@ bool IsFoo(bool Bar);
     "generator": "?"
   },
   "module": {
-    "name": "",
+    "name": "BoolTest",
     "platform": {
       "architecture": "arm64",
       "operatingSystem": {

diff  --git a/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c b/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
index e668f69bc7e05f..651e0df2cd93a0 100644
--- a/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
+++ b/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
@@ -27,9 +27,6 @@
 #ifndef TEST_H
 #define TEST_H
 
-#define testmarcro1 32
-#define testmacro2 42
-
 int testfunc (int param1, int param2);
 void testfunc2 ();
 #endif /* TEST_H */
@@ -185,7 +182,7 @@ int main ()
       "location": {
         "position": {
           "character": 4,
-          "line": 6
+          "line": 3
         },
         "uri": "file://INPUT_DIR/test.h"
       },
@@ -249,7 +246,7 @@ int main ()
       "location": {
         "position": {
           "character": 5,
-          "line": 7
+          "line": 4
         },
         "uri": "file://INPUT_DIR/test.h"
       },
@@ -335,106 +332,6 @@ int main ()
       "pathComponents": [
         "main"
       ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "testmarcro1"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "c",
-        "precise": "c:test.h at 39@macro at testmarcro1"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 3
-        },
-        "uri": "file://INPUT_DIR/test.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "testmarcro1"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "testmarcro1"
-          }
-        ],
-        "title": "testmarcro1"
-      },
-      "pathComponents": [
-        "testmarcro1"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "testmacro2"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "c",
-        "precise": "c:test.h at 62@macro at testmacro2"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 4
-        },
-        "uri": "file://INPUT_DIR/test.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "testmacro2"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "testmacro2"
-          }
-        ],
-        "title": "testmacro2"
-      },
-      "pathComponents": [
-        "testmacro2"
-      ]
     }
   ]
 }
@@ -573,7 +470,7 @@ int main ()
       "location": {
         "position": {
           "character": 4,
-          "line": 6
+          "line": 3
         },
         "uri": "file://INPUT_DIR/test.h"
       },
@@ -637,7 +534,7 @@ int main ()
       "location": {
         "position": {
           "character": 5,
-          "line": 7
+          "line": 4
         },
         "uri": "file://INPUT_DIR/test.h"
       },
@@ -659,106 +556,6 @@ int main ()
       "pathComponents": [
         "testfunc2"
       ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "testmarcro1"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "c",
-        "precise": "c:test.h at 39@macro at testmarcro1"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 3
-        },
-        "uri": "file://INPUT_DIR/test.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "testmarcro1"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "testmarcro1"
-          }
-        ],
-        "title": "testmarcro1"
-      },
-      "pathComponents": [
-        "testmarcro1"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "testmacro2"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "c",
-        "precise": "c:test.h at 62@macro at testmacro2"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 4
-        },
-        "uri": "file://INPUT_DIR/test.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "testmacro2"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "testmacro2"
-          }
-        ],
-        "title": "testmacro2"
-      },
-      "pathComponents": [
-        "testmacro2"
-      ]
     }
   ]
 }

diff  --git a/clang/test/ExtractAPI/emit-symbol-graph/single_file.c b/clang/test/ExtractAPI/emit-symbol-graph/single_file.c
index b00b5f5237c9a3..feb759f5947bc9 100644
--- a/clang/test/ExtractAPI/emit-symbol-graph/single_file.c
+++ b/clang/test/ExtractAPI/emit-symbol-graph/single_file.c
@@ -15,9 +15,6 @@
 // CHECK-NOT: warning:
 
 //--- main.c
-#define TESTMACRO1 2
-#define TESTMARCRO2 5
-
 int main ()
 {
   return 0;
@@ -87,7 +84,7 @@ int main ()
       "location": {
         "position": {
           "character": 4,
-          "line": 3
+          "line": 0
         },
         "uri": "file://INPUT_DIR/main.c"
       },
@@ -109,106 +106,6 @@ int main ()
       "pathComponents": [
         "main"
       ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "TESTMACRO1"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "c",
-        "precise": "c:main.c at 8@macro at TESTMACRO1"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 0
-        },
-        "uri": "file://INPUT_DIR/main.c"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "TESTMACRO1"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "TESTMACRO1"
-          }
-        ],
-        "title": "TESTMACRO1"
-      },
-      "pathComponents": [
-        "TESTMACRO1"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "TESTMARCRO2"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "c",
-        "precise": "c:main.c at 29@macro at TESTMARCRO2"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 1
-        },
-        "uri": "file://INPUT_DIR/main.c"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "TESTMARCRO2"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "TESTMARCRO2"
-          }
-        ],
-        "title": "TESTMARCRO2"
-      },
-      "pathComponents": [
-        "TESTMARCRO2"
-      ]
     }
   ]
 }

diff  --git a/clang/test/ExtractAPI/macros.c b/clang/test/ExtractAPI/macros.c
index 10003fe6f6e40f..15eb5f6a7f66fe 100644
--- a/clang/test/ExtractAPI/macros.c
+++ b/clang/test/ExtractAPI/macros.c
@@ -1,416 +1,358 @@
 // RUN: rm -rf %t
-// RUN: split-file %s %t
-// RUN: sed -e "s at INPUT_DIR@%{/t:regex_replacement}@g" \
-// RUN: %t/reference.output.json.in >> %t/reference.output.json
-// RUN: %clang -extract-api --pretty-sgf --product-name=Macros -target arm64-apple-macosx \
-// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing --product-name=Macros -triple arm64-apple-macosx \
+// RUN:   -isystem %S -x objective-c-header %s -o %t/output.symbols.json
 
-// Generator version is not consistent across test runs, normalize it.
-// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
-// RUN: %t/output.json >> %t/output-normalized.json
-// RUN: 
diff  %t/reference.output.json %t/output-normalized.json
-
-// CHECK-NOT: error:
-// CHECK-NOT: warning:
-
-//--- input.h
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix HELLO
 #define HELLO 1
+// HELLO-LABEL: "!testLabel": "c:@macro at HELLO"
+// HELLO:      "accessLevel": "public",
+// HELLO-NEXT: "declarationFragments": [
+// HELLO-NEXT:   {
+// HELLO-NEXT:     "kind": "keyword",
+// HELLO-NEXT:     "spelling": "#define"
+// HELLO-NEXT:   },
+// HELLO-NEXT:   {
+// HELLO-NEXT:     "kind": "text",
+// HELLO-NEXT:     "spelling": " "
+// HELLO-NEXT:   },
+// HELLO-NEXT:   {
+// HELLO-NEXT:     "kind": "identifier",
+// HELLO-NEXT:     "spelling": "HELLO"
+// HELLO-NEXT:   }
+// HELLO-NEXT: ],
+// HELLO:      "kind": {
+// HELLO-NEXT:   "displayName": "Macro",
+// HELLO-NEXT:   "identifier": "objective-c.macro"
+// HELLO-NEXT: },
+// HELLO-NEXT: "location": {
+// HELLO-NEXT:   "position": {
+// HELLO-NEXT:     "character": 8,
+// HELLO-NEXT:     "line": [[# @LINE - 25]]
+// HELLO-NEXT:   },
+// HELLO-NEXT:   "uri": "file://{{.*}}/macros.c"
+// HELLO-NEXT: },
+// HELLO-NEXT: "names": {
+// HELLO-NEXT:   "navigator": [
+// HELLO-NEXT:     {
+// HELLO-NEXT:       "kind": "identifier",
+// HELLO-NEXT:       "spelling": "HELLO"
+// HELLO-NEXT:     }
+// HELLO-NEXT:   ],
+// HELLO-NEXT:   "subHeading": [
+// HELLO-NEXT:     {
+// HELLO-NEXT:       "kind": "identifier",
+// HELLO-NEXT:       "spelling": "HELLO"
+// HELLO-NEXT:     }
+// HELLO-NEXT:   ],
+// HELLO-NEXT:   "title": "HELLO"
+// HELLO-NEXT: },
+// HELLO-NEXT: "pathComponents": [
+// HELLO-NEXT:   "HELLO"
+// HELLO-NEXT: ]
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix WORLD
 #define WORLD 2
+// WORLD-LABEL: "!testLabel": "c:@macro at WORLD"
+// WORLD:      "accessLevel": "public",
+// WORLD-NEXT: "declarationFragments": [
+// WORLD-NEXT:   {
+// WORLD-NEXT:     "kind": "keyword",
+// WORLD-NEXT:     "spelling": "#define"
+// WORLD-NEXT:   },
+// WORLD-NEXT:   {
+// WORLD-NEXT:     "kind": "text",
+// WORLD-NEXT:     "spelling": " "
+// WORLD-NEXT:   },
+// WORLD-NEXT:   {
+// WORLD-NEXT:     "kind": "identifier",
+// WORLD-NEXT:     "spelling": "WORLD"
+// WORLD-NEXT:   }
+// WORLD-NEXT: ],
+// WORLD:      "kind": {
+// WORLD-NEXT:   "displayName": "Macro",
+// WORLD-NEXT:   "identifier": "objective-c.macro"
+// WORLD-NEXT: },
+// WORLD-NEXT: "location": {
+// WORLD-NEXT:   "position": {
+// WORLD-NEXT:     "character": 8,
+// WORLD-NEXT:     "line": [[# @LINE - 25]]
+// WORLD-NEXT:   },
+// WORLD-NEXT:   "uri": "file://{{.*}}/macros.c"
+// WORLD-NEXT: },
+// WORLD-NEXT: "names": {
+// WORLD-NEXT:   "navigator": [
+// WORLD-NEXT:     {
+// WORLD-NEXT:       "kind": "identifier",
+// WORLD-NEXT:       "spelling": "WORLD"
+// WORLD-NEXT:     }
+// WORLD-NEXT:   ],
+// WORLD-NEXT:   "subHeading": [
+// WORLD-NEXT:     {
+// WORLD-NEXT:       "kind": "identifier",
+// WORLD-NEXT:       "spelling": "WORLD"
+// WORLD-NEXT:     }
+// WORLD-NEXT:   ],
+// WORLD-NEXT:   "title": "WORLD"
+// WORLD-NEXT: },
+// WORLD-NEXT: "pathComponents": [
+// WORLD-NEXT:   "WORLD"
+// WORLD-NEXT: ]
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix MACRO_FUN
 #define MACRO_FUN(x) x x
+// MACRO_FUN-LABEL: "!testLabel": "c:@macro at MACRO_FUN"
+// MACRO_FUN-NEXT: "accessLevel": "public",
+// MACRO_FUN-NEXT: "declarationFragments": [
+// MACRO_FUN-NEXT:   {
+// MACRO_FUN-NEXT:     "kind": "keyword",
+// MACRO_FUN-NEXT:     "spelling": "#define"
+// MACRO_FUN-NEXT:   },
+// MACRO_FUN-NEXT:   {
+// MACRO_FUN-NEXT:     "kind": "text",
+// MACRO_FUN-NEXT:     "spelling": " "
+// MACRO_FUN-NEXT:   },
+// MACRO_FUN-NEXT:   {
+// MACRO_FUN-NEXT:     "kind": "identifier",
+// MACRO_FUN-NEXT:     "spelling": "MACRO_FUN"
+// MACRO_FUN-NEXT:   },
+// MACRO_FUN-NEXT:   {
+// MACRO_FUN-NEXT:     "kind": "text",
+// MACRO_FUN-NEXT:     "spelling": "("
+// MACRO_FUN-NEXT:   },
+// MACRO_FUN-NEXT:   {
+// MACRO_FUN-NEXT:     "kind": "internalParam",
+// MACRO_FUN-NEXT:     "spelling": "x"
+// MACRO_FUN-NEXT:   },
+// MACRO_FUN-NEXT:   {
+// MACRO_FUN-NEXT:     "kind": "text",
+// MACRO_FUN-NEXT:     "spelling": ")"
+// MACRO_FUN-NEXT:   }
+// MACRO_FUN-NEXT: ],
+// MACRO_FUN:      "kind": {
+// MACRO_FUN-NEXT:   "displayName": "Macro",
+// MACRO_FUN-NEXT:   "identifier": "objective-c.macro"
+// MACRO_FUN-NEXT: },
+// MACRO_FUN-NEXT: "location": {
+// MACRO_FUN-NEXT:   "position": {
+// MACRO_FUN-NEXT:     "character": 8,
+// MACRO_FUN-NEXT:     "line": [[# @LINE - 37]]
+// MACRO_FUN-NEXT:   },
+// MACRO_FUN-NEXT:   "uri": "file://{{.*}}/macros.c"
+// MACRO_FUN-NEXT: },
+// MACRO_FUN-NEXT: "names": {
+// MACRO_FUN-NEXT:   "navigator": [
+// MACRO_FUN-NEXT:     {
+// MACRO_FUN-NEXT:       "kind": "identifier",
+// MACRO_FUN-NEXT:       "spelling": "MACRO_FUN"
+// MACRO_FUN-NEXT:     }
+// MACRO_FUN-NEXT:   ],
+// MACRO_FUN-NEXT:   "subHeading": [
+// MACRO_FUN-NEXT:     {
+// MACRO_FUN-NEXT:       "kind": "identifier",
+// MACRO_FUN-NEXT:       "spelling": "MACRO_FUN"
+// MACRO_FUN-NEXT:     }
+// MACRO_FUN-NEXT:   ],
+// MACRO_FUN-NEXT:   "title": "MACRO_FUN"
+// MACRO_FUN-NEXT: },
+// MACRO_FUN-NEXT: "pathComponents": [
+// MACRO_FUN-NEXT:   "MACRO_FUN"
+// MACRO_FUN-NEXT: ]
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix FUN
 #define FUN(x, y, z) x + y + z
+// FUN-LABEL: "!testLabel": "c:@macro at FUN"
+// FUN-NEXT: "accessLevel": "public",
+// FUN-NEXT: "declarationFragments": [
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "keyword",
+// FUN-NEXT:     "spelling": "#define"
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "text",
+// FUN-NEXT:     "spelling": " "
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "identifier",
+// FUN-NEXT:     "spelling": "FUN"
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "text",
+// FUN-NEXT:     "spelling": "("
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "internalParam",
+// FUN-NEXT:     "spelling": "x"
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "text",
+// FUN-NEXT:     "spelling": ", "
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "internalParam",
+// FUN-NEXT:     "spelling": "y"
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "text",
+// FUN-NEXT:     "spelling": ", "
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "internalParam",
+// FUN-NEXT:     "spelling": "z"
+// FUN-NEXT:   },
+// FUN-NEXT:   {
+// FUN-NEXT:     "kind": "text",
+// FUN-NEXT:     "spelling": ")"
+// FUN-NEXT:   }
+// FUN-NEXT: ],
+// FUN:      "kind": {
+// FUN-NEXT:   "displayName": "Macro",
+// FUN-NEXT:   "identifier": "objective-c.macro"
+// FUN-NEXT: },
+// FUN-NEXT: "location": {
+// FUN-NEXT:   "position": {
+// FUN-NEXT:     "character": 8,
+// FUN-NEXT:     "line": [[# @LINE - 53]]
+// FUN-NEXT:   },
+// FUN-NEXT:   "uri": "file://{{.*}}/macros.c"
+// FUN-NEXT: },
+// FUN-NEXT: "names": {
+// FUN-NEXT:   "navigator": [
+// FUN-NEXT:     {
+// FUN-NEXT:       "kind": "identifier",
+// FUN-NEXT:       "spelling": "FUN"
+// FUN-NEXT:     }
+// FUN-NEXT:   ],
+// FUN-NEXT:   "subHeading": [
+// FUN-NEXT:     {
+// FUN-NEXT:       "kind": "identifier",
+// FUN-NEXT:       "spelling": "FUN"
+// FUN-NEXT:     }
+// FUN-NEXT:   ],
+// FUN-NEXT:   "title": "FUN"
+// FUN-NEXT: },
+// FUN-NEXT: "pathComponents": [
+// FUN-NEXT:   "FUN"
+// FUN-NEXT: ]
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix FUNC99
 #define FUNC99(x, ...)
+// FUNC99-LABEL: "!testLabel": "c:@macro at FUNC99"
+// FUNC99-NEXT: "accessLevel": "public",
+// FUNC99-NEXT: "declarationFragments": [
+// FUNC99-NEXT:   {
+// FUNC99-NEXT:     "kind": "keyword",
+// FUNC99-NEXT:     "spelling": "#define"
+// FUNC99-NEXT:   },
+// FUNC99-NEXT:   {
+// FUNC99-NEXT:     "kind": "text",
+// FUNC99-NEXT:     "spelling": " "
+// FUNC99-NEXT:   },
+// FUNC99-NEXT:   {
+// FUNC99-NEXT:     "kind": "identifier",
+// FUNC99-NEXT:     "spelling": "FUNC99"
+// FUNC99-NEXT:   },
+// FUNC99-NEXT:   {
+// FUNC99-NEXT:     "kind": "text",
+// FUNC99-NEXT:     "spelling": "("
+// FUNC99-NEXT:   },
+// FUNC99-NEXT:   {
+// FUNC99-NEXT:     "kind": "internalParam",
+// FUNC99-NEXT:     "spelling": "x"
+// FUNC99-NEXT:   },
+// FUNC99-NEXT:   {
+// FUNC99-NEXT:     "kind": "text",
+// FUNC99-NEXT:     "spelling": ", ...)"
+// FUNC99-NEXT:   }
+// FUNC99-NEXT: ],
+// FUNC99:      "kind": {
+// FUNC99-NEXT:   "displayName": "Macro",
+// FUNC99-NEXT:   "identifier": "objective-c.macro"
+// FUNC99-NEXT: },
+// FUNC99-NEXT: "location": {
+// FUNC99-NEXT:   "position": {
+// FUNC99-NEXT:     "character": 8,
+// FUNC99-NEXT:     "line": [[# @LINE - 37]]
+// FUNC99-NEXT:   },
+// FUNC99-NEXT:   "uri": "file://{{.*}}/macros.c"
+// FUNC99-NEXT: },
+// FUNC99-NEXT: "names": {
+// FUNC99-NEXT:   "navigator": [
+// FUNC99-NEXT:     {
+// FUNC99-NEXT:       "kind": "identifier",
+// FUNC99-NEXT:       "spelling": "FUNC99"
+// FUNC99-NEXT:     }
+// FUNC99-NEXT:   ],
+// FUNC99-NEXT:   "subHeading": [
+// FUNC99-NEXT:     {
+// FUNC99-NEXT:       "kind": "identifier",
+// FUNC99-NEXT:       "spelling": "FUNC99"
+// FUNC99-NEXT:     }
+// FUNC99-NEXT:   ],
+// FUNC99-NEXT:   "title": "FUNC99"
+// FUNC99-NEXT: },
+// FUNC99-NEXT: "pathComponents": [
+// FUNC99-NEXT:   "FUNC99"
+// FUNC99-NEXT: ]
+
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix FUNGNU
 #define FUNGNU(x...)
+// FUNGNU-LABEL: "!testLabel": "c:@macro at FUNGNU"
+// FUNGNU-NEXT: "accessLevel": "public",
+// FUNGNU-NEXT: "declarationFragments": [
+// FUNGNU-NEXT:   {
+// FUNGNU-NEXT:     "kind": "keyword",
+// FUNGNU-NEXT:     "spelling": "#define"
+// FUNGNU-NEXT:   },
+// FUNGNU-NEXT:   {
+// FUNGNU-NEXT:     "kind": "text",
+// FUNGNU-NEXT:     "spelling": " "
+// FUNGNU-NEXT:   },
+// FUNGNU-NEXT:   {
+// FUNGNU-NEXT:     "kind": "identifier",
+// FUNGNU-NEXT:     "spelling": "FUNGNU"
+// FUNGNU-NEXT:   },
+// FUNGNU-NEXT:   {
+// FUNGNU-NEXT:     "kind": "text",
+// FUNGNU-NEXT:     "spelling": "("
+// FUNGNU-NEXT:   },
+// FUNGNU-NEXT:   {
+// FUNGNU-NEXT:     "kind": "internalParam",
+// FUNGNU-NEXT:     "spelling": "x"
+// FUNGNU-NEXT:   },
+// FUNGNU-NEXT:   {
+// FUNGNU-NEXT:     "kind": "text",
+// FUNGNU-NEXT:     "spelling": "...)"
+// FUNGNU-NEXT:   }
+// FUNGNU-NEXT: ],
+// FUNGNU:      "kind": {
+// FUNGNU-NEXT:   "displayName": "Macro",
+// FUNGNU-NEXT:   "identifier": "objective-c.macro"
+// FUNGNU-NEXT: },
+// FUNGNU-NEXT: "location": {
+// FUNGNU-NEXT:   "position": {
+// FUNGNU-NEXT:     "character": 8,
+// FUNGNU-NEXT:     "line": [[# @LINE - 37]]
+// FUNGNU-NEXT:   },
+// FUNGNU-NEXT:   "uri": "file://{{.*}}/macros.c"
+// FUNGNU-NEXT: },
+// FUNGNU-NEXT: "names": {
+// FUNGNU-NEXT:   "navigator": [
+// FUNGNU-NEXT:     {
+// FUNGNU-NEXT:       "kind": "identifier",
+// FUNGNU-NEXT:       "spelling": "FUNGNU"
+// FUNGNU-NEXT:     }
+// FUNGNU-NEXT:   ],
+// FUNGNU-NEXT:   "subHeading": [
+// FUNGNU-NEXT:     {
+// FUNGNU-NEXT:       "kind": "identifier",
+// FUNGNU-NEXT:       "spelling": "FUNGNU"
+// FUNGNU-NEXT:     }
+// FUNGNU-NEXT:   ],
+// FUNGNU-NEXT:   "title": "FUNGNU"
+// FUNGNU-NEXT: },
+// FUNGNU-NEXT: "pathComponents": [
+// FUNGNU-NEXT:   "FUNGNU"
+// FUNGNU-NEXT: ]
+
+// expected-no-diagnostics
 
-//--- reference.output.json.in
-{
-  "metadata": {
-    "formatVersion": {
-      "major": 0,
-      "minor": 5,
-      "patch": 3
-    },
-    "generator": "?"
-  },
-  "module": {
-    "name": "Macros",
-    "platform": {
-      "architecture": "arm64",
-      "operatingSystem": {
-        "minimumVersion": {
-          "major": 11,
-          "minor": 0,
-          "patch": 0
-        },
-        "name": "macosx"
-      },
-      "vendor": "apple"
-    }
-  },
-  "relationships": [],
-  "symbols": [
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "HELLO"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "objective-c",
-        "precise": "c:input.h at 8@macro at HELLO"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "objective-c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 0
-        },
-        "uri": "file://INPUT_DIR/input.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "HELLO"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "HELLO"
-          }
-        ],
-        "title": "HELLO"
-      },
-      "pathComponents": [
-        "HELLO"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "WORLD"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "objective-c",
-        "precise": "c:input.h at 24@macro at WORLD"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "objective-c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 1
-        },
-        "uri": "file://INPUT_DIR/input.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "WORLD"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "WORLD"
-          }
-        ],
-        "title": "WORLD"
-      },
-      "pathComponents": [
-        "WORLD"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "MACRO_FUN"
-        },
-        {
-          "kind": "text",
-          "spelling": "("
-        },
-        {
-          "kind": "internalParam",
-          "spelling": "x"
-        },
-        {
-          "kind": "text",
-          "spelling": ")"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "objective-c",
-        "precise": "c:input.h at 40@macro at MACRO_FUN"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "objective-c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 2
-        },
-        "uri": "file://INPUT_DIR/input.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "MACRO_FUN"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "MACRO_FUN"
-          }
-        ],
-        "title": "MACRO_FUN"
-      },
-      "pathComponents": [
-        "MACRO_FUN"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "FUN"
-        },
-        {
-          "kind": "text",
-          "spelling": "("
-        },
-        {
-          "kind": "internalParam",
-          "spelling": "x"
-        },
-        {
-          "kind": "text",
-          "spelling": ", "
-        },
-        {
-          "kind": "internalParam",
-          "spelling": "y"
-        },
-        {
-          "kind": "text",
-          "spelling": ", "
-        },
-        {
-          "kind": "internalParam",
-          "spelling": "z"
-        },
-        {
-          "kind": "text",
-          "spelling": ")"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "objective-c",
-        "precise": "c:input.h at 65@macro at FUN"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "objective-c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 3
-        },
-        "uri": "file://INPUT_DIR/input.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "FUN"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "FUN"
-          }
-        ],
-        "title": "FUN"
-      },
-      "pathComponents": [
-        "FUN"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "FUNC99"
-        },
-        {
-          "kind": "text",
-          "spelling": "("
-        },
-        {
-          "kind": "internalParam",
-          "spelling": "x"
-        },
-        {
-          "kind": "text",
-          "spelling": ", ...)"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "objective-c",
-        "precise": "c:input.h at 96@macro at FUNC99"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "objective-c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 4
-        },
-        "uri": "file://INPUT_DIR/input.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "FUNC99"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "FUNC99"
-          }
-        ],
-        "title": "FUNC99"
-      },
-      "pathComponents": [
-        "FUNC99"
-      ]
-    },
-    {
-      "accessLevel": "public",
-      "declarationFragments": [
-        {
-          "kind": "keyword",
-          "spelling": "#define"
-        },
-        {
-          "kind": "text",
-          "spelling": " "
-        },
-        {
-          "kind": "identifier",
-          "spelling": "FUNGNU"
-        },
-        {
-          "kind": "text",
-          "spelling": "("
-        },
-        {
-          "kind": "internalParam",
-          "spelling": "x"
-        },
-        {
-          "kind": "text",
-          "spelling": "...)"
-        }
-      ],
-      "identifier": {
-        "interfaceLanguage": "objective-c",
-        "precise": "c:input.h at 119@macro at FUNGNU"
-      },
-      "kind": {
-        "displayName": "Macro",
-        "identifier": "objective-c.macro"
-      },
-      "location": {
-        "position": {
-          "character": 8,
-          "line": 5
-        },
-        "uri": "file://INPUT_DIR/input.h"
-      },
-      "names": {
-        "navigator": [
-          {
-            "kind": "identifier",
-            "spelling": "FUNGNU"
-          }
-        ],
-        "subHeading": [
-          {
-            "kind": "identifier",
-            "spelling": "FUNGNU"
-          }
-        ],
-        "title": "FUNGNU"
-      },
-      "pathComponents": [
-        "FUNGNU"
-      ]
-    }
-  ]
-}

diff  --git a/clang/test/ExtractAPI/submodule-macro.m b/clang/test/ExtractAPI/submodule-macro.m
new file mode 100644
index 00000000000000..a41d59a1574253
--- /dev/null
+++ b/clang/test/ExtractAPI/submodule-macro.m
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
+// RUN:   --emit-extension-symbol-graphs --symbol-graph-dir=%t/symbols -isystem %t \
+// RUN:   --product-name=Umbrella -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules-cache \
+// RUN:   -triple arm64-apple-macosx -x objective-c-header %t/Umbrella.h %t/Subheader.h
+
+//--- Umbrella.h
+#include "Subheader.h"
+#import <stdbool.h>
+
+//--- Subheader.h
+#define FOO 1
+
+//--- module.modulemap
+module Umbrella {
+    umbrella header "Umbrella.h"
+    export *
+    module * { export * }
+}
+
+// RUN: FileCheck %s --input-file  %t/symbols/Umbrella.symbols.json --check-prefix MOD
+// MOD-NOT: bool
+// MOD: "!testLabel": "c:@macro at FOO"
+


        


More information about the cfe-commits mailing list