[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-13 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D144999#4415419 , @oontvoo wrote:

> In D144999#4415137 , @jasonmolenda 
> wrote:
>
>> Michael and I looked into this.  This simple c++ file is resulting in 
>> eh_frame unwind info on aarch64 darwin instead of compact unwind info.

P.S: still no luck reproducing this with TOT clang.  Would you mind verifying 
my test case below (this was on M1  mac):

  ### clang is built with commit up to 5b1c62c0f2e9a739707429f650cb897c067f86c2
  vyng-macbookpro3 /Users/vyng/repo/llvm-project/build_all$ ./bin/clang++  
../cross-project-tests/debuginfo-tests/dexter-tests/optnone-struct-and-methods.cpp
 -g -O0 -c -o test_tot.o
  
  vyng-macbookpro3 /Users/vyng/repo/llvm-project/build_all$ objdump --macho 
--unwind-info --dwarf=frames  test_tot.o
  Contents of __compact_unwind section:
Entry at offset 0x0:
  start:0x0 ltmp0
  length:   0x70
  compact encoding: 0x4400
  personality function: 0x0 ___gxx_personality_v0
  LSDA: 0x238 ltmp1
Entry at offset 0x20:
  start:0x70 __ZN12_GLOBAL__N_11AC1Ev
  length:   0x2c
  compact encoding: 0x0400
Entry at offset 0x40:
  start:0x9c __ZN12_GLOBAL__N_11A7getDataEv
  length:   0x78
  compact encoding: 0x0400
Entry at offset 0x60:
  start:0x114 __ZN12_GLOBAL__N_11AD1Ev
  length:   0x2c
  compact encoding: 0x0400
Entry at offset 0x80:
  start:0x140 __ZN12_GLOBAL__N_11AC2Ev
  length:   0x2c
  compact encoding: 0x02001000
Entry at offset 0xa0:
  start:0x16c __ZN12_GLOBAL__N_11A12setOtherDataEv
  length:   0x74
  compact encoding: 0x0400
Entry at offset 0xc0:
  start:0x1e0 __ZN12_GLOBAL__N_11A12getOtherDataEv
  length:   0x18
  compact encoding: 0x02001000
Entry at offset 0xe0:
  start:0x1f8 __ZN12_GLOBAL__N_11AD2Ev
  length:   0x40
  compact encoding: 0x0400
  
  .debug_frame contents:
  
  
  .eh_frame contents:
   nothing in eh_frame section, which is expected and matches what produced 
by base clang




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-12 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D144999#4415137 , @jasonmolenda 
wrote:

> Michael and I looked into this.  This simple c++ file is resulting in 
> eh_frame unwind info on aarch64 darwin instead of compact unwind info.  The 
> eh_frame instructions don't describe the epilogue, so lldb is stopping on the 
> final RET instruction after it has adjusted $sp back to its original value 
> and the unwind now fails to work in the debugger.  That's always the problem 
> with eh_frame/debug_frame from the debugger's point of view - it's only 
> guaranteed to describe the unwind state at throwable locations.  gdb lives 
> exclusively off of eh_frame/debug_frame so in practice gcc/clang (at least on 
> intel) describe both the prologue and the epilogue for the debugger's 
> benefit.  But that's not what this eh_frame includes on aarch64 darwin, and 
> it breaks the debugger because it's trusting the eh_frame to be accurate at 
> every instruction point.
>
> The emission of eh_frame on aarch64 darwin instead of compact unwind, for 
> this simple codegen, is a bug and cannot remain in the tree unfixed.  It will 
> increase binary size and reduce throw performance.  It also happens to cause 
> lldb regressions like this because we've never lived off of eh_frame as our 
> primary unwind format on this platform, but that's a separate issue and I'm 
> not going to dig in to finding a way to detect this & ignore the eh_frame on 
> this target.

Thanks for the details! From your descriptions, I agree that this is a bug - 
the change in this patch is *NOT* intended to change the unwind format when 
there's no personality symbol - (it should only affect custom personality 
symbols, which is not the case in this example)
Still debugging - not sure why it only occurs for aarch64

> Looking at the failing test case that Michael has been debugging, none of 
> these methods have a personality, and yet we're getting eh_frame instead of 
> compact unwind.  That's the bug.




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

P.S This might have the same root-cause with the previous comment and could be 
fixed by D152540  as well.
(not able to repro the failures yet - don't have arm64 readily available, will 
test it later this evening. but on linux x86-64 and macos x86-64, ninja 
check-debuginfo passed for me)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D144999#4409149 , @Michael137 
wrote:

> In D144999#4408248 , @Michael137 
> wrote:
>
>> Looks like the latest reland of this patch 
>> (`e60b30d5e3878e7d91f8872ec4c4dca00d4a2dfc`) broke some debug-info 
>> `cross-project-tests` on the Arm64 macOS buildbots: 
>> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake-as/263/execution/node/54/log/
>>
>>   Failed Tests (2):
>> cross-project-tests :: debuginfo-tests/dexter-tests/optnone-fastmath.cpp
>> cross-project-tests :: 
>> debuginfo-tests/dexter-tests/optnone-struct-and-methods.cpp
>>
>> You can run those tests by adding `cross-project-tests` to 
>> `LLVM_ENABLE_PROJECTS` and running `ninja check-debuginfo`.
>>
>> AFAICT, it also broke following LLDB test 
>> (https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake-as/263/execution/node/65/log/):
>>
>>   Failed Tests (1):
>> lldb-api :: functionalities/step-avoids-no-debug/TestStepNoDebug.py
>>
>> Let me know if you need help reproducing this
>
> Mind taking a look or reverting the patch until the tests pass?

Yes - having a look now - wasn't able to repro the test failure before because 
the build broke at HEAD:

  /mnt/ssd/repo/llvm-project/llvm/include/llvm/CodeGen/RDFRegisters.h: In 
member function ‘constexpr size_t llvm::rdf::RegisterRef::hash() const’:
  /mnt/ssd/repo/llvm-project/llvm/include/llvm/CodeGen/RDFRegisters.h:92:35: 
error: call to non-‘constexpr’ function ‘std::size_t std::hash::operator()(unsigned int) const’
 92 | return std::hash{}(Reg) ^
|~~~^


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D144999#4407934 , @t.p.northover 
wrote:

> I don't think this handles the no-personality case properly. For example this 
> code leads to a DWARF entry now:
>
>   void bar(int *) noexcept;
>   void foo() {
> int arr;
> bar(&arr);
>   }

Thanks! Sent the fix in D152540 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-08 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

P.S: https://reviews.llvm.org/D152449


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-08 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D144999#4405793 , @fdeazeve wrote:

> I believe this is breaking the LLDB tests: 
> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/56106/changes
> https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/buildTimeTrend
>
> Build 56105 was passing, and the only relevant change seems to come from this 
> review.
>
> Note that the failure is due to a test that is now passing:
>
>   Unexpectedly Passed Tests (1):
> lldb-shell :: Unwind/prefer-debug-over-eh-frame.test
>
> Maybe we forgot to re-enable that test?

The behaviour has changed - I can update the test.
Question: Do you prefer to have it set a flag that goes back to the old 
behaviour? OR change to to expect-passing?

(My vote would be on have it expect the test to pass because, from reading the 
test, this is preferring debug-frame over eh-frame, which probably isn't ideal 
in the new code beacuse all non-canonical personality symbols will now be 
eh-frame)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-07 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 529283.
oontvoo added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj < %s | \
+// RUN: llvm-mc -triple=arm64-apple-ios -filety

[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-06-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 528965.
oontvoo added a comment.

rebase for rolling forward. (Will wait ~1 day before pushing to avoid possible 
stacking reverts because this depends on D151824 
)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch

[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-31 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo reopened this revision.
oontvoo added a comment.
This revision is now accepted and ready to land.

In D144999#4356218 , @thakis wrote:

> Reverted in 4980eead4d0b4666d53dad07afb091375b3a13a0 
>  for now.
>
> (The assert only happens when targeting x86_64, not arm64. The repro script 
> above has the right `-arch` flag to toggle it.)

Thanks for the revert! This was caused by another bug (should be fixed in 
https://reviews.llvm.org/D151824)
Will reland this once that is landed.




Comment at: llvm/lib/MC/MCAsmBackend.cpp:125
+// Reserving an empty slot for it seems silly.
+return name == "__gxx_personality_v0" || name == "__objc_personality_v0";
+  }

need an additional _


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-18 Thread Vy Nguyen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG09aaf53a05e3: [RFC][MC][MachO]Only emits compact-unwind 
format for "canonical" personality… (authored by oontvoo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s

[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-18 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 523354.
oontvoo added a comment.

rebase again (windows failures in flang tests looked unrelated)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj 

[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-17 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-17 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 523148.
oontvoo added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj < %s | \
+// RUN: llvm-mc -triple=arm64-apple-ios -filety

[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-17 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 523147.
oontvoo marked an inline comment as done.
oontvoo edited the summary of this revision.
oontvoo added a comment.

updated comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
@@ -1,4 +1,4 @@
-// RUN: llvm-mc

[PATCH] D144999: [Clang][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-10 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

@int3 @thakis, et al - friendly 🔔  :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-08 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

Hi all! The CI builds are all clean now. Any further comment/review on this? 
Would love to close this out soon. Thanks! :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-08 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 520344.
oontvoo added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple=arm64-apple-ios -filetype=obj < %s | \
+// RUN: llvm-mc -triple=arm64-apple-ios -filety

[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-05 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 519939.
oontvoo added a comment.

addressed review comments:

- added explanation on why we left out _gcc personality
- updated more clang tests

hopefully should be all green now!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
  llvm/test/CodeGen/X86/2014-08-29-CompactUnwind.ll
  llvm/test/CodeGen/X86/compact-unwind.ll
  llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
  llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
  llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
  llvm/test/MC/X86/compact-unwind.s

Index: llvm/test/MC/X86/compact-unwind.s
===
--- llvm/test/MC/X86/compact-unwind.s
+++ llvm/test/MC/X86/compact-unwind.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s | llvm-objdump --unwind-info - | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin10.0 %s -emit-compact-unwind-non-canonical=true | llvm-objdump --unwind-info - | FileCheck %s
 
 	.section	__TEXT,__text,regular,pure_instructions
 	.macosx_version_min 10, 10
Index: llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
===
--- llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
+++ llvm/test/MC/MachO/ARM/compact-unwind-armv7k.s
@@ -1,4 +1,4 @@
-@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
+@ RUN: llvm-mc -triple=thumbv7k-apple-watchos2.0.0 -emit-compact-unwind-non-canonical=true -filetype=obj -o %t < %s && llvm-objdump --unwind-info %t | FileCheck %s
 
 @ CHECK: Contents of __compact_unwind section:
 
Index: llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
===
--- llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
+++ llvm/test/MC/MachO/AArch64/emit-dwarf-unwind.s
@@ -1,11 +1,11 @@
 // RUN: rm -rf %t; mkdir %t
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj -o %t/x86_64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64.o | FileCheck %s --check-prefix TWO-FDES
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj -o %t/arm64.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o
+// RUN: llvm-mc -triple x86_64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind no-compact-unwind -o %t/x86_64-no-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/x86_64-no-dwarf.o | FileCheck %s --check-prefix ONE-FDE
-// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o
+// RUN: llvm-mc -triple arm64-apple-macos11.0 %s -filetype=obj --emit-dwarf-unwind always -o %t/arm64-dwarf.o -emit-compact-unwind-non-canonical=true
 // RUN: llvm-objdump --macho --dwarf=frames %t/arm64-dwarf.o | FileCheck %s --check-prefix TWO-FDES
 
 // TWO-FDES: FDE
Index: llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
===
--- llvm/test/MC/AArch64/arm64-leaf-compact-unwind.s
+++ llvm/test/MC/AArch64/arm64-leaf-compa

[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-05 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo marked an inline comment as done.
oontvoo added a comment.

In D144999#4319964 , @jyknight wrote:

> I wonder if we actually need to define a clang frontend flag for this; I 
> suspect nobody will ever want to specify it, since the only non-canonical 
> personality clang will ever generate that changes behavior is the pure-C 
> destructor-only personality, `__gnu_personality_v0`. Otherwise, it could only 
> arise from assembly or IR.
>
> For a test-case, can just use `-mllvm -emit-compact-unwind-non-canonical`.

Per offline discussion, passing it via `-mllvm` doesn't work because  
llvm-flags that populate MCTargetOptions flags aren't registered in Clang, so 
it needs to be at least a clang cc1 option.




Comment at: lld/MachO/UnwindInfoSection.cpp:364
   cu.encoding = target->modeDwarfEncoding | d->unwindEntry->outSecOff;
-  const FDE &fde = cast(d->getFile())->fdes[d->unwindEntry];
   cu.functionLength = fde.funcLength;

int3 wrote:
> seems like this was accidentally deleted?
yes - good catch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-05 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 519849.
oontvoo added a comment.
Herald added a subscriber: MaskRay.

updated more clang test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/test/Driver/femit-dwarf-unwind.s
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

Index: llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
===
--- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -1350,9 +1350,13 @@
 
   /// Implementation of algorithm to generate the compact unwind encoding
   /// for the CFI instructions.
-  uint32_t
-  generateCompactUnwindEncoding(ArrayRef Instrs) const override {
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ArrayRef Instrs = FI->Instructions;
 if (Instrs.empty()) return 0;
+if (!isDarwinCanonicalPersonality(FI->Personality) &&
+!Ctxt->emitCompactUnwindNonCanonical())
+  return CU::UNWIND_MODE_DWARF;
 
 // Reset the saved registers.
 unsigned SavedRegIdx = 0;
Index: llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
===
--- llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
+++ llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
@@ -11,6 +11,7 @@
 
 #include "ARMAsmBackend.h"
 #include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCObjectWriter.h"
 
 namespace llvm {
@@ -32,8 +33,8 @@
 /*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype);
   }
 
-  uint32_t generateCompactUnwindEncoding(
-  ArrayRef Instrs) const override;
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override;
 };
 } // end namespace llvm
 
Index: llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
===
--- llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -1108,14 +1108,19 @@
 /// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
 /// tells the runtime to fallback and unwind using dwarf.
 uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
-ArrayRef Instrs) const {
+const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const {
   DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
   // Only armv7k uses CFI based unwinding.
   if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
 return 0;
   // No .cfi directives means no frame.
+  ArrayRef Instrs = FI->Instructions;
   if (Instrs.empty())
 return 0;
+  if (!isDarwinCanonicalPersonality(FI->Personality) &&
+  !Ctxt->emitCompactUnwindNonCanonical())
+return CU::UNWIND_ARM_MODE_DWARF;
+
   // Start off assuming CFA is at SP+0.
   unsigned CFARegister = ARM::SP;
   int CFARegisterOffset = 0;
Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
===
--- llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -564,10 +564,14 @@
   }
 
   /// Generate the compact unwind encoding from the CFI directives.
-  uint32_t generateCompactUnwindEncoding(
- ArrayRef Instrs) const override {
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+

[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-03 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 519216.
oontvoo added a comment.
Herald added a subscriber: ormris.

- defined equivalent flag in the clang driver


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/Driver/femit-dwarf-unwind.c
  clang/tools/driver/cc1as_main.cpp
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

Index: llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
===
--- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -1350,9 +1350,13 @@
 
   /// Implementation of algorithm to generate the compact unwind encoding
   /// for the CFI instructions.
-  uint32_t
-  generateCompactUnwindEncoding(ArrayRef Instrs) const override {
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ArrayRef Instrs = FI->Instructions;
 if (Instrs.empty()) return 0;
+if (!isDarwinCanonicalPersonality(FI->Personality) &&
+!Ctxt->emitCompactUnwindNonCanonical())
+  return CU::UNWIND_MODE_DWARF;
 
 // Reset the saved registers.
 unsigned SavedRegIdx = 0;
Index: llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
===
--- llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
+++ llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
@@ -11,6 +11,7 @@
 
 #include "ARMAsmBackend.h"
 #include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCObjectWriter.h"
 
 namespace llvm {
@@ -32,8 +33,8 @@
 /*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype);
   }
 
-  uint32_t generateCompactUnwindEncoding(
-  ArrayRef Instrs) const override;
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override;
 };
 } // end namespace llvm
 
Index: llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
===
--- llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -1108,14 +1108,19 @@
 /// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
 /// tells the runtime to fallback and unwind using dwarf.
 uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
-ArrayRef Instrs) const {
+const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const {
   DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
   // Only armv7k uses CFI based unwinding.
   if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
 return 0;
   // No .cfi directives means no frame.
+  ArrayRef Instrs = FI->Instructions;
   if (Instrs.empty())
 return 0;
+  if (!isDarwinCanonicalPersonality(FI->Personality) &&
+  !Ctxt->emitCompactUnwindNonCanonical())
+return CU::UNWIND_ARM_MODE_DWARF;
+
   // Start off assuming CFA is at SP+0.
   unsigned CFARegister = ARM::SP;
   int CFARegisterOffset = 0;
Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
===
--- llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -564,10 +564,14 @@
   }
 
   /// Generate the compact unwind encoding from the CFI directives.
-  uint32_t generateCompactUnwindEncoding(
- ArrayRef Instrs) const override {
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ArrayRef Instr

[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

2023-05-02 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 518710.
oontvoo added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

updated clang test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144999/new/

https://reviews.llvm.org/D144999

Files:
  clang/test/Driver/femit-dwarf-unwind.c
  lld/MachO/UnwindInfoSection.cpp
  lld/test/MachO/Inputs/eh-frame-x86_64-r.o
  lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
  lld/test/MachO/compact-unwind-generated.test
  lld/test/MachO/compact-unwind-lsda-folding.s
  lld/test/MachO/compact-unwind-stack-ind.s
  lld/test/MachO/compact-unwind.s
  lld/test/MachO/eh-frame-personality-dedup.s
  lld/test/MachO/eh-frame.s
  lld/test/MachO/icf-only-lsda-folded.s
  lld/test/MachO/icf.s
  lld/test/MachO/invalid/compact-unwind-bad-reloc.s
  lld/test/MachO/invalid/compact-unwind-personalities.s
  llvm/include/llvm/MC/MCAsmBackend.h
  llvm/include/llvm/MC/MCContext.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
  llvm/lib/MC/MCAsmBackend.cpp
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCStreamer.cpp
  llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
  llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
  llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
  llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

Index: llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
===
--- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -1350,9 +1350,13 @@
 
   /// Implementation of algorithm to generate the compact unwind encoding
   /// for the CFI instructions.
-  uint32_t
-  generateCompactUnwindEncoding(ArrayRef Instrs) const override {
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ArrayRef Instrs = FI->Instructions;
 if (Instrs.empty()) return 0;
+if (!isDarwinCanonicalPersonality(FI->Personality) &&
+!Ctxt->emitCompactUnwindNonCanonical())
+  return CU::UNWIND_MODE_DWARF;
 
 // Reset the saved registers.
 unsigned SavedRegIdx = 0;
Index: llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
===
--- llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
+++ llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
@@ -11,6 +11,7 @@
 
 #include "ARMAsmBackend.h"
 #include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCObjectWriter.h"
 
 namespace llvm {
@@ -32,8 +33,8 @@
 /*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype);
   }
 
-  uint32_t generateCompactUnwindEncoding(
-  ArrayRef Instrs) const override;
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override;
 };
 } // end namespace llvm
 
Index: llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
===
--- llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -1108,14 +1108,19 @@
 /// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
 /// tells the runtime to fallback and unwind using dwarf.
 uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
-ArrayRef Instrs) const {
+const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const {
   DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
   // Only armv7k uses CFI based unwinding.
   if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
 return 0;
   // No .cfi directives means no frame.
+  ArrayRef Instrs = FI->Instructions;
   if (Instrs.empty())
 return 0;
+  if (!isDarwinCanonicalPersonality(FI->Personality) &&
+  !Ctxt->emitCompactUnwindNonCanonical())
+return CU::UNWIND_ARM_MODE_DWARF;
+
   // Start off assuming CFA is at SP+0.
   unsigned CFARegister = ARM::SP;
   int CFARegisterOffset = 0;
Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
===
--- llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -564,10 +564,14 @@
   }
 
   /// Generate the compact unwind encoding from the CFI directives.
-  uint32_t generateCompactUnwindEncoding(
- ArrayRef Instrs) const override {
+  uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ const MCContext *Ctxt) const override {
+ArrayRef Instrs = FI->Instructions;
 if (Instrs.empty())
   return CU::UNWIND_ARM64_MODE_FRAMELESS;
+if (!isDarwinCanonicalPersonality(FI->Personality) 

[PATCH] D139652: Add the thread sanitizer support for X86_64 WatchOS simulators

2022-12-09 Thread Vy Nguyen via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0073fd8d0dda: Add the thread sanitizer support for X86_64 
WatchOS simulators (authored by yfyang, committed by oontvoo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139652/new/

https://reviews.llvm.org/D139652

Files:
  clang/lib/Driver/ToolChains/Darwin.cpp
  clang/test/Driver/fsanitize.c


Index: clang/test/Driver/fsanitize.c
===
--- clang/test/Driver/fsanitize.c
+++ clang/test/Driver/fsanitize.c
@@ -460,9 +460,21 @@
 // RUN: %clang --target=arm64-apple-macos -fsanitize=thread %s -### 2>&1 | 
FileCheck %s --check-prefix=CHECK-TSAN-ARM64-MACOS
 // CHECK-TSAN-ARM64-MACOS-NOT: unsupported option
 
+// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=thread %s -### 
2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-IOSSIMULATOR
+// CHECK-TSAN-ARM64-IOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=thread %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-WATCHOSSIMULATOR
+// CHECK-TSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=thread %s -### 
2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-TVOSSIMULATOR
+// CHECK-TSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option
+
 // RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=thread %s -### 
2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-IOSSIMULATOR
 // CHECK-TSAN-X86-64-IOSSIMULATOR-NOT: unsupported option
 
+// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=thread %s 
-### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-WATCHOSSIMULATOR
+// CHECK-TSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option
+
 // RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=thread %s -### 
2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-TVOSSIMULATOR
 // CHECK-TSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option
 
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -3277,11 +3277,10 @@
   !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))
 Res |= SanitizerKind::Vptr;
 
-  if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {
+  if ((IsX86_64 || IsAArch64) &&
+  (isTargetMacOSBased() || isTargetIOSSimulator() ||
+   isTargetTvOSSimulator() || isTargetWatchOSSimulator())) {
 Res |= SanitizerKind::Thread;
-  } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
-if (IsX86_64)
-  Res |= SanitizerKind::Thread;
   }
   return Res;
 }


Index: clang/test/Driver/fsanitize.c
===
--- clang/test/Driver/fsanitize.c
+++ clang/test/Driver/fsanitize.c
@@ -460,9 +460,21 @@
 // RUN: %clang --target=arm64-apple-macos -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-MACOS
 // CHECK-TSAN-ARM64-MACOS-NOT: unsupported option
 
+// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-IOSSIMULATOR
+// CHECK-TSAN-ARM64-IOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-WATCHOSSIMULATOR
+// CHECK-TSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option
+
+// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ARM64-TVOSSIMULATOR
+// CHECK-TSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option
+
 // RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-IOSSIMULATOR
 // CHECK-TSAN-X86-64-IOSSIMULATOR-NOT: unsupported option
 
+// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-WATCHOSSIMULATOR
+// CHECK-TSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option
+
 // RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-X86-64-TVOSSIMULATOR
 // CHECK-TSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option
 
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -3277,11 +3277,10 @@
   !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))
 Res |= SanitizerKind::Vptr;
 
-  if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {
+  if ((IsX86_64 || IsAArch64) &&
+  (isTargetMacOSBased() || isTargetIOSSimulator() ||
+   isTargetTvOSSimulator() || isTargetWatchOSSimulator()))

[PATCH] D114975: [clang-tidy][objc] Finds and fixes improper usages of XCTAssertEquals and XCTAssertNotEquals.

2021-12-02 Thread Vy Nguyen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGaba8f320cc13: [clang-tidy][objc] Finds and fixes improper 
usages of XCTAssertEquals and… (authored by oontvoo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114975/new/

https://reviews.llvm.org/D114975

Files:
  clang-tools-extra/clang-tidy/objc/AssertEquals.cpp
  clang-tools-extra/clang-tidy/objc/AssertEquals.h
  clang-tools-extra/clang-tidy/objc/CMakeLists.txt
  clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/objc-assert-equals.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
  clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m

Index: clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s objc-assert-equals %t -- -- -I %S/Inputs/objc-assert
+#include "XCTestAssertions.h"
+// Can't reference NSString directly so we use this getStr() instead.
+__typeof(@"abc") getStr() {
+  return @"abc";
+}
+void foo() {
+  XCTAssertEqual(getStr(), @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), @"abc");
+  XCTAssertEqual(@"abc", @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", @"abc");
+  XCTAssertEqual(@"abc", getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", getStr());
+  XCTAssertEqual(getStr(), getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), getStr());
+  // Primitive types should be ok
+  XCTAssertEqual(123, 123);
+  XCTAssertEqual(123.0, 123.45);
+  // FIXME: This is the case where we don't diagnose properly.
+  // XCTAssertEqual(@"abc" != @"abc", @"xyz" != @"xyz")
+}
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
@@ -0,0 +1,30 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+#define THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+
+#define _XCTPrimitiveAssertEqual(test, expression1, expressionStr1, \
+ expression2, expressionStr2, ...)  \
+  ({\
+__typeof__(expression1) expressionValue1 = (expression1);   \
+__typeof__(expression2) expressionValue2 = (expression2);   \
+if (expressionValue1 != expressionValue2) { \
+}   \
+  })
+
+#define _XCTPrimitiveAssertEqualObjects(test, expression1, expressionStr1, \
+expression2, expressionStr2, ...)  \
+  ({   \
+__typeof__(expression1) expressionValue1 = (expression1);  \
+__typeof__(expression2) expressionValue2 = (expression2);  \
+if (expressionValue1 != expressionValue2) {\
+}  \
+  })
+
+#define XCTAssertEqual(expression1, expression2, ...) \
+  _XCTPrimitiveAssertEqual(nil, expression1, @ #expression1, expression2, \
+   @ #expression2, __VA_ARGS__)
+
+#define XCTAssertEqualObjects(expression1, expression2, ...)\
+  _XCTPrimitiveAssertEqualObjects(nil, expression1, @ #expression1, \
+  expression2, @ #expression2, __VA_ARGS__)
+
+#endif // THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
Index: clang-tools-extra/docs/clang-tidy/checks/objc-assert-equals.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/objc-assert-equals.rst
@@ -0,0 +1,11 @@
+.. title:: clang-tidy - objc-assert-equals
+
+objc-assert-equals
+==
+
+Finds improper usages of `XCTAssertEqual` and `XCTAssertNotEqual` and replaces
+them with `XCTAssertEqualObjects` or `XCTAssertNotEqualObjects`.
+
+This makes tests less fragile, as many improperly rely on pointer equality for
+st

[PATCH] D114975: [clang-tidy][objc] Finds and fixes improper usages of XCTAssertEquals and XCTAssertNotEquals.

2021-12-02 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114975/new/

https://reviews.llvm.org/D114975

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D114975: [clang-tidy][objc] Finds and fixes improper usages of XCTAssertEquals and XCTAssertNotEquals.

2021-12-02 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 391472.
oontvoo added a comment.

doc


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114975/new/

https://reviews.llvm.org/D114975

Files:
  clang-tools-extra/clang-tidy/objc/AssertEquals.cpp
  clang-tools-extra/clang-tidy/objc/AssertEquals.h
  clang-tools-extra/clang-tidy/objc/CMakeLists.txt
  clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/objc-assert-equals.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
  clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m

Index: clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s objc-assert-equals %t -- -- -I %S/Inputs/objc-assert
+#include "XCTestAssertions.h"
+// Can't reference NSString directly so we use this getStr() instead.
+__typeof(@"abc") getStr() {
+  return @"abc";
+}
+void foo() {
+  XCTAssertEqual(getStr(), @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), @"abc");
+  XCTAssertEqual(@"abc", @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", @"abc");
+  XCTAssertEqual(@"abc", getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", getStr());
+  XCTAssertEqual(getStr(), getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), getStr());
+  // Primitive types should be ok
+  XCTAssertEqual(123, 123);
+  XCTAssertEqual(123.0, 123.45);
+  // FIXME: This is the case where we don't diagnose properly.
+  // XCTAssertEqual(@"abc" != @"abc", @"xyz" != @"xyz")
+}
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
@@ -0,0 +1,30 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+#define THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+
+#define _XCTPrimitiveAssertEqual(test, expression1, expressionStr1, \
+ expression2, expressionStr2, ...)  \
+  ({\
+__typeof__(expression1) expressionValue1 = (expression1);   \
+__typeof__(expression2) expressionValue2 = (expression2);   \
+if (expressionValue1 != expressionValue2) { \
+}   \
+  })
+
+#define _XCTPrimitiveAssertEqualObjects(test, expression1, expressionStr1, \
+expression2, expressionStr2, ...)  \
+  ({   \
+__typeof__(expression1) expressionValue1 = (expression1);  \
+__typeof__(expression2) expressionValue2 = (expression2);  \
+if (expressionValue1 != expressionValue2) {\
+}  \
+  })
+
+#define XCTAssertEqual(expression1, expression2, ...) \
+  _XCTPrimitiveAssertEqual(nil, expression1, @ #expression1, expression2, \
+   @ #expression2, __VA_ARGS__)
+
+#define XCTAssertEqualObjects(expression1, expression2, ...)\
+  _XCTPrimitiveAssertEqualObjects(nil, expression1, @ #expression1, \
+  expression2, @ #expression2, __VA_ARGS__)
+
+#endif // THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
Index: clang-tools-extra/docs/clang-tidy/checks/objc-assert-equals.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/objc-assert-equals.rst
@@ -0,0 +1,11 @@
+.. title:: clang-tidy - objc-assert-equals
+
+objc-assert-equals
+==
+
+Finds improper usages of `XCTAssertEqual` and `XCTAssertNotEqual` and replaces
+them with `XCTAssertEqualObjects` or `XCTAssertNotEqualObjects`.
+
+This makes tests less fragile, as many improperly rely on pointer equality for
+strings that have equal values.  This assumption is not guarantted by the
+language.
Index: clang-tools-extra/docs/clang-tidy/check

[PATCH] D114975: [clang-tidy][objc] Finds and fixes improper usages of XCTAssertEquals and XCTAssertNotEquals.

2021-12-02 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 391451.
oontvoo added a comment.

updated diff


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114975/new/

https://reviews.llvm.org/D114975

Files:
  clang-tools-extra/clang-tidy/objc/AssertEquals.cpp
  clang-tools-extra/clang-tidy/objc/AssertEquals.h
  clang-tools-extra/clang-tidy/objc/CMakeLists.txt
  clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
  clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m

Index: clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s objc-assert-equals %t -- -- -I %S/Inputs/objc-assert
+#include "XCTestAssertions.h"
+// Can't reference NSString directly so we use this getStr() instead.
+__typeof(@"abc") getStr() {
+  return @"abc";
+}
+void foo() {
+  XCTAssertEqual(getStr(), @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), @"abc");
+  XCTAssertEqual(@"abc", @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", @"abc");
+  XCTAssertEqual(@"abc", getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", getStr());
+  XCTAssertEqual(getStr(), getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), getStr());
+  // Primitive types should be ok
+  XCTAssertEqual(123, 123);
+  XCTAssertEqual(123.0, 123.45);
+  // FIXME: This is the case where we don't diagnose properly.
+  // XCTAssertEqual(@"abc" != @"abc", @"xyz" != @"xyz")
+}
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
@@ -0,0 +1,30 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+#define THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+
+#define _XCTPrimitiveAssertEqual(test, expression1, expressionStr1, \
+ expression2, expressionStr2, ...)  \
+  ({\
+__typeof__(expression1) expressionValue1 = (expression1);   \
+__typeof__(expression2) expressionValue2 = (expression2);   \
+if (expressionValue1 != expressionValue2) { \
+}   \
+  })
+
+#define _XCTPrimitiveAssertEqualObjects(test, expression1, expressionStr1, \
+expression2, expressionStr2, ...)  \
+  ({   \
+__typeof__(expression1) expressionValue1 = (expression1);  \
+__typeof__(expression2) expressionValue2 = (expression2);  \
+if (expressionValue1 != expressionValue2) {\
+}  \
+  })
+
+#define XCTAssertEqual(expression1, expression2, ...) \
+  _XCTPrimitiveAssertEqual(nil, expression1, @ #expression1, expression2, \
+   @ #expression2, __VA_ARGS__)
+
+#define XCTAssertEqualObjects(expression1, expression2, ...)\
+  _XCTPrimitiveAssertEqualObjects(nil, expression1, @ #expression1, \
+  expression2, @ #expression2, __VA_ARGS__)
+
+#endif // THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -92,7 +92,7 @@
`bugprone-string-constructor `_, "Yes"
`bugprone-string-integer-assignment `_, "Yes"
`bugprone-string-literal-with-embedded-nul `_,
-   `bugprone-stringview-nullptr `_, "Yes"
+   `bugprone-stringview-nullptr `_, "Yes"   
`bugprone-suspicious-enum-usage `_,
`bugprone-suspicious-include `_,
`bugprone-suspicious-memory-comparison `_,
@@ -261,6 +261,7 @@
`mpi-buffer-deref `_, "Yes"
`mpi-type-mismatch `_, "Yes"
`objc-avoid-nserror-init `_,
+   `objc-assert-

[PATCH] D114975: [clang-tidy][objc] Finds and fixes improper usages of XCTAssertEquals and XCTAssertNotEquals.

2021-12-02 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
Herald added subscribers: carlosgalvezp, xazax.hun, mgorny.
oontvoo requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Using XCTAssertEqual on NSString* objects are almost always  wrong.
Unfortunatley, we have seen a lot of tests doing this and reyling on pointer 
equality for strings with the same values.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114975

Files:
  clang-tools-extra/clang-tidy/objc/AssertEquals.cpp
  clang-tools-extra/clang-tidy/objc/AssertEquals.h
  clang-tools-extra/clang-tidy/objc/CMakeLists.txt
  clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
  clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m

Index: clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/objc-assert-equals.m
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s custom-objc-assert-equals %t -- -- -I %S/input/objc-assert
+#include "XCTestAssertions.h"
+// Can't reference NSString directly so we use this getStr() instead.
+__typeof(@"abc") getStr() {
+  return @"abc";
+}
+void foo() {
+  XCTAssertEqual(getStr(), @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), @"abc");
+  XCTAssertEqual(@"abc", @"abc");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", @"abc");
+  XCTAssertEqual(@"abc", getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(@"abc", getStr());
+  XCTAssertEqual(getStr(), getStr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use XCTAssertEqualObjects for comparing objects
+  // CHECK-FIXES: XCTAssertEqualObjects(getStr(), getStr());
+  // Primitive types should be ok
+  XCTAssertEqual(123, 123);
+  XCTAssertEqual(123.0, 123.45);
+  // FIXME: This is the case where we don't diagnose properly.
+  // XCTAssertEqual(@"abc" != @"abc", @"xyz" != @"xyz")
+}
Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/Inputs/objc-assert/XCTestAssertions.h
@@ -0,0 +1,30 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+#define THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
+
+#define _XCTPrimitiveAssertEqual(test, expression1, expressionStr1, \
+ expression2, expressionStr2, ...)  \
+  ({\
+__typeof__(expression1) expressionValue1 = (expression1);   \
+__typeof__(expression2) expressionValue2 = (expression2);   \
+if (expressionValue1 != expressionValue2) { \
+}   \
+  })
+
+#define _XCTPrimitiveAssertEqualObjects(test, expression1, expressionStr1, \
+expression2, expressionStr2, ...)  \
+  ({   \
+__typeof__(expression1) expressionValue1 = (expression1);  \
+__typeof__(expression2) expressionValue2 = (expression2);  \
+if (expressionValue1 != expressionValue2) {\
+}  \
+  })
+
+#define XCTAssertEqual(expression1, expression2, ...) \
+  _XCTPrimitiveAssertEqual(nil, expression1, @ #expression1, expression2, \
+   @ #expression2, __VA_ARGS__)
+
+#define XCTAssertEqualObjects(expression1, expression2, ...)\
+  _XCTPrimitiveAssertEqualObjects(nil, expression1, @ #expression1, \
+  expression2, @ #expression2, __VA_ARGS__)
+
+#endif // THIRD_PARTY_LLVM_LLVM_PROJECT_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_INPUTS_OBJC_ASSERT_XCTESTASSERTIONS_H_
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -92,7 +92,7 @@
`bugprone-string-constructor `_, "Yes"
`bugprone-string-integer-assignment `_, "Yes"
`bugprone-string-literal-with-embedded-nul `_,
-   `bugprone-stringview-nullptr `_, "Yes"
+   `bugprone-stringview-nullptr `_, "Yes"  

[PATCH] D114842: [lld-macho] Remove old macho darwin lld

2021-12-01 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo accepted this revision.
oontvoo added a comment.

LG - thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114842/new/

https://reviews.llvm.org/D114842

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85843: Add "status" to the list of absl libraries.

2020-08-13 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

(With LGTM from sbenza)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85843/new/

https://reviews.llvm.org/D85843

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85843: Add "status" to the list of absl libraries.

2020-08-13 Thread Vy Nguyen via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG114c9fa0e46f: Add "status" to the list of absl 
libraries. (authored by oontvoo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85843/new/

https://reviews.llvm.org/D85843

Files:
  clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h


Index: clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
===
--- clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
+++ clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
@@ -50,8 +50,8 @@
   static const char *AbseilLibraries[] = {
   "algorithm", "base", "container",   "debugging", "flags",
   "hash",  "iterator", "memory",  "meta",  "numeric",
-  "random","strings",  "synchronization", "time",  "types",
-  "utility"};
+  "random","strings",  "synchronization", "status","time",
+  "types", "utility"};
   return std::any_of(
   std::begin(AbseilLibraries), std::end(AbseilLibraries),
   [&](const char *Library) { return Path.startswith(Library); });


Index: clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
===
--- clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
+++ clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
@@ -50,8 +50,8 @@
   static const char *AbseilLibraries[] = {
   "algorithm", "base", "container",   "debugging", "flags",
   "hash",  "iterator", "memory",  "meta",  "numeric",
-  "random","strings",  "synchronization", "time",  "types",
-  "utility"};
+  "random","strings",  "synchronization", "status","time",
+  "types", "utility"};
   return std::any_of(
   std::begin(AbseilLibraries), std::end(AbseilLibraries),
   [&](const char *Library) { return Path.startswith(Library); });
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D85843: Add "status" to the list of absl libraries.

2020-08-12 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
oontvoo added a reviewer: sbenza.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
oontvoo requested review of this revision.

The Abseil-NoInternalDependenciesCheck currently mistakenly triggers on any 
usage of internal helpers even if it is within absl/status.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85843

Files:
  clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h


Index: clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
===
--- clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
+++ clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
@@ -50,8 +50,8 @@
   static const char *AbseilLibraries[] = {
   "algorithm", "base", "container",   "debugging", "flags",
   "hash",  "iterator", "memory",  "meta",  "numeric",
-  "random","strings",  "synchronization", "time",  "types",
-  "utility"};
+  "random","strings",  "synchronization", "status","time",
+  "types", "utility"};
   return std::any_of(
   std::begin(AbseilLibraries), std::end(AbseilLibraries),
   [&](const char *Library) { return Path.startswith(Library); });


Index: clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
===
--- clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
+++ clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h
@@ -50,8 +50,8 @@
   static const char *AbseilLibraries[] = {
   "algorithm", "base", "container",   "debugging", "flags",
   "hash",  "iterator", "memory",  "meta",  "numeric",
-  "random","strings",  "synchronization", "time",  "types",
-  "utility"};
+  "random","strings",  "synchronization", "status","time",
+  "types", "utility"};
   return std::any_of(
   std::begin(AbseilLibraries), std::end(AbseilLibraries),
   [&](const char *Library) { return Path.startswith(Library); });
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83529: Summary: [clang] Provide a way for WhileStmt to report the location of its LParen and RParen.

2020-07-10 Thread Vy Nguyen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG17ea41e47256: Summary: [clang] Provide a way for WhileStmt 
to report the location of its… (authored by oontvoo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83529/new/

https://reviews.llvm.org/D83529

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/unittests/AST/SourceLocationTest.cpp

Index: clang/unittests/AST/SourceLocationTest.cpp
===
--- clang/unittests/AST/SourceLocationTest.cpp
+++ clang/unittests/AST/SourceLocationTest.cpp
@@ -60,6 +60,59 @@
   EXPECT_FALSE(Verifier.match("int i;", varDecl()));
 }
 
+class WhileParenLocationVerifier : public MatchVerifier {
+  unsigned ExpectLParenLine = 0, ExpectLParenColumn = 0;
+  unsigned ExpectRParenLine = 0, ExpectRParenColumn = 0;
+
+public:
+  void expectLocations(unsigned LParenLine, unsigned LParenColumn,
+   unsigned RParenLine, unsigned RParenColumn) {
+ExpectLParenLine = LParenLine;
+ExpectLParenColumn = LParenColumn;
+ExpectRParenLine = RParenLine;
+ExpectRParenColumn = RParenColumn;
+  }
+
+protected:
+  void verify(const MatchFinder::MatchResult &Result,
+  const WhileStmt &Node) override {
+SourceLocation LParenLoc = Node.getLParenLoc();
+SourceLocation RParenLoc = Node.getRParenLoc();
+unsigned LParenLine =
+Result.SourceManager->getSpellingLineNumber(LParenLoc);
+unsigned LParenColumn =
+Result.SourceManager->getSpellingColumnNumber(LParenLoc);
+unsigned RParenLine =
+Result.SourceManager->getSpellingLineNumber(RParenLoc);
+unsigned RParenColumn =
+Result.SourceManager->getSpellingColumnNumber(RParenLoc);
+
+if (LParenLine != ExpectLParenLine || LParenColumn != ExpectLParenColumn ||
+RParenLine != ExpectRParenLine || RParenColumn != ExpectRParenColumn) {
+  std::string MsgStr;
+  llvm::raw_string_ostream Msg(MsgStr);
+  Msg << "Expected LParen Location <" << ExpectLParenLine << ":"
+  << ExpectLParenColumn << ">, found <";
+  LParenLoc.print(Msg, *Result.SourceManager);
+  Msg << ">\n";
+
+  Msg << "Expected RParen Location <" << ExpectRParenLine << ":"
+  << ExpectRParenColumn << ">, found <";
+  RParenLoc.print(Msg, *Result.SourceManager);
+  Msg << ">";
+
+  this->setFailure(Msg.str());
+}
+  }
+};
+
+TEST(LocationVerifier, WhileParenLoc) {
+  WhileParenLocationVerifier Verifier;
+  Verifier.expectLocations(1, 17, 1, 38);
+  EXPECT_TRUE(Verifier.match("void f() { while(true/*some comment*/) {} }",
+ whileStmt()));
+}
+
 class LabelDeclRangeVerifier : public RangeVerifier {
 protected:
   SourceRange getRange(const LabelStmt &Node) override {
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -194,6 +194,8 @@
 Record.AddDeclRef(S->getConditionVariable());
 
   Record.AddSourceLocation(S->getWhileLoc());
+  Record.AddSourceLocation(S->getLParenLoc());
+  Record.AddSourceLocation(S->getRParenLoc());
   Code = serialization::STMT_WHILE;
 }
 
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -271,6 +271,8 @@
 S->setConditionVariable(Record.getContext(), readDeclAs());
 
   S->setWhileLoc(readSourceLocation());
+  S->setLParenLoc(readSourceLocation());
+  S->setRParenLoc(readSourceLocation());
 }
 
 void ASTStmtReader::VisitDoStmt(DoStmt *S) {
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -1347,9 +1347,10 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
-  Sema::ConditionResult Cond, Stmt *Body) {
-return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
+  Sema::ConditionResult Cond,
+  SourceLocation RParenLoc, Stmt *Body) {
+return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
   }
 
   /// Build a new do-while statement.
@@ -7335

[PATCH] D83529: Summary: [clang] Provide a way for WhileStmt to report the location of its LParen and RParen.

2020-07-10 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 277148.
oontvoo added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83529/new/

https://reviews.llvm.org/D83529

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/unittests/AST/SourceLocationTest.cpp

Index: clang/unittests/AST/SourceLocationTest.cpp
===
--- clang/unittests/AST/SourceLocationTest.cpp
+++ clang/unittests/AST/SourceLocationTest.cpp
@@ -60,6 +60,59 @@
   EXPECT_FALSE(Verifier.match("int i;", varDecl()));
 }
 
+class WhileParenLocationVerifier : public MatchVerifier {
+  unsigned ExpectLParenLine = 0, ExpectLParenColumn = 0;
+  unsigned ExpectRParenLine = 0, ExpectRParenColumn = 0;
+
+public:
+  void expectLocations(unsigned LParenLine, unsigned LParenColumn,
+   unsigned RParenLine, unsigned RParenColumn) {
+ExpectLParenLine = LParenLine;
+ExpectLParenColumn = LParenColumn;
+ExpectRParenLine = RParenLine;
+ExpectRParenColumn = RParenColumn;
+  }
+
+protected:
+  void verify(const MatchFinder::MatchResult &Result,
+  const WhileStmt &Node) override {
+SourceLocation LParenLoc = Node.getLParenLoc();
+SourceLocation RParenLoc = Node.getRParenLoc();
+unsigned LParenLine =
+Result.SourceManager->getSpellingLineNumber(LParenLoc);
+unsigned LParenColumn =
+Result.SourceManager->getSpellingColumnNumber(LParenLoc);
+unsigned RParenLine =
+Result.SourceManager->getSpellingLineNumber(RParenLoc);
+unsigned RParenColumn =
+Result.SourceManager->getSpellingColumnNumber(RParenLoc);
+
+if (LParenLine != ExpectLParenLine || LParenColumn != ExpectLParenColumn ||
+RParenLine != ExpectRParenLine || RParenColumn != ExpectRParenColumn) {
+  std::string MsgStr;
+  llvm::raw_string_ostream Msg(MsgStr);
+  Msg << "Expected LParen Location <" << ExpectLParenLine << ":"
+  << ExpectLParenColumn << ">, found <";
+  LParenLoc.print(Msg, *Result.SourceManager);
+  Msg << ">\n";
+
+  Msg << "Expected RParen Location <" << ExpectRParenLine << ":"
+  << ExpectRParenColumn << ">, found <";
+  RParenLoc.print(Msg, *Result.SourceManager);
+  Msg << ">";
+
+  this->setFailure(Msg.str());
+}
+  }
+};
+
+TEST(LocationVerifier, WhileParenLoc) {
+  WhileParenLocationVerifier Verifier;
+  Verifier.expectLocations(1, 17, 1, 38);
+  EXPECT_TRUE(Verifier.match("void f() { while(true/*some comment*/) {} }",
+ whileStmt()));
+}
+
 class LabelDeclRangeVerifier : public RangeVerifier {
 protected:
   SourceRange getRange(const LabelStmt &Node) override {
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -194,6 +194,8 @@
 Record.AddDeclRef(S->getConditionVariable());
 
   Record.AddSourceLocation(S->getWhileLoc());
+  Record.AddSourceLocation(S->getLParenLoc());
+  Record.AddSourceLocation(S->getRParenLoc());
   Code = serialization::STMT_WHILE;
 }
 
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -271,6 +271,8 @@
 S->setConditionVariable(Record.getContext(), readDeclAs());
 
   S->setWhileLoc(readSourceLocation());
+  S->setLParenLoc(readSourceLocation());
+  S->setRParenLoc(readSourceLocation());
 }
 
 void ASTStmtReader::VisitDoStmt(DoStmt *S) {
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -1347,9 +1347,10 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
-  Sema::ConditionResult Cond, Stmt *Body) {
-return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
+  Sema::ConditionResult Cond,
+  SourceLocation RParenLoc, Stmt *Body) {
+return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
   }
 
   /// Build a new do-while statement.
@@ -7335,7 +7336,8 @@
   Body.get() == S->getBody())
 return Owned(S);
 
-  return getDerived().RebuildWhileStmt(S->getWhileLoc

[PATCH] D83529: Summary: [clang] Provide a way for WhileStmt to report the location of its LParen and RParen.

2020-07-10 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D83529#2145087 , @riccibruno wrote:

> No objection from me, but I am not a reviewer. I am just accepting this to 
> cancel my comment on the missing serialization.


No worries. Thanks for your input!

I think Dmitri has already accepted this (pending additional test and variables 
renaming, which I've done). 
I'm re-running the sanitizer tests to make sure it's not related then will 
commit, unless someone else would like to chime in ...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83529/new/

https://reviews.llvm.org/D83529



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83529: Summary: [clang] Provide a way for WhileStmt to report the location of its LParen and RParen.

2020-07-10 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 277115.
oontvoo marked 3 inline comments as done.
oontvoo added a comment.

Added unit test and the missing serialisation code


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83529/new/

https://reviews.llvm.org/D83529

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/unittests/AST/SourceLocationTest.cpp

Index: clang/unittests/AST/SourceLocationTest.cpp
===
--- clang/unittests/AST/SourceLocationTest.cpp
+++ clang/unittests/AST/SourceLocationTest.cpp
@@ -60,6 +60,59 @@
   EXPECT_FALSE(Verifier.match("int i;", varDecl()));
 }
 
+class WhileParenLocationVerifier : public MatchVerifier {
+  unsigned ExpectLParenLine = 0, ExpectLParenColumn = 0;
+  unsigned ExpectRParenLine = 0, ExpectRParenColumn = 0;
+
+public:
+  void expectLocations(unsigned LParenLine, unsigned LParenColumn,
+   unsigned RParenLine, unsigned RParenColumn) {
+ExpectLParenLine = LParenLine;
+ExpectLParenColumn = LParenColumn;
+ExpectRParenLine = RParenLine;
+ExpectRParenColumn = RParenColumn;
+  }
+
+protected:
+  void verify(const MatchFinder::MatchResult &Result,
+  const WhileStmt &Node) override {
+SourceLocation LParenLoc = Node.getLParenLoc();
+SourceLocation RParenLoc = Node.getRParenLoc();
+unsigned LParenLine =
+Result.SourceManager->getSpellingLineNumber(LParenLoc);
+unsigned LParenColumn =
+Result.SourceManager->getSpellingColumnNumber(LParenLoc);
+unsigned RParenLine =
+Result.SourceManager->getSpellingLineNumber(RParenLoc);
+unsigned RParenColumn =
+Result.SourceManager->getSpellingColumnNumber(RParenLoc);
+
+if (LParenLine != ExpectLParenLine || LParenColumn != ExpectLParenColumn ||
+RParenLine != ExpectRParenLine || RParenColumn != ExpectRParenColumn) {
+  std::string MsgStr;
+  llvm::raw_string_ostream Msg(MsgStr);
+  Msg << "Expected LParen Location <" << ExpectLParenLine << ":"
+  << ExpectLParenColumn << ">, found <";
+  LParenLoc.print(Msg, *Result.SourceManager);
+  Msg << ">\n";
+
+  Msg << "Expected RParen Location <" << ExpectRParenLine << ":"
+  << ExpectRParenColumn << ">, found <";
+  RParenLoc.print(Msg, *Result.SourceManager);
+  Msg << ">";
+
+  this->setFailure(Msg.str());
+}
+  }
+};
+
+TEST(LocationVerifier, WhileParenLoc) {
+  WhileParenLocationVerifier Verifier;
+  Verifier.expectLocations(1, 17, 1, 38);
+  EXPECT_TRUE(Verifier.match("void f() { while(true/*some comment*/) {} }",
+ whileStmt()));
+}
+
 class LabelDeclRangeVerifier : public RangeVerifier {
 protected:
   SourceRange getRange(const LabelStmt &Node) override {
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -194,6 +194,8 @@
 Record.AddDeclRef(S->getConditionVariable());
 
   Record.AddSourceLocation(S->getWhileLoc());
+  Record.AddSourceLocation(S->getLParenLoc());
+  Record.AddSourceLocation(S->getRParenLoc());
   Code = serialization::STMT_WHILE;
 }
 
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -271,6 +271,8 @@
 S->setConditionVariable(Record.getContext(), readDeclAs());
 
   S->setWhileLoc(readSourceLocation());
+  S->setLParenLoc(readSourceLocation());
+  S->setRParenLoc(readSourceLocation());
 }
 
 void ASTStmtReader::VisitDoStmt(DoStmt *S) {
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -1347,9 +1347,10 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
-  Sema::ConditionResult Cond, Stmt *Body) {
-return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
+  Sema::ConditionResult Cond,
+  SourceLocation RParenLoc, Stmt *Body) {
+return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
   }
 
   /// Build a new do-while statement.
@@ -7335,7 +7336,8 @@
   Body.get() == S->get

[PATCH] D83529: Summary: [clang] Provide a way for WhileStmt to report the location of its LParen and RParen.

2020-07-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
Herald added subscribers: cfe-commits, martong.
Herald added a reviewer: shafik.
Herald added a project: clang.

This helps avoiding hacks downstream.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83529

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Stmt.cpp
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp

Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -271,6 +271,8 @@
 S->setConditionVariable(Record.getContext(), readDeclAs());
 
   S->setWhileLoc(readSourceLocation());
+  S->setLParenLoc(readSourceLocation());
+  S->setRParenLoc(readSourceLocation());
 }
 
 void ASTStmtReader::VisitDoStmt(DoStmt *S) {
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -1347,9 +1347,10 @@
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
-  Sema::ConditionResult Cond, Stmt *Body) {
-return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
+  Sema::ConditionResult Cond,
+  SourceLocation RParenLoc, Stmt *Body) {
+return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
   }
 
   /// Build a new do-while statement.
@@ -7335,7 +7336,8 @@
   Body.get() == S->getBody())
 return Owned(S);
 
-  return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get());
+  return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
+   Cond, S->getRParenLoc(), Body.get());
 }
 
 template
Index: clang/lib/Sema/SemaStmt.cpp
===
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -1328,8 +1328,9 @@
 }
 }
 
-StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
-Stmt *Body) {
+StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc,
+SourceLocation LParenLoc, ConditionResult Cond,
+SourceLocation RParenLoc, Stmt *Body) {
   if (Cond.isInvalid())
 return StmtError();
 
@@ -1344,7 +1345,7 @@
 getCurCompoundScope().setHasEmptyLoopBodies();
 
   return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body,
-   WhileLoc);
+   WhileLoc, LParenLoc, RParenLoc);
 }
 
 StmtResult
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1156,10 +1156,14 @@
 /// should try to recover harder.  It returns false if the condition is
 /// successfully parsed.  Note that a successful parse can still have semantic
 /// errors in the condition.
+/// Additionally, if LParenLoc and RParenLoc are non-null, it will assign
+/// the location of the outer-most '(' and ')', respectively, to them.
 bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
Sema::ConditionResult &Cond,
SourceLocation Loc,
-   Sema::ConditionKind CK) {
+   Sema::ConditionKind CK,
+   SourceLocation *LParenLoc,
+   SourceLocation *RParenLoc) {
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
 
@@ -1189,6 +1193,13 @@
   // Otherwise the condition is valid or the rparen is present.
   T.consumeClose();
 
+  if (LParenLoc != nullptr) {
+*LParenLoc = T.getOpenLocation();
+  }
+  if (RParenLoc != nullptr) {
+*RParenLoc = T.getCloseLocation();
+  }
+
   // Check for extraneous ')'s to catch things like "if (foo())) {".  We know
   // that all callers are looking for a statement after the condition, so ")"
   // isn't valid.
@@ -1582,8 +1593,10 @@
 
   // Parse the condition.
   Sema::ConditionResult Cond;
+  SourceLocation LParen;
+  SourceLocation RParen;
   if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc,
-Sema::ConditionKind::Boolean))
+Sema::ConditionKind::Boolean, &LParen, &RParen))
 return StmtError();
 
   // C99 6.8.5p5 - In C99,

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-07 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 276084.
oontvoo added a comment.

one more test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/attr-trivial-abi.cpp
  clang/test/SemaObjCXX/attr-trivial-abi.mm

Index: clang/test/SemaObjCXX/attr-trivial-abi.mm
===
--- clang/test/SemaObjCXX/attr-trivial-abi.mm
+++ clang/test/SemaObjCXX/attr-trivial-abi.mm
@@ -57,7 +57,7 @@
 };
 
 // Do not warn when 'trivial_abi' is used to annotate a template class.
-template
+template 
 struct __attribute__((trivial_abi)) S10 {
   T p;
 };
@@ -76,21 +76,27 @@
   __weak id b;
 };
 
-template
+template 
 struct __attribute__((trivial_abi)) S15 : S14 {
 };
 
 S15 s15;
 
-template
+template 
 struct __attribute__((trivial_abi)) S16 {
   S14 a;
 };
 
 S16 s16;
 
-template
+template 
 struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}}
+  S17();
+  S17(S17 &&);
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}}
   __weak id a;
 };
 
Index: clang/test/SemaCXX/attr-trivial-abi.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+// Should not crash.
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
+  virtual void m();
+};
+
+struct S3_2 {
+  virtual void m();
+} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
+
+struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
+  S3_3(S3_3 &&);
+  S3_2 s32;
+};
+
+// Diagnose invalid trivial_abi even when the type is templated because it has a non-trivial field.
+template 
+struct __attribute__((trivial_abi)) S3_4 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_4'}} expected-note {{has a field of a non-trivial class type}}
+  S3_4(S3_4 &&);
+  S3_2 s32;
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+// Do not warn about deleted ctors  when 'trivial_abi' is used to annotate a template class.
+template 
+struct __attribute__((trivial_abi)) S10 {
+  T p;
+};
+
+S10 p1;
+
+template 
+struct S14 {
+  T a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S15 : S14 {
+};
+
+S15 s15;
+
+template 
+struct __attribute__((trivial_abi)) S16 {
+  S14 a;
+};
+
+S16 s16;
+
+template 
+struct __attribute__((trivial_abi)) S17 {
+};
+
+S17 s17;
+
+namespace deletedCopyMoveConstructor {
+struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted a;
+};
+
+struct __attribute__((trivial_abi)) CopyDeleted {
+  CopyDeleted(const CopyDeleted &) = delete;
+  CopyDeleted(CopyDeleted &&) = default;
+};
+
+struct __attribute__((trivial_abi)) MoveDeleted {
+  MoveDeleted(const MoveDeleted &) = default;
+  MoveDeleted(MoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyDeleted a;
+  MoveDeleted b;
+};
+
+// This is fine since the move constructor isn't deleted.
+struct __attribute__((trivial_abi)) S20 {
+  int &&a; // a member of rvalue reference type deletes the copy constructor.
+};
+} // namespace deletedCopyMoveConstructor
Index: clang/lib/Sema/SemaDeclCXX.cpp
===

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-07 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 276077.
oontvoo added a comment.

lint


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/attr-trivial-abi.cpp
  clang/test/SemaObjCXX/attr-trivial-abi.mm

Index: clang/test/SemaObjCXX/attr-trivial-abi.mm
===
--- clang/test/SemaObjCXX/attr-trivial-abi.mm
+++ clang/test/SemaObjCXX/attr-trivial-abi.mm
@@ -57,7 +57,7 @@
 };
 
 // Do not warn when 'trivial_abi' is used to annotate a template class.
-template
+template 
 struct __attribute__((trivial_abi)) S10 {
   T p;
 };
@@ -76,21 +76,27 @@
   __weak id b;
 };
 
-template
+template 
 struct __attribute__((trivial_abi)) S15 : S14 {
 };
 
 S15 s15;
 
-template
+template 
 struct __attribute__((trivial_abi)) S16 {
   S14 a;
 };
 
 S16 s16;
 
-template
+template 
 struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}}
+  S17();
+  S17(S17 &&);
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}}
   __weak id a;
 };
 
Index: clang/test/SemaCXX/attr-trivial-abi.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+// Should not crash.
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
+  virtual void m();
+};
+
+struct S3_2 {
+  virtual void m();
+} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
+
+struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
+  S3_3(S3_3 &&);
+  S3_2 s32;
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+// Do not warn when 'trivial_abi' is used to annotate a template class.
+template 
+struct __attribute__((trivial_abi)) S10 {
+  T p;
+};
+
+S10 p1;
+
+template 
+struct S14 {
+  T a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S15 : S14 {
+};
+
+S15 s15;
+
+template 
+struct __attribute__((trivial_abi)) S16 {
+  S14 a;
+};
+
+S16 s16;
+
+template 
+struct __attribute__((trivial_abi)) S17 {
+};
+
+S17 s17;
+
+namespace deletedCopyMoveConstructor {
+struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted a;
+};
+
+struct __attribute__((trivial_abi)) CopyDeleted {
+  CopyDeleted(const CopyDeleted &) = delete;
+  CopyDeleted(CopyDeleted &&) = default;
+};
+
+struct __attribute__((trivial_abi)) MoveDeleted {
+  MoveDeleted(const MoveDeleted &) = default;
+  MoveDeleted(MoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyDeleted a;
+  MoveDeleted b;
+};
+
+// This is fine since the move constructor isn't deleted.
+struct __attribute__((trivial_abi)) S20 {
+  int &&a; // a member of rvalue reference type deletes the copy constructor.
+};
+} // namespace deletedCopyMoveConstructor
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9719,6 +9719,10 @@
 
   // Ill-formed if the copy and move constructors are deleted.
   auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+// If the type is dependent, then assume it might have
+// implicit copy or move ctor because we won't know yet at this point.

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-07 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 276076.
oontvoo marked 2 inline comments as done.
oontvoo added a comment.

prevent diagnostics for dependent types


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/attr-trivial-abi.cpp
  clang/test/SemaObjCXX/attr-trivial-abi.mm

Index: clang/test/SemaObjCXX/attr-trivial-abi.mm
===
--- clang/test/SemaObjCXX/attr-trivial-abi.mm
+++ clang/test/SemaObjCXX/attr-trivial-abi.mm
@@ -57,7 +57,7 @@
 };
 
 // Do not warn when 'trivial_abi' is used to annotate a template class.
-template
+template 
 struct __attribute__((trivial_abi)) S10 {
   T p;
 };
@@ -76,21 +76,27 @@
   __weak id b;
 };
 
-template
+template 
 struct __attribute__((trivial_abi)) S15 : S14 {
 };
 
 S15 s15;
 
-template
+template 
 struct __attribute__((trivial_abi)) S16 {
   S14 a;
 };
 
 S16 s16;
 
-template
+template 
 struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}}
+  S17();
+  S17(S17 &&);
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}}
   __weak id a;
 };
 
Index: clang/test/SemaCXX/attr-trivial-abi.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+// Should not crash.
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
+  virtual void m();
+};
+
+struct S3_2 {
+  virtual void m();
+} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
+
+struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
+  S3_3(S3_3 &&);
+  S3_2 s32;
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+// Do not warn when 'trivial_abi' is used to annotate a template class.
+template 
+struct __attribute__((trivial_abi)) S10 {
+  T p;
+};
+
+S10 p1;
+
+template 
+struct S14 {
+  T a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S15 : S14 {
+};
+
+S15 s15;
+
+template 
+struct __attribute__((trivial_abi)) S16 {
+  S14 a;
+};
+
+S16 s16;
+
+template 
+struct __attribute__((trivial_abi)) S17 {
+};
+
+S17 s17;
+
+namespace deletedCopyMoveConstructor {
+struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted a;
+};
+
+struct __attribute__((trivial_abi)) CopyDeleted {
+  CopyDeleted(const CopyDeleted &) = delete;
+  CopyDeleted(CopyDeleted &&) = default;
+};
+
+struct __attribute__((trivial_abi)) MoveDeleted {
+  MoveDeleted(const MoveDeleted &) = default;
+  MoveDeleted(MoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyDeleted a;
+  MoveDeleted b;
+};
+
+// This is fine since the move constructor isn't deleted.
+struct __attribute__((trivial_abi)) S20 {
+  int &&a; // a member of rvalue reference type deletes the copy constructor.
+};
+} // namespace deletedCopyMoveConstructor
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9719,6 +9719,10 @@
 
   // Ill-formed if the copy and move constructors are deleted.
   auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+// Only check if the type is dependent, then assume i

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 275899.
oontvoo added a comment.

updated diff


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/attr-trivial-abi.cpp
  clang/test/SemaObjCXX/attr-trivial-abi.mm

Index: clang/test/SemaObjCXX/attr-trivial-abi.mm
===
--- clang/test/SemaObjCXX/attr-trivial-abi.mm
+++ clang/test/SemaObjCXX/attr-trivial-abi.mm
@@ -56,9 +56,8 @@
   int a;
 };
 
-// Do not warn when 'trivial_abi' is used to annotate a template class.
-template
-struct __attribute__((trivial_abi)) S10 {
+template 
+struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi' cannot be applied to 'S10}}'  expected-note {{copy constructors and move constructors are all deleted}}
   T p;
 };
 
@@ -76,21 +75,27 @@
   __weak id b;
 };
 
-template
-struct __attribute__((trivial_abi)) S15 : S14 {
+template 
+struct __attribute__((trivial_abi)) S15 : S14 { // expected-warning {{'trivial_abi' cannot be applied to 'S15'}} expected-note {{copy constructors and move constructors are all deleted}}
 };
 
 S15 s15;
 
-template
-struct __attribute__((trivial_abi)) S16 {
+template 
+struct __attribute__((trivial_abi)) S16 { // expected-warning {{'trivial_abi' cannot be applied to 'S16'}} expected-note {{copy constructors and move constructors are all deleted}}
   S14 a;
 };
 
 S16 s16;
 
-template
+template 
 struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}}
+  S17();
+  S17(S17 &&);
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}}
   __weak id a;
 };
 
Index: clang/test/SemaCXX/attr-trivial-abi.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+// Should not crash.
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
+  virtual void m();
+};
+
+struct S3_2 {
+  virtual void m();
+} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
+
+struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
+  S3_3(S3_3 &&);
+  S3_2 s32;
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi' cannot be applied to 'S10}}'  expected-note {{copy constructors and move constructors are all deleted}}
+  T p;
+};
+
+S10 p1;
+
+template 
+struct S14 {
+  T a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S15 : S14 { // expected-warning {{'trivial_abi' cannot be applied to 'S15'}} expected-note {{copy constructors and move constructors are all deleted}}
+};
+
+S15 s15;
+
+template 
+struct __attribute__((trivial_abi)) S16 { // expected-warning {{'trivial_abi' cannot be applied to 'S16'}} expected-note {{copy constructors and move constructors are all deleted}}
+  S14 a;
+};
+
+S16 s16;
+
+template 
+struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{copy constructors and move constructors are all deleted}}
+};
+
+S17 s17;
+
+namespace deletedCopyMoveConstructor {
+struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted a;
+};
+
+struct __attribute__((trivial_abi)) CopyDeleted {
+  CopyDeleted(const CopyDeleted &) = delete;
+  CopyDeleted(CopyDeleted &&) = default;

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 275898.
oontvoo added a comment.

updated diff


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/attr-trivial-abi.cpp
  clang/test/SemaObjCXX/attr-trivial-abi.mm

Index: clang/test/SemaObjCXX/attr-trivial-abi.mm
===
--- clang/test/SemaObjCXX/attr-trivial-abi.mm
+++ clang/test/SemaObjCXX/attr-trivial-abi.mm
@@ -57,8 +57,8 @@
 };
 
 // Do not warn when 'trivial_abi' is used to annotate a template class.
-template
-struct __attribute__((trivial_abi)) S10 {
+template 
+struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi' cannot be applied to 'S10}}'  expected-note {{copy constructors and move constructors are all deleted}}
   T p;
 };
 
@@ -76,21 +76,25 @@
   __weak id b;
 };
 
-template
-struct __attribute__((trivial_abi)) S15 : S14 {
+template 
+struct __attribute__((trivial_abi)) S15 : S14 { // expected-warning {{'trivial_abi' cannot be applied to 'S15'}} expected-note {{copy constructors and move constructors are all deleted}}
 };
 
 S15 s15;
 
-template
-struct __attribute__((trivial_abi)) S16 {
+template 
+struct __attribute__((trivial_abi)) S16 { // expected-warning {{'trivial_abi' cannot be applied to 'S16'}} expected-note {{copy constructors and move constructors are all deleted}}
   S14 a;
 };
 
 S16 s16;
 
-template
-struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}}
+template 
+struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{copy constructors and move constructors are all deleted}}
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}}
   __weak id a;
 };
 
Index: clang/test/SemaCXX/attr-trivial-abi.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+// Should not crash.
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
+  virtual void m();
+};
+
+struct S3_2 {
+  virtual void m();
+} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
+
+struct __attribute__((trivial_abi)) S3_3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3_3'}} expected-note {{has a field of a non-trivial class type}}
+  S3_3(S3_3 &&);
+  S3_2 s32;
+};
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi' cannot be applied to 'S10}}'  expected-note {{copy constructors and move constructors are all deleted}}
+  T p;
+};
+
+S10 p1;
+
+template 
+struct S14 {
+  T a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S15 : S14 { // expected-warning {{'trivial_abi' cannot be applied to 'S15'}} expected-note {{copy constructors and move constructors are all deleted}}
+};
+
+S15 s15;
+
+template 
+struct __attribute__((trivial_abi)) S16 { // expected-warning {{'trivial_abi' cannot be applied to 'S16'}} expected-note {{copy constructors and move constructors are all deleted}}
+  S14 a;
+};
+
+S16 s16;
+
+template 
+struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{copy constructors and move constructors are all deleted}}
+};
+
+S17 s17;
+
+namespace deletedCopyMoveConstructor {
+struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted a

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 275895.
oontvoo added a comment.

Add more tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/attr-trivial-abi.cpp
  clang/test/SemaObjCXX/attr-trivial-abi.mm

Index: clang/test/SemaObjCXX/attr-trivial-abi.mm
===
--- clang/test/SemaObjCXX/attr-trivial-abi.mm
+++ clang/test/SemaObjCXX/attr-trivial-abi.mm
@@ -57,8 +57,8 @@
 };
 
 // Do not warn when 'trivial_abi' is used to annotate a template class.
-template
-struct __attribute__((trivial_abi)) S10 {
+template 
+struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi' cannot be applied to 'S10}}'  expected-note {{copy constructors and move constructors are all deleted}}
   T p;
 };
 
@@ -76,21 +76,25 @@
   __weak id b;
 };
 
-template
-struct __attribute__((trivial_abi)) S15 : S14 {
+template 
+struct __attribute__((trivial_abi)) S15 : S14 { // expected-warning {{'trivial_abi' cannot be applied to 'S15'}} expected-note {{copy constructors and move constructors are all deleted}}
 };
 
 S15 s15;
 
-template
-struct __attribute__((trivial_abi)) S16 {
+template 
+struct __attribute__((trivial_abi)) S16 { // expected-warning {{'trivial_abi' cannot be applied to 'S16'}} expected-note {{copy constructors and move constructors are all deleted}}
   S14 a;
 };
 
 S16 s16;
 
-template
-struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{has a __weak field}}
+template 
+struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{copy constructors and move constructors are all deleted}}
+  __weak id a;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{has a __weak field}}
   __weak id a;
 };
 
Index: clang/test/SemaCXX/attr-trivial-abi.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/attr-trivial-abi.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+void __attribute__((trivial_abi)) foo(); // expected-warning {{'trivial_abi' attribute only applies to classes}}
+
+// Should not crash.
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
+
+struct [[clang::trivial_abi]] S0 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S1 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S3 { // expected-warning {{'trivial_abi' cannot be applied to 'S3'}} expected-note {{is polymorphic}}
+  virtual void m();
+};
+
+struct S3_2 {
+  virtual void m();
+} __attribute__((trivial_abi)); // expected-warning {{'trivial_abi' cannot be applied to 'S3_2'}} expected-note {{is polymorphic}}
+
+struct S4 {
+  int a;
+};
+
+struct __attribute__((trivial_abi)) S5 : public virtual S4 { // expected-warning {{'trivial_abi' cannot be applied to 'S5'}} expected-note {{has a virtual base}}
+};
+
+struct __attribute__((trivial_abi)) S9 : public S4 {
+};
+
+struct __attribute__((trivial_abi(1))) S8 { // expected-error {{'trivial_abi' attribute takes no arguments}}
+  int a;
+};
+
+// Do not warn when 'trivial_abi' is used to annotate a template class.
+template 
+struct __attribute__((trivial_abi)) S10 { // expected-warning {{'trivial_abi' cannot be applied to 'S10}}'  expected-note {{copy constructors and move constructors are all deleted}}
+  T p;
+};
+
+S10 p1;
+
+template 
+struct S14 {
+  T a;
+};
+
+template 
+struct __attribute__((trivial_abi)) S15 : S14 { // expected-warning {{'trivial_abi' cannot be applied to 'S15'}} expected-note {{copy constructors and move constructors are all deleted}}
+};
+
+S15 s15;
+
+template 
+struct __attribute__((trivial_abi)) S16 { // expected-warning {{'trivial_abi' cannot be applied to 'S16'}} expected-note {{copy constructors and move constructors are all deleted}}
+  S14 a;
+};
+
+S16 s16;
+
+template 
+struct __attribute__((trivial_abi)) S17 { // expected-warning {{'trivial_abi' cannot be applied to 'S17'}} expected-note {{copy constructors and move constructors are all deleted}}
+};
+
+S17 s17;
+
+namespace deletedCopyMoveConstructor {
+struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+  CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+};
+
+struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}} expected-note {{copy constructors and move constructors are all deleted}}
+  CopyMoveDeleted a;
+};
+
+struct __attribute__((trivial_abi)) CopyDeleted {
+  CopyDeleted(const CopyDeleted &) = delete;
+  CopyDeleted(CopyDelete

[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 275885.
oontvoo added a comment.

Dont skip checking even for templated type


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/trivial-abi-templated-type.cpp


Index: clang/test/SemaCXX/trivial-abi-templated-type.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/trivial-abi-templated-type.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// expected-no-diagnostics
+
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9719,6 +9719,11 @@
 
   // Ill-formed if the copy and move constructors are deleted.
   auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+// If we know there exist users-defined move/copy ctors, don't try to infer
+// the deletion of implicit ones becausee Sema may not have the info yet.
+if (RD.hasUserDeclaredMoveConstructor() ||
+RD.hasUserDeclaredCopyConstructor())
+  return true;
 if (RD.needsImplicitCopyConstructor() &&
 !RD.defaultedCopyConstructorIsDeleted())
   return true;


Index: clang/test/SemaCXX/trivial-abi-templated-type.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/trivial-abi-templated-type.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// expected-no-diagnostics
+
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9719,6 +9719,11 @@
 
   // Ill-formed if the copy and move constructors are deleted.
   auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+// If we know there exist users-defined move/copy ctors, don't try to infer
+// the deletion of implicit ones becausee Sema may not have the info yet.
+if (RD.hasUserDeclaredMoveConstructor() ||
+RD.hasUserDeclaredCopyConstructor())
+  return true;
 if (RD.needsImplicitCopyConstructor() &&
 !RD.defaultedCopyConstructorIsDeleted())
   return true;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 275866.
oontvoo added a comment.

add test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83263/new/

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/trivial-abi-templated-type.cpp


Index: clang/test/SemaCXX/trivial-abi-templated-type.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/trivial-abi-templated-type.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// expected-no-diagnostics
+
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -6591,7 +6591,7 @@
   }
 
   // See if trivial_abi has to be dropped.
-  if (Record->hasAttr())
+  if (!Record->isDependentType() && Record->hasAttr())
 checkIllFormedTrivialABIStruct(*Record);
 
   // Set HasTrivialSpecialMemberForCall if the record has attribute


Index: clang/test/SemaCXX/trivial-abi-templated-type.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/trivial-abi-templated-type.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// expected-no-diagnostics
+
+template 
+class __attribute__((trivial_abi)) a { a(a &&); };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -6591,7 +6591,7 @@
   }
 
   // See if trivial_abi has to be dropped.
-  if (Record->hasAttr())
+  if (!Record->isDependentType() && Record->hasAttr())
 checkIllFormedTrivialABIStruct(*Record);
 
   // Set HasTrivialSpecialMemberForCall if the record has attribute
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83263: [WIP] Clang crashed while checking for deletion of copy and move ctors

2020-07-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repro:

- Annotate the unique_ptr class with trivial_abi (eg., 
https://godbolt.org/z/-rprsc)
- ./build/bin/clang++ -stdlib=libc++ -I../libcxx/memory

Crash:

  @ 0x559d129463fc  
clang::CXXRecordDecl::defaultedCopyConstructorIsDeleted()
   @ 0x559d1288d3e5  
clang::Sema::checkIllFormedTrivialABIStruct()::$_7::operator()()
   @ 0x559d12884c34  clang::Sema::checkIllFormedTrivialABIStruct()
   @ 0x559d1288412e  clang::Sema::CheckCompletedCXXClass()
   @ 0x559d1288d843  clang::Sema::ActOnFinishCXXMemberSpecification()
   @ 0x559d12020109  clang::Parser::ParseCXXMemberSpecification()
   @ 0x559d1201e80c  clang::Parser::ParseClassSpecifier()
   @ 0x559d1204e807  clang::Parser::ParseDeclarationSpecifiers()
   @ 0x559d120e9aa9  clang::Parser::ParseSingleDeclarationAfterTemplate()
   @ 0x559d120e8f21  
clang::Parser::ParseTemplateDeclarationOrSpecialization()
   @ 0x559d120e8886  clang::Parser::ParseDeclarationStartingWithTemplate()
   @ 0x559d1204a1d4  clang::Parser::ParseDeclaration()
   @ 0x559d12004b1d  clang::Parser::ParseExternalDeclaration()
   @ 0x559d12017689  clang::Parser::ParseInnerNamespace()
   @ 0x559d12017024  clang::Parser::ParseNamespace()
   @ 0x559d1204a29b  clang::Parser::ParseDeclaration()
   @ 0x559d12004c74  clang::Parser::ParseExternalDeclaration()


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83263

Files:
  clang/lib/Sema/SemaDeclCXX.cpp


Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9719,6 +9719,11 @@
 
   // Ill-formed if the copy and move constructors are deleted.
   auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+// If we know there exist users-defined move/copy ctors, don't try to infer
+// the deletion of implicit ones becausee Sema may not have the info yet.
+if (RD.hasUserDeclaredMoveConstructor() ||
+RD.hasUserDeclaredCopyConstructor())
+  return true;
 if (RD.needsImplicitCopyConstructor() &&
 !RD.defaultedCopyConstructorIsDeleted())
   return true;


Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9719,6 +9719,11 @@
 
   // Ill-formed if the copy and move constructors are deleted.
   auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+// If we know there exist users-defined move/copy ctors, don't try to infer
+// the deletion of implicit ones becausee Sema may not have the info yet.
+if (RD.hasUserDeclaredMoveConstructor() ||
+RD.hasUserDeclaredCopyConstructor())
+  return true;
 if (RD.needsImplicitCopyConstructor() &&
 !RD.defaultedCopyConstructorIsDeleted())
   return true;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81444: Make the diagnostic-missing-prototypes put the suggested `static` in front of `const` if exists.

2020-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa21a46205165: Make the diagnostic-missing-prototypes put the 
suggested `static` in front of… (authored by oontvoo).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81444/new/

https://reviews.llvm.org/D81444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/warn-missing-prototypes.c

Index: clang/test/Sema/warn-missing-prototypes.c
===
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,60 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  return (void *)0;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous prototype for function 'get_struct'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Turn off clang-format for white-space dependent testing.
+// clang-format off
+// Two spaces between cost and struct
+const  struct MyStruct get_struct_2() {  // expected-warning{{no previous prototype for function 'get_struct_2'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Two spaces bewteen const and struct
+const  struct MyStruct* get_struct_ptr() {  // expected-warning{{no previous prototype for function 'get_struct_ptr'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  return (void*)0;
+}
+
+// Random comment before const.
+/*some randome comment*/const  struct MyStruct* get_struct_3() {  // expected-warning{{no previous prototype for function 'get_struct_3'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:25-[[@LINE-2]]:25}:"static "
+  return (void*)0;
+}
+
+// Random comment after const.
+const/*some randome comment*/ struct MyStruct* get_struct_4() {  // expected-warning{{no previous prototype for function 'get_struct_4'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  return (void*)0;
+}
+// clang-format on
+
+#define MY_CONST const
+
+// Since we can't easily understand what MY_CONST means while preparing the
+// diagnostic, the fix-it suggests to add 'static' in a non-idiomatic place.
+MY_CONST struct MyStruct *get_struct_nyi() { // expected-warning{{no previous prototype for function 'get_struct_nyi'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"static "
+  return (void *)0;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,48 @@
 : FixItHint{});
 }
   } else {
+// Returns true if the token beginning at this Loc is `const`.
+auto isLocAtConst = [&](SourceLocation Loc, const SourceManager &SM,
+const LangOptions &LangOpts) {
+  std::pair LocInfo = SM.getDecomposedLoc(Loc);
+  if (LocInfo.first.isInvalid())
+return false;
+
+  bool Invalid = false;
+  StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+return false;
+
+  if (LocInfo.second > Buffer.size())
+return false;
+
+  const char *LexStart = Buffer.data() + LocInfo.second;
+  StringRef StartTok(LexStart, Buffer.size() - LocInfo.second);
+
+  return StartTok.consume_front("const") &&
+ (StartTok.empty() || isWhitespace(StartTok[0]) ||
+  StartTok.startswith("/*") || StartTok.startswith("//"));
+   

[PATCH] D81444: Make the diagnostic-missing-prototypes put the suggested `static` in front of `const` if exists.

2020-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 269657.
oontvoo marked an inline comment as done.
oontvoo added a comment.

Address review comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81444/new/

https://reviews.llvm.org/D81444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/warn-missing-prototypes.c

Index: clang/test/Sema/warn-missing-prototypes.c
===
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,60 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  return (void *)0;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous prototype for function 'get_struct'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Turn off clang-format for white-space dependent testing.
+// clang-format off
+// Two spaces between cost and struct
+const  struct MyStruct get_struct_2() {  // expected-warning{{no previous prototype for function 'get_struct_2'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Two spaces bewteen const and struct
+const  struct MyStruct* get_struct_ptr() {  // expected-warning{{no previous prototype for function 'get_struct_ptr'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  return (void*)0;
+}
+
+// Random comment before const.
+/*some randome comment*/const  struct MyStruct* get_struct_3() {  // expected-warning{{no previous prototype for function 'get_struct_3'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:25-[[@LINE-2]]:25}:"static "
+  return (void*)0;
+}
+
+// Random comment after const.
+const/*some randome comment*/ struct MyStruct* get_struct_4() {  // expected-warning{{no previous prototype for function 'get_struct_4'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  return (void*)0;
+}
+// clang-format on
+
+#define MY_CONST const
+
+// Since we can't easily understand what MY_CONST means while preparing the
+// diagnostic, the fix-it suggests to add 'static' in a non-idiomatic place.
+MY_CONST struct MyStruct *get_struct_nyi() { // expected-warning{{no previous prototype for function 'get_struct_nyi'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"static "
+  return (void *)0;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,48 @@
 : FixItHint{});
 }
   } else {
+// Returns true if the token beginning at this Loc is `const`.
+auto isLocAtConst = [&](SourceLocation Loc, const SourceManager &SM,
+const LangOptions &LangOpts) {
+  std::pair LocInfo = SM.getDecomposedLoc(Loc);
+  if (LocInfo.first.isInvalid())
+return false;
+
+  bool Invalid = false;
+  StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+return false;
+
+  if (LocInfo.second > Buffer.size())
+return false;
+
+  const char *LexStart = Buffer.data() + LocInfo.second;
+  StringRef StartTok(LexStart, Buffer.size() - LocInfo.second);
+
+  return StartTok.consume_front("const") &&
+ (StartTok.empty() || isWhitespace(StartTok[0]) ||
+  StartTok.startswith("/*") || StartTok.startswith("//"));
+};
+
+auto findBeginLoc = [&]() {
+  // If the return t

[PATCH] D81444: Make the diagnostic-missing-prototypes put the suggested `static` in front of `const` if exists.

2020-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo marked 7 inline comments as done.
oontvoo added inline comments.



Comment at: clang/test/Sema/warn-missing-prototypes.c:62
+
+const struct MyStruct get_struct() { // expected-warning{{no previous 
prototype for function 'get_struct'}}
+ // expected-note@-1{{declare 'static' if 
the function is not intended to be used outside of this translation unit}}

gribozavr2 wrote:
> Did you mean to return a pointer to MyStruct? The top-level const is not 
> meaningful.
No, I actually intended to test the top-level const. Though not being 
meaningful, it's still syntactically correct.
But now that you've mentioned it, I should add a test for  `MyStruct* ` too.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81444/new/

https://reviews.llvm.org/D81444



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81444: Make the diagnostic-missing-prototypes put the suggested `static` in front of `const` if exists.

2020-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 269627.
oontvoo marked an inline comment as done.
oontvoo added a comment.

- Less brittle way to find the loc of const.
- Add more tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81444/new/

https://reviews.llvm.org/D81444

Files:
  clang/include/clang/Lex/Lexer.h
  clang/lib/Lex/Lexer.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/warn-missing-prototypes.c

Index: clang/test/Sema/warn-missing-prototypes.c
===
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,57 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  int *ret;
+  return ret;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous prototype for function 'get_struct'}}
+ // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Turn off clang-format for white-space dependent testing.
+// clang-format off
+// Two spaces between cost and struct
+const  struct MyStruct get_struct_2() {  // expected-warning{{no previous prototype for function 'get_struct_2'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Random comment before const. We should put the `static` between the comment block and `const`
+/*some randome comment*/const struct MyStruct get_struct_3() {  // expected-warning{{no previous prototype for function 'get_struct_3'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:25-[[@LINE-2]]:25}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+
+// Random comment after const.
+const/*some randome comment*/ struct MyStruct get_struct_4() {  // expected-warning{{no previous prototype for function 'get_struct_4'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
+// clang-format on
+
+#define MY_CONST const
+
+// This is not supported. We can't expand MY_CONST (efficiently) so we just give
+// up and put the 'static' before 'struct'
+MY_CONST struct MyStruct get_struct_nyi() { // expected-warning{{no previous prototype for function 'get_struct_nyi'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:10-[[@LINE-2]]:10}:"static "
+  struct MyStruct ret;
+  return ret;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,24 @@
 : FixItHint{});
 }
   } else {
+// If the return type has `const` qualifier, we want to insert `static`
+// before `const` (and not before the typename).
+auto findBeginLoc = [&]() {
+  if ((FD->getReturnType()->isAnyPointerType() &&
+   FD->getReturnType()->getPointeeType().isConstQualified()) ||
+  FD->getReturnType().isConstQualified())
+// But only do this if we can determine where the `const` is.
+if (clang::Lexer::isConst(FD->getBeginLoc(), getSourceManager(),
+  getLangOpts()))
+
+  return FD->getBeginLoc();
+
+  return FD->getTypeSpecStartLoc();
+};
 Diag(FD->getTypeSpecStartLoc(), diag::note_static_for_internal_linkage)
 << /* function */ 1
 << (FD->getStorageClass() == SC_None
-? FixItHint::CreateInsertion(FD->getTypeSpecStartLoc(),
- "static ")
+? FixItHint::CreateInsertion(findBeginLoc(), "static ")
 : FixItHint{});
   }
 

[PATCH] D81444: Make the diagnostic-missing-prototypes put the suggested `static` in front of `const` if exists.

2020-06-09 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo marked an inline comment as done.
oontvoo added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:14252
+  FD->getReturnType().isConstQualified())
+return FD->getReturnTypeSourceRange().getBegin().getLocWithOffset(
+/*strlen("const ")=*/-6);

gribozavr2 wrote:
> Could you add tests for the following cases? I'm not sure the implementation 
> will work.
> 
> ```
> // Two spaces between 'const' and 'struct'.
> const  struct MyStruct get_struct() ...
> 
> const /*comment*/ struct MyStruct get_struct() ...
> 
> #define MY_CONST const
> MY_CONST struct MyStruct get_struct() ...
> ```
> 
> I think a better way would be to check the token that comes before the type 
> name, and if that token is 'const', then adjust the source location -- 
> otherwise insert the 'static' keyword where we used to insert it in the past.
Done.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81444/new/

https://reviews.llvm.org/D81444



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81444: Make the diagnostic-missing-prototypes put the suggested `static` in front of `const` if exists.

2020-06-08 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
oontvoo added a reviewer: gribozavr2.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Consider: `const int* get_foo() {return nullptr;}`
The suggested fix should be `static const int* get_foo(){}`
and not `const static int* get_foo(){}`


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D81444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/warn-missing-prototypes.c


Index: clang/test/Sema/warn-missing-prototypes.c
===
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,19 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a 
prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for 
function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for 
function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be 
used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  int *ret;
+  return ret;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous 
prototype for function 'get_struct'}}
+ // expected-note@-1{{declare 'static' if 
the function is not intended to be used outside of this translation unit}}
+ // CHECK: 
fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,22 @@
 : FixItHint{});
 }
   } else {
+auto find_begin = [FD]() {
+  // If the return type has `const` qualifier, we want to insert
+  // `static` before `const` (and not before the typename).
+  if ((FD->getReturnType()->isAnyPointerType() &&
+   FD->getReturnType()->getPointeeType().isConstQualified()) ||
+  FD->getReturnType().isConstQualified())
+return FD->getReturnTypeSourceRange().getBegin().getLocWithOffset(
+/*strlen("const ")=*/-6);
+  else
+return FD->getTypeSpecStartLoc();
+};
+
 Diag(FD->getTypeSpecStartLoc(), diag::note_static_for_internal_linkage)
 << /* function */ 1
 << (FD->getStorageClass() == SC_None
-? FixItHint::CreateInsertion(FD->getTypeSpecStartLoc(),
- "static ")
+? FixItHint::CreateInsertion(find_begin(), "static ")
 : FixItHint{});
   }
 


Index: clang/test/Sema/warn-missing-prototypes.c
===
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,19 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  int *ret;
+  return ret;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous prototype for function 'get_struct'}}
+ // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,22 @@
 : FixItHint{});
 }
   } else {
+auto find_begin = [FD]() {
+  // If the return type has `const` qualifier, we want to insert
+  // `static` before `const` (and not before the typename).
+  if ((FD->getReturnType()->isAnyPointerType() &&
+   FD->getReturnType()->getPointeeType().isConstQualified()) ||
+  FD->getReturnType().isConstQualified())
+return FD->getReturnT

[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo closed this revision.
oontvoo added a comment.

Thanks, all!
Committed 
https://github.com/llvm/llvm-project/commit/51401a676c036f2bd4e6b4b38f3538615799de40


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 267008.
oontvoo added a comment.

Move matcher to near forEachArgumentWithParam


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,45 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, FunctionDecl) {
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, Lambda) {
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, BlockDecl) {
+  EXPECT_TRUE(matchesObjC(
+  "void func()  { void (^my_block)(int arg) = ^void(int arg) {}; } ",
+  parmVarDecl(isAtPosition(0;
+
+  EXPECT_TRUE(matchesObjC("void func()  { void (^my_block)(int x, int y) = "
+  "^void(int x, int y) {}; } ",
+  parmVarDecl(isAtPosition(1;
+
+  EXPECT_TRUE(notMatchesObjC(
+  "void func()  { void (^my_block)(int arg) = ^void(int arg) {}; } ",
+  parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -219,6 +219,7 @@
   REGISTER_MATCHER(floatLiteral);
   REGISTER_MATCHER(forEach);
   REGISTER_MATCHER(forEachArgumentWithParam);
+  REGISTER_MATCHER(isAtPosition);
   REGISTER_MATCHER(forEachConstructorInitializer);
   REGISTER_MATCHER(forEachDescendant);
   REGISTER_MATCHER(forEachOverridden);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4257,6 +4257,34 @@
   return Matched;
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  const clang::DeclContext *Context = Node.getParentFunctionOrMethod();
+
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+
+  return false;
+}
+
 /// Matches any parameter of a function or an ObjC method declaration or a
 /// block.
 ///
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4671,6 +4671,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
+
+MatcherisAtPositionunsigned N
+Matches t

[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D80603#2061131 , @aaron.ballman 
wrote:

> In D80603#2059122 , @gribozavr2 
> wrote:
>
> > In D80603#2058019 , @aaron.ballman 
> > wrote:
> >
> > > I'm sorry if I'm being dense, but `hasParameter`  traverses to the 
> > > `ParmVarDecl`, so I'm not certain I understand why this new matcher is 
> > > needed as a public matcher. It seems like you can already accomplish this 
> > > without adding a second API to do effectively the same thing: 
> > > `functionDecl(hasParameter(0, parmVarDecl().bind("param")))`, can't you?
> >
> >
> > It is syntax sugar, true. Note that the proposed matcher is a narrowing 
> > matcher for `parmVarDecl()`, while your suggestion is a narrowing matcher 
> > for `functionDecl()`, so it is not an entirely apples-to-apples comparison. 
> > Think about use cases like: `declRefExpr(to(parmVarDecl(at(...`. To 
> > rewrite that with `hasParameter()`, we have to use `hasAncestor` to find 
> > the `functionDecl` first, and then compare the AST node pointers. So while 
> > it is possible to express this proposed operation today, it requires a 
> > complex matcher for such a conceptually simple operation.
>
>
> Thank you, that clarifies the need nicely for me!
>
> Is there a reason we want to support blocks but not lambdas?


Yes, the implementation does support lambdas

> Also, you need to update Registry.cpp to add this to the list of dynamic 
> matchers.

Done


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 266999.
oontvoo added a comment.

Updated Registry


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,45 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, FunctionDecl) {
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, Lambda) {
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, BlockDecl) {
+  EXPECT_TRUE(matchesObjC(
+  "void func()  { void (^my_block)(int arg) = ^void(int arg) {}; } ",
+  parmVarDecl(isAtPosition(0;
+
+  EXPECT_TRUE(matchesObjC("void func()  { void (^my_block)(int x, int y) = "
+  "^void(int x, int y) {}; } ",
+  parmVarDecl(isAtPosition(1;
+
+  EXPECT_TRUE(notMatchesObjC(
+  "void func()  { void (^my_block)(int arg) = ^void(int arg) {}; } ",
+  parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -261,6 +261,7 @@
   REGISTER_MATCHER(hasCastKind);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(isAtPosition);
   REGISTER_MATCHER(hasDecayedType);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeclaration);
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4615,6 +4615,34 @@
  InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  const clang::DeclContext *Context = Node.getParentFunctionOrMethod();
+
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+
+  return false;
+}
+
 /// Matches the index expression of an array subscript expression.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4671,6 +4671,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
+
+MatcherisAtPositionunsigned N
+Matche

[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 266887.
oontvoo marked 2 inline comments as done.
oontvoo added a comment.

Change tests to us no/matchesObjC


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,45 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, FunctionDecl) {
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, Lambda) {
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, BlockDecl) {
+  EXPECT_TRUE(matchesObjC(
+  "void func()  { void (^my_block)(int arg) = ^void(int arg) {}; } ",
+  parmVarDecl(isAtPosition(0;
+
+  EXPECT_TRUE(matchesObjC("void func()  { void (^my_block)(int x, int y) = "
+  "^void(int x, int y) {}; } ",
+  parmVarDecl(isAtPosition(1;
+
+  EXPECT_TRUE(notMatchesObjC(
+  "void func()  { void (^my_block)(int arg) = ^void(int arg) {}; } ",
+  parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4615,6 +4615,34 @@
  InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  const clang::DeclContext *Context = Node.getParentFunctionOrMethod();
+
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+
+  return false;
+}
+
 /// Matches the index expression of an array subscript expression.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4671,6 +4671,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
+
+MatcherisAtPositionunsigned N
+Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+list. The parameter list could be that of either a block, function, or
+objc-method.
+
+
+Given
+
+void f(int a, int b, int c) {
+}
+
+``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+
+``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+
+
 
 
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 266735.
oontvoo added a comment.

More tests for Block


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,43 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, FunctionDecl) {
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, Lambda) {
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
+TEST(IsAtPosition, BlockDecl) {
+  // FIXME: Needs to enable block-support (ie., -fblocks)
+  if (true)
+return;
+  EXPECT_TRUE(matches("void x()  { auto b = ^(int y) { }; } ",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x()  { auto b = ^(int y,int z) { }; } ",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x()  { auto b = ^(int y) { }; } ",
+ parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4615,6 +4615,39 @@
  InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
+// Returns true if Node is a parameter at N in the given Context
+// of type DeclT.
+template 
+static bool __isParamAt(const clang::DeclContext *Context,
+const clang::ParmVarDecl &Node, unsigned N) {
+  if (const auto *Decl = dyn_cast_or_null(Context))
+return N < Decl->param_size() && Decl->getParamDecl(N) == &Node;
+
+  return false;
+}
+
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  const clang::DeclContext *ParentContext = Node.getParentFunctionOrMethod();
+  return __isParamAt(ParentContext, Node, N) ||
+ __isParamAt(ParentContext, Node, N) ||
+ __isParamAt(ParentContext, Node, N);
+}
+
 /// Matches the index expression of an array subscript expression.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4671,6 +4671,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
+
+MatcherisAtPositionunsigned N
+Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+list. The parameter list could be that of either a block, function, or
+objc-method.
+
+
+Given
+
+void f(int a, int b, int c) {
+}
+
+``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+
+``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+
+
 
 
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://list

[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 266714.
oontvoo added a comment.

use helper for examining the node instead of nested matchers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/AST/ASTContext.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,29 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+
+  // Tests with function-decls
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+
+  // Tests with lamdas
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -10749,6 +10749,13 @@
   return I->second;
 }
 
+bool ASTContext::parameterHasIndex(const ParmVarDecl *D, unsigned index) const {
+  ParameterIndexTable::const_iterator I = ParamIndices.find(D);
+  if (I == ParamIndices.end())
+return false;
+  return I->second == index;
+}
+
 QualType ASTContext::getStringLiteralArrayType(QualType EltTy,
unsigned Length) const {
   // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4615,6 +4615,27 @@
  InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  const clang::DeclContext *ParentContext = Node.getParentFunctionOrMethod();
+  return ParentContext != nullptr &&
+ ParentContext->getParentASTContext().parameterHasIndex(&Node, N);
+}
+
 /// Matches the index expression of an array subscript expression.
 ///
 /// Given
Index: clang/include/clang/AST/ASTContext.h
===
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2795,6 +2795,10 @@
   /// index of the parameter when it exceeds the size of the normal bitfield.
   unsigned getParameterIndex(const ParmVarDecl *D) const;
 
+  // Returns "true" iff the given ParmVarDecl exists in this context at the
+  // given position.
+  bool parameterHasIndex(const ParmVarDecl *D, unsigned index) const;
+
   /// Return a string representing the human readable name for the specified
   /// function declaration or file name. Used by SourceLocExpr and
   /// PredefinedExpr to cache evaluated results.
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4671,6 +4671,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, Match

[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D80603#2058019 , @aaron.ballman 
wrote:

> In D80603#2057970 , @oontvoo wrote:
>
> > In D80603#2057014 , @aaron.ballman 
> > wrote:
> >
> > > Does the `hasParameter()` matcher not already do this?
> >
> >
> > Yes, it does. But we'd like it to be able to match on the parmVarDecl().
>
>
> I'm sorry if I'm being dense, but `hasParameter`  traverses to the 
> `ParmVarDecl`, so I'm not certain I understand why this new matcher is needed 
> as a public matcher. It seems like you can already accomplish this without 
> adding a second API to do effectively the same thing: 
> `functionDecl(hasParameter(0, parmVarDecl().bind("param")))`, can't you?


Ah, I didn't mean to say it wasn't *already possible* to do any of this.

It would be *very* nice to have this (at least to some of us, that I know of). 
(make the logic a lot simpler in a few custom matchers).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 266642.
oontvoo added a comment.

Remove unrelated doc generated by the script


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,29 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+
+  // Tests with function-decls
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+
+  // Tests with lamdas
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4615,6 +4615,37 @@
  InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  constexpr char Name[] = "##isAtPosition_parmVar_";
+
+  // The direct parent of any parmVarDecl is a TypeLoc, and not a Decl,
+  // so we have to go up one more level.
+  return parmVarDecl(
+ hasParent(typeLoc(anyOf(hasParent(blockDecl(hasParameter(
+ N, parmVarDecl().bind(Name,
+ hasParent(objcMethodDecl(hasParameter(
+ N, parmVarDecl().bind(Name,
+ hasParent(functionDecl(hasParameter(
+ N, parmVarDecl().bind(Name))),
+ equalsBoundNode(Name))
+  .matches(Node, Finder, Builder);
+}
+
 /// Matches the index expression of an array subscript expression.
 ///
 /// Given
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -4671,6 +4671,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
+
+MatcherisAtPositionunsigned N
+Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+list. The parameter list could be that of either a block, function, or
+objc-method.
+
+
+Given
+
+void f(int a, int b, int c) {
+}
+
+``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+
+``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+
+
 
 
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 266615.
oontvoo marked 7 inline comments as done.
oontvoo added a comment.

- Added docs
- Make it work with {block,objcMethod}Decl too.  More tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,29 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+
+  // Tests with function-decls
+  EXPECT_TRUE(matches("void x(int a);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b);", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val);", parmVarDecl(isAtPosition(1;
+
+  // Tests with lamdas
+  EXPECT_TRUE(
+  matches("void x() { [](int a) {};  }", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x() { [](int a, int b) {}; }",
+  parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(
+  notMatches("void x() { [](int val) {}; }", parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -3096,6 +3096,37 @@
 internal::TypeList>
 hasAncestor;
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list. The parameter list could be that of either a block, function, or
+/// objc-method.
+///
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  constexpr char Name[] = "##isAtPosition_parmVar_";
+
+  // The direct parent of any parmVarDecl is a TypeLoc, and not a Decl,
+  // so we have to go up one more level.
+  return parmVarDecl(
+ hasParent(typeLoc(anyOf(hasParent(blockDecl(hasParameter(
+ N, parmVarDecl().bind(Name,
+ hasParent(objcMethodDecl(hasParameter(
+ N, parmVarDecl().bind(Name,
+ hasParent(functionDecl(hasParameter(
+ N, parmVarDecl().bind(Name))),
+ equalsBoundNode(Name))
+  .matches(Node, Finder, Builder);
+}
+
 /// Matches if the provided matcher does not match.
 ///
 /// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X"
Index: clang/docs/LibASTMatchersReference.html
===
--- clang/docs/LibASTMatchersReference.html
+++ clang/docs/LibASTMatchersReference.html
@@ -1226,6 +1226,11 @@
 
 
 
+MatcherStmt>fixedPointLiteralMatcherFixedPointLiteral>...
+Matches fixed point literals
+
+
+
 MatcherStmt>floatLiteralMatcherFloatingLiteral>...
 Matches float literals of all sizes / encodings, e.g.
 1.0, 1.0f, 1.0L and 1e10.
@@ -4671,6 +4676,23 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
+
+MatcherisAtPositionunsigned N
+Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+list. The parameter list could be that of either a block, function, or
+objc-method.
+
+
+Given
+
+void f(int a, int b, int c) {
+}
+
+`

[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

In D80603#2057014 , @aaron.ballman 
wrote:

> Does the `hasParameter()` matcher not already do this?


Yes, it does. But we'd like it to be able to match on the parmVarDecl().




Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:7018
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  return parmVarDecl(hasAncestor(functionDecl(
+ hasParameter(N, parmVarDecl().bind("this_decl",

ymandel wrote:
> I think that `hasAncestor` will keep going up the chain of ancestors if it 
> fails the match on the first surrounding `functionDecl`. That could make this 
> matcher very expensive.  Why hasParent (or, whatever combination of 
> `hasParent` and other matchers needed to precisely describe the immediately 
> surrounding `functionDecl`)?
> Why [not] hasParent ?

The direct parent of the param is a TypeLoc, so I thought `hasAncestor()` was 
more convenient. But I've changed it to two nested `hasParent()` now.




Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:7022
+  .matches(Node, Finder, Builder);
+}
+

gribozavr2 wrote:
> Could you move it closer to other parameter-related matchers, maybe near the 
> definition of `forEachArgumentWithParam`?
Moved it to after hasAncestor.
(Can't move to near forEachArgumentWithParam because that's before hasAncestor 
and hasParent, which are needed by this)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-26 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

P.S: Please ignore the child revision ... accidentally committed it to the 
wrong branch. I've fixed the git branches locally but can't figure out how to 
tell phabricator ...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80603/new/

https://reviews.llvm.org/D80603



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80603: add isAtPosition narrowing matcher for parmVarDecl

2020-05-26 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
Herald added subscribers: cfe-commits, danielkiss, kristof.beyls.
Herald added a project: clang.
oontvoo added reviewers: gribozavr, ymandel.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D80603

Files:
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,13 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", 
parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", 
parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7001,6 +7001,26 @@
   return InnerMatcher.matches(Node, Finder, Builder);
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the 
parameter
+/// list.
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))``` matches `int a`.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches `int b`.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  return parmVarDecl(hasAncestor(functionDecl(
+ hasParameter(N, parmVarDecl().bind("this_decl",
+ equalsBoundNode("this_decl"))
+  .matches(Node, Finder, Builder);
+}
+
 
////
 // OpenMP handling.
 
////


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -2643,6 +2643,13 @@
   parmVarDecl(hasDefaultArgument(;
 }
 
+TEST(IsAtPosition, Basic) {
+  EXPECT_TRUE(matches("void x(int a) {}", parmVarDecl(isAtPosition(0;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(matches("void x(int a, int b) {}", parmVarDecl(isAtPosition(1;
+  EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(isAtPosition(1;
+}
+
 TEST(IsArray, Basic) {
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
   cxxNewExpr(isArray(;
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7001,6 +7001,26 @@
   return InnerMatcher.matches(Node, Finder, Builder);
 }
 
+/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
+/// list.
+///
+/// Given
+///
+/// \code
+/// void f(int a, int b, int c) {
+/// }
+/// \endcode
+///
+/// ``parmVarDecl(isAtPosition(0))``` matches `int a`.
+///
+/// ``parmVarDecl(isAtPosition(1))`` matches `int b`.
+AST_MATCHER_P(clang::ParmVarDecl, isAtPosition, unsigned, N) {
+  return parmVarDecl(hasAncestor(functionDecl(
+ hasParameter(N, parmVarDecl().bind("this_decl",
+ equalsBoundNode("this_decl"))
+  .matches(Node, Finder, Builder);
+}
+
 ////
 // OpenMP handling.
 ////
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-04-06 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

jyknight@ Hi, pinging again 🔔🔔🔔 (sorry!)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-04-01 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 254384.
oontvoo added a comment.

Update docs.

Note: The failure looks spurious ... They seemed to pass locally for me:
One eg:

[hi on] vyng@vyng:~/repo/llvm-project$ ./build/bin/llvm-lit -v 
./clang/test/ClangScanDeps/modules-full.cpp
llvm-lit: 
/usr/local/google/home/vyng/repo/llvm-project/llvm/utils/lit/lit/llvm/config.py:342:
 note: using clang: 
/usr/local/google/home/vyng/repo/llvm-project/build/bin/clang

- Testing: 1 tests, 1 workers --

PASS: Clang :: ClangScanDeps/modules-full.cpp (1 of 1)

Testing Time: 2.75s

  Expected Passes: 1


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/PPDirectives.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/header_in_imported_module.h
  clang/test/Modules/Inputs/imported_module.cppm
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/header-in-imported-module.c
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+// expected-no-diagnostics
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/header-in-imported-module.c
===
--- /dev/null
+++ clang/test/Modules/header-in-imported-module.c
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: %clang -x c++ -fmodules  -fmodules-ts --precompile -o %t/ModuleB39206.pcm %S/Inputs/imported_module.cppm
+// RUN: %clang -x c++ -fmodules   -fmodules-ts -c %t/ModuleB39206.pcm -o %t/ModuleB39206.o
+// RUN: %clang -x c++ -fmodules  -fmodules-ts -I%S/Inputs  -fmodule-file=%t/ModuleB39206.pcm   -c %s
+// expected-no-diagnostics
+
+// Bug 39206
+
+#include "header_in_imported_module.h"
+module ModuleB39206;
+
+#ifndef ALL_GOOD
+#error "missing macro in impl"
+#endif
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/imported_module.cppm
===
--- /dev/null
+++ clang/test/Modules/Inputs/imported_module.cppm
@@ -0,0 +1,6 @@
+export module ModuleB39206;
+#include "header_in_imported_module.h"
+
+#ifndef ALL_GOOD
+#error "Missing macro in module decl"
+#endif
\ No newline at end of file
Index: clang/test/Modules/Inputs/header_in_imported_module.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/header_in_imported_module.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define ALL_GOOD
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLo

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-04-01 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 254321.
oontvoo added a comment.

clean up ... Ready to review. PTAL! =)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/PPDirectives.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/header_in_imported_module.h
  clang/test/Modules/Inputs/imported_module.cppm
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/header-in-imported-module.c
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+// expected-no-diagnostics
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/header-in-imported-module.c
===
--- /dev/null
+++ clang/test/Modules/header-in-imported-module.c
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: %clang -fmodules -x c++ -fmodules-ts --precompile -o %t/ModuleB39206.pcm %S/Inputs/imported_module.cppm
+// RUN: %clang -fmodules -x c++ -fmodules-ts -c %t/ModuleB39206.pcm -o %t/ModuleB39206.o
+// RUN: %clang -fmodules -x c++ -fmodules-ts -fmodule-file=%t/ModuleB39206.pcm -verify  -c %s
+// expected-no-diagnostics
+
+// Bug 39206
+
+#include "header_in_imported_module.h"
+module ModuleB39206;
+
+#ifndef ALL_GOOD
+#error "missing macro in impl"
+#endif
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/imported_module.cppm
===
--- /dev/null
+++ clang/test/Modules/Inputs/imported_module.cppm
@@ -0,0 +1,5 @@
+export module ModuleB39206;
+#include "header.h"
+
+#ifndef ALL_GOOD
+#error "Missing macro in module decl"
\ No newline at end of file
Index: clang/test/Modules/Inputs/header_in_imported_module.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/header_in_imported_module.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define ALL_GOOD
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also s

[PATCH] D77116: temp tests

2020-03-30 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77116

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/PPDirectives.cpp
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/header_in_imported_module.h
  clang/test/Modules/Inputs/imported_module.cppm
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/header-in-imported-module.c
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+// expected-no-diagnostics
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/header-in-imported-module.c
===
--- /dev/null
+++ clang/test/Modules/header-in-imported-module.c
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x c++ -fmodules-ts --precompile -o %t/ModuleB39206.pcm %S/Inputs/imported_module.cppm
+// RUN: %clang_cc1 -fmodules -x c++ -fmodules-ts -c %t/ModuleB39206.pcm -o %t/ModuleB39206.o
+// RUN: %clang_cc1 -fmodules -x c++ -fmodules-ts -fmodule-file=%t/ModuleB39206.pcm -verify  -c %s
+// expected-no-diagnostics
+
+// Bug 39206
+
+#include "header_in_imported_module.h"
+module ModuleB39206;
+
+#ifndef ALL_GOOD
+#error "missing macro in impl"
+#endif
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/imported_module.cppm
===
--- /dev/null
+++ clang/test/Modules/Inputs/imported_module.cppm
@@ -0,0 +1,5 @@
+export module ModuleB39206;
+#include "header.h"
+
+#ifndef ALL_GOOD
+#error "Missing macro in module decl"
\ No newline at end of file
Index: clang/test/Modules/Inputs/header_in_imported_module.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/header_in_imported_module.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define ALL_GOOD
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different mod

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-30 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253623.
oontvoo added a comment.

Rebaase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/header_in_imported_module.h
  clang/test/Modules/Inputs/imported_module.cppm
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/header-in-imported-module.c
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+// expected-no-diagnostics
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/header-in-imported-module.c
===
--- /dev/null
+++ clang/test/Modules/header-in-imported-module.c
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify  -x c++ %s
+//
+// RUN: %clang_cc1 -x c++ -fmodules-ts --precompile -o %t/ModuleB39206.pcm %S/Inputs/imported_module.cppm
+// RUN: %clang_cc1 -x c++ -fmodules-ts -c %t/ModuleB39206.pcm -o %t/ModuleB39206.o
+// RUN: %clang_cc1 -x c++ -fmodules-ts -fmodule-file=%t/ModuleB39206.pcm -verify  -c %s
+// expected-no-diagnostics
+
+// Bug 39206
+
+#include "header_in_imported_module.h"
+module ModuleB39206;
+
+#ifndef ALL_GOOD
+#error "missing macro in impl"
+#endif
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/imported_module.cppm
===
--- /dev/null
+++ clang/test/Modules/Inputs/imported_module.cppm
@@ -0,0 +1,5 @@
+export module ModuleB39206;
+#include "header.h"
+
+#ifndef ALL_GOOD
+#error "Missing macro in module decl"
\ No newline at end of file
Index: clang/test/Modules/Inputs/header_in_imported_module.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/header_in_imported_module.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define ALL_GOOD
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also skip 

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253388.
oontvoo added a comment.

Add more tests (From Bug 39206)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/header_in_imported_module.h
  clang/test/Modules/Inputs/imported_module.cppm
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/header-in-imported-module.c
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+// expected-no-diagnostics
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/header-in-imported-module.c
===
--- /dev/null
+++ clang/test/Modules/header-in-imported-module.c
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify  -x c++ %s
+//
+// RUN: %clang_cc1 -x c++ -fmodules-ts --precompile -o %t/ModuleB39206.pcm %S/Inputs/imported_module.cppm
+// RUN: %clang_cc1 -x c++ -fmodules-ts -c %t/ModuleB39206.pcm -o %t/ModuleB39206.o
+// RUN: %clang_cc1 -x c++ -fmodules-ts -fmodule-file=%t/ModuleB39206.pcm -verify  -c %s
+// expected-no-diagnostics
+
+// Bug 39206
+
+#include "header_in_imported_module.h"
+module ModuleB39206;
+
+#ifndef ALL_GOOD
+#error "missing macro in impl"
+#endif
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/imported_module.cppm
===
--- /dev/null
+++ clang/test/Modules/Inputs/imported_module.cppm
@@ -0,0 +1,5 @@
+export module ModuleB39206;
+#include "header.h"
+
+#ifndef ALL_GOOD
+#error "Missing macro in module decl"
\ No newline at end of file
Index: clang/test/Modules/Inputs/header_in_imported_module.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/header_in_imported_module.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define ALL_GOOD
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since i

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-28 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253382.
oontvoo added a comment.

Update tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+// expected-no-diagnostics
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1801,8 +1803,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2636,6 +2643,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pra

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253289.
oontvoo added a comment.

cleanup logging


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1801,8 +1803,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2636,6 +2643,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix tha

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253245.
oontvoo added a comment.

Updated tests and get it to pass


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/dummy_textual_header.h
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify -x c %s
+#include "dummy_pragma_once.h"
+#include "dummy_textual_header.h"
+
+void *p = &x;
+void *q = &y;
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,11 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+  textual header "dummy_textual_header.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/dummy_textual_header.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_textual_header.h
@@ -0,0 +1,2 @@
+#pragma once
+int y = 6;
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+#include "dummy_textual_header.h"
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1801,8 +1803,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2636,6 +2643,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe 

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253175.
oontvoo added a comment.

Merge master


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,5 @@
+
+#include "dummy_pragma_once.h"
+#include "dummy_pragma_once.h"  // Re-importing should be fine
+
+void *p = &x;
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,10 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+//#pragma once | dont need this
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1621,7 +1621,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1678,6 +1678,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1705,7 +1708,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1783,8 +1786,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1801,8 +1803,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2636,6 +2643,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
@@ -4722,6 +4748,24 @@
   if (WritingModule)
 WriteSubmodules(WritingModule);
 
+  

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253162.
oontvoo added a comment.

Add tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/dummy_pragma_once.h
  clang/test/Modules/Inputs/module.map
  clang/test/Modules/import-pragma-once.c

Index: clang/test/Modules/import-pragma-once.c
===
--- /dev/null
+++ clang/test/Modules/import-pragma-once.c
@@ -0,0 +1,5 @@
+
+#include "dummy_pragma_once.h"
+#include "dummy_pragma_once.h"  // Re-importing should be fine
+
+void *p = &x;
Index: clang/test/Modules/Inputs/module.map
===
--- clang/test/Modules/Inputs/module.map
+++ clang/test/Modules/Inputs/module.map
@@ -282,6 +282,10 @@
   header "dummy.h"
 }
 
+module dummy_pragma_once {
+  header "dummy_pragma_once.h"
+}
+
 module builtin {
   header "builtin.h"
   explicit module sub {
Index: clang/test/Modules/Inputs/dummy_pragma_once.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/dummy_pragma_once.h
@@ -0,0 +1,3 @@
+//#pragma once | dont need this
+
+int x = 5;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
@@ -4715,6 +4741,24 @@
   if (WritingModule)
 WriteSubmodules(WritingModule);
 
+  // 

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253157.
oontvoo added a comment.

.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
@@ -4715,6 +4741,24 @@
   if (WritingModule)
 WriteSubmodules(WritingModule);
 
+  // Write the imported headers, only for the precompiled header (ie, no
+  // modules) because the modules will have emitted their own imported headers.
+  if ((!WritingModule || PP.Submodules.empty()) &&
+  !PP.CurSubmoduleState->IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : PP.CurSubmoduleState->IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP.getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(PP_IMPORTED_HEADERS, Record);
+  }
+
   // We need to have information about submodules to correctly deserialize
   // decls from OpenCLExtensionDecls block
   WriteOpenCLExtensionDecls(SemaRef);
Index: clang/lib/Serialization/ASTReader.cpp

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-27 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 253155.
oontvoo added a comment.

Also serialise non-mods' imported headers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
@@ -4715,6 +4741,24 @@
   if (WritingModule)
 WriteSubmodules(WritingModule);
 
+  // Write the imported headers, only for the precompiled header (ie, no
+  // modules) because the modules will have emitted their own imported headers.
+  if ((!WritingModule || PP.Submodules.empty()) &&
+  !PP.CurSubmoduleState->IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : PP.CurSubmoduleState->IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP.getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(PP_IMPORTED_HEADERS, Record);
+  }
+
   // We need to have information about submodules to correctly deserialize
   // decls from OpenCLExtensionDecls block
   WriteOpenCLExtensionDecls(SemaRef);
Index: clang/lib/Serialization/ASTReader.

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-26 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252791.
oontvoo added a comment.

Handle includes/import from outer mods


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1,3 +1,4 @@
+
 //===- ASTReader.cpp - AST File Reader ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -1898,6 +1899,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5619,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9280,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-26 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252768.
oontvoo added a comment.

Handle textual headers


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1,3 +1,4 @@
+
 //===- ASTReader.cpp - AST File Reader ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -1898,6 +1899,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5619,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9280,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().ded

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-26 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252760.
oontvoo added a comment.

.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI->UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1,3 +1,4 @@
+
 //===- ASTReader.cpp - AST File Reader ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -1898,6 +1899,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5619,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9280,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefini

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-26 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252761.
oontvoo added a comment.

.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,25 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (unsigned UID : it->second.IncludedFiles) {
+  // Only save it if the header is actually import/pragma once.
+  // FIXME When we first see a header, it always goes into the mod's
+  // list of included, regardless of whether it was pragma-once or not.
+  // Maybe better to fix that earlier?
+  auto HFI = PP->getHeaderSearchInfo().FileInfo[UID];
+  if (HFI.isImport || HFI.isPragmaOnce) {
+Record.push_back(HFI.UID);
+  }
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1,3 +1,4 @@
+
 //===- ASTReader.cpp - AST File Reader ===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -1898,6 +1899,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5619,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9280,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinit

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-25 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252738.
oontvoo added a comment.

...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (const HeaderFileInfo *HFI : it->second.IncludedFiles) {
+  Record.push_back(HFI->UID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5618,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9279,38 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map UIDToIndex;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToIndex map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned Idx = 0; Idx < HS.FileInfo.size(); ++Idx) {
+  UIDToIndex[HS.FileInfo[Idx].UID] = Idx;
+  // Clear the no longer useful UID fields.
+  HS.FileInfo[Idx].UID = 0;
+  

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-25 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252735.
oontvoo added a comment.




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (const HeaderFileInfo *HFI : it->second.IncludedFiles) {
+  Record.push_back(HFI->UID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5618,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9279,38 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map UIDToIndex;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToIndex map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned Idx = 0; Idx < HS.FileInfo.size(); ++Idx) {
+  UIDToIndex[HS.FileInfo[Idx].UID] = Idx;
+  // Clear the no longer useful UID fields.
+  HS.FileInfo[Idx].UID = 0;
+}

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-25 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252728.
oontvoo added a comment.

Typo - missing ! operator


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (const HeaderFileInfo *HFI : it->second.IncludedFiles) {
+  Record.push_back(HFI->UID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5618,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9279,38 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map UIDToIndex;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToIndex map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned Idx = 0; Idx < HS.FileInfo.size(); ++Idx) {
+  UIDToIndex[HS.FileInfo[Idx].UID] = Idx;
+  // Clear the no longer useful UID fields.
+  HS.File

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-25 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252685.
oontvoo added a comment.

Handle the case where the file is first seen


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (const HeaderFileInfo *HFI : it->second.IncludedFiles) {
+  Record.push_back(HFI->UID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5618,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9279,38 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map UIDToIndex;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToIndex map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned Idx = 0; Idx < HS.FileInfo.size(); ++Idx) {
+  UIDToIndex[HS.FileInfo[Idx].UID] = Idx;
+  // Clear the no longer useful UID fie

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-25 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo added a comment.

@jyknight  Actually, please hold on on the review ... still working on it


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-24 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252371.
oontvoo added a comment.

clang format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1619,7 +1619,7 @@
   endian::Writer LE(Out, little);
   unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
   LE.write(KeyLen);
-  unsigned DataLen = 1 + 2 + 4 + 4;
+  unsigned DataLen = 1 + 2 + 4 + 4 + 4;
   for (auto ModInfo : Data.KnownHeaders)
 if (Writer.getLocalOrImportedSubmoduleID(ModInfo.getModule()))
   DataLen += 4;
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,8 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
-HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+HeaderFileInfo *HFI = HS.getExistingFileInfo(File, /*WantExternal*/ !Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
 
@@ -1799,8 +1801,13 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI,
+HS.getModuleMap().findAllModulesForHeader(File),
+{},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (const HeaderFileInfo *HFI : it->second.IncludedFiles) {
+  Record.push_back(HFI->UID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5618,11 @@
   }
   break;
 
+case SUBMODULE_IMPORTED_HEADERS:
+  for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+PendingImportedHeaders[&F].push_back(Record[Idx]);
+  }
+  break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9279,38 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map UIDToIndex;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToIndex map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned Idx = 0; Idx < HS.FileInfo.size(); ++Idx) {
+  UIDToIndex[HS.FileInfo[Idx].UID] = Idx;
+  // Clear the no longer useful UID fields.
+  HS.FileInfo[Idx].UID

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-24 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo marked an inline comment as done.
oontvoo added a comment.

Addressed comments. PTAL. Thanks!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-24 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252237.
oontvoo added a comment.

Cleanup


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1676,6 +1676,9 @@
   }
   LE.write(Offset);
 
+  // Write this file UID.
+  LE.write(Data.HFI.UID);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1703,7 +1706,7 @@
 /// Write the header search block for the list of files that
 ///
 /// \param HS The header search structure to save.
-void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
+void ASTWriter::WriteHeaderSearch(HeaderSearch &HS) {
   HeaderFileInfoTrait GeneratorTrait(*this);
   llvm::OnDiskChainedHashTableGenerator Generator;
   SmallVector SavedStrings;
@@ -1781,7 +1784,7 @@
 // changed since it was loaded. Also skip it if it's for a modular header
 // from a different module; in that case, we rely on the module(s)
 // containing the header to provide this information.
-const HeaderFileInfo *HFI =
+HeaderFileInfo *HFI =
 HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
 if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
   continue;
@@ -1799,8 +1802,11 @@
 HeaderFileInfoTrait::key_type Key = {
   Filename, File->getSize(), getTimestampForOutput(File)
 };
+// Set the UID for this HFI so that its importers could use it
+// when serializing.
+HFI->UID = UID;
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {},
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2640,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (const HeaderFileInfo* HFI : it->second.IncludedFiles) {
+  Record.push_back(HFI->UID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,9 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  HFI.UID = endian::readNext(d);
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -5615,6 +5618,11 @@
   }
   break;
 
+  case SUBMODULE_IMPORTED_HEADERS:
+for (unsigned Idx = 0; Idx < Record.size(); ++Idx) {
+  PendingImportedHeaders[&F].push_back(Record[Idx]);
+}
+break;
 case SUBMODULE_EXPORTS:
   for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) {
 UnresolvedModuleRef Unresolved;
@@ -9271,6 +9279,38 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map UIDToIndex;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToIndex map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned Idx = 0; Idx < HS.FileInfo.size(); ++Idx) {
+  UIDToIndex[HS.FileInfo[Idx].UID] = Idx;
+  // Clear the no longer useful UID fields.
+  HS.FileInfo[Idx].UID = 0;
+}
+
+const auto &Iter = PendingImportedHeaders.begin();
+for (unsigned I = 0; I < PendingImportedHeaders.size(); ++I) {
+  ModuleFile *ModFile = Iter[I].first;
+  auto &HeaderUIDs = Iter[I].second;
+  Module *M = HS.lookupModule(ModFile->ModuleName);
+
+  Preprocessor::SubmoduleState &SubState = PP.Submodules[M];
+  for (unsigned OldUID : HeaderUIDs) {
+auto IdxIt = UIDToIndex.find(OldUID);
+   

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-23 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252205.
oontvoo added a comment.

Fix build errors


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1599,6 +1599,8 @@
   const HeaderFileInfo &HFI;
   ArrayRef KnownHeaders;
   UnresolvedModule Unresolved;
+  uint32_t UID;
+  uint32_t FileIndex;
 };
 using data_type_ref = const data_type &;
 
@@ -1676,6 +1678,10 @@
   }
   LE.write(Offset);
 
+  // Write this file UID and its index into the array where it was written.
+  LE.write(Data.UID);
+  LE.write(Data.FileIndex);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1800,7 +1806,8 @@
   Filename, File->getSize(), getTimestampForOutput(File)
 };
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {},
+  File->getUID(), UID,
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty() ) {
+RecordData Record;
+for (auto FileUID : it->second.IncludedFiles) {
+  Record.push_back(FileUID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,13 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  {
+HFI.UID = endian::readNext(d);
+//TODO: seems the index is not needed
+const uint32_t OldIndex = endian::readNext(d);
+  }
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -9271,6 +9278,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()){
+std::map OldToNewUID;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToNewUID map
+// for use next.
+HeaderSearch& HS = PP.getHeaderSearchInfo();
+for (unsigned NewUID = 0; NewUID < HS.FileInfo.size(); ++NewUID) {
+  OldToNewUID[HS.FileInfo[NewUID].UID] = NewUID;
+  HS.FileInfo[NewUID].UID = NewUID;
+}
+
+const auto& Iter = PendingImportedHeaders.begin();
+for (unsigned I = 0; I < PendingImportedHeaders.size(); ++I){
+  ModuleFile* ModFile = Iter[I].first;
+  auto& HeaderUIDs = Iter[I].second;
+  Module *M = HS.lookupModule(ModFile->ModuleName);
+
+  Preprocessor::SubmoduleState&  SubState = PP.Submodules[M];
+  for (unsigned OldUid : HeaderUIDs) {
+auto NewUIDIt = OldToNewUID.find(OldUid);
+assert(NewUIDIt != OldToNewUID.end());
+
+SubState.IncludedFiles.insert(NewUIDIt->second);
+  }
+}
+PendingImportedHeaders.clear();
+  }
 }
 
 void ASTReader::diagnoseOdrViolations() {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,21 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// After module m

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-23 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252206.
oontvoo added a comment.

Clang format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1599,6 +1599,8 @@
   const HeaderFileInfo &HFI;
   ArrayRef KnownHeaders;
   UnresolvedModule Unresolved;
+  uint32_t UID;
+  uint32_t FileIndex;
 };
 using data_type_ref = const data_type &;
 
@@ -1676,6 +1678,10 @@
   }
   LE.write(Offset);
 
+  // Write this file UID and its index into the array where it was written.
+  LE.write(Data.UID);
+  LE.write(Data.FileIndex);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1800,7 +1806,9 @@
   Filename, File->getSize(), getTimestampForOutput(File)
 };
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+*HFI, HS.getModuleMap().findAllModulesForHeader(File),
+{},   File->getUID(),
+UID,
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2642,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty()) {
+RecordData Record;
+for (auto FileUID : it->second.IncludedFiles) {
+  Record.push_back(FileUID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,13 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  {
+HFI.UID = endian::readNext(d);
+// TODO: seems the index is not needed
+const uint32_t OldIndex = endian::readNext(d);
+  }
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -9271,6 +9278,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()) {
+std::map OldToNewUID;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToNewUID map
+// for use next.
+HeaderSearch &HS = PP.getHeaderSearchInfo();
+for (unsigned NewUID = 0; NewUID < HS.FileInfo.size(); ++NewUID) {
+  OldToNewUID[HS.FileInfo[NewUID].UID] = NewUID;
+  HS.FileInfo[NewUID].UID = NewUID;
+}
+
+const auto &Iter = PendingImportedHeaders.begin();
+for (unsigned I = 0; I < PendingImportedHeaders.size(); ++I) {
+  ModuleFile *ModFile = Iter[I].first;
+  auto &HeaderUIDs = Iter[I].second;
+  Module *M = HS.lookupModule(ModFile->ModuleName);
+
+  Preprocessor::SubmoduleState &SubState = PP.Submodules[M];
+  for (unsigned OldUid : HeaderUIDs) {
+auto NewUIDIt = OldToNewUID.find(OldUid);
+assert(NewUIDIt != OldToNewUID.end());
+
+SubState.IncludedFiles.insert(NewUIDIt->second);
+  }
+}
+PendingImportedHeaders.clear();
+  }
 }
 
 void ASTReader::diagnoseOdrViolations() {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,22 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// Af

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-23 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252203.
oontvoo added a comment.

(hopefully) Final revision ... running out of idea for edit comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1599,6 +1599,8 @@
   const HeaderFileInfo &HFI;
   ArrayRef KnownHeaders;
   UnresolvedModule Unresolved;
+  uint32_t UID;
+  uint32_t FileIndex;
 };
 using data_type_ref = const data_type &;
 
@@ -1676,6 +1678,10 @@
   }
   LE.write(Offset);
 
+  // Write this file UID and its index into the array where it was written.
+  LE.write(Data.UID);
+  LE.write(Data.FileIndex);
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
@@ -1800,7 +1806,8 @@
   Filename, File->getSize(), getTimestampForOutput(File)
 };
 HeaderFileInfoTrait::data_type Data = {
-  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {}
+  *HFI, HS.getModuleMap().findAllModulesForHeader(File), {},
+  File->getUID(), UID,
 };
 Generator.insert(Key, Data, GeneratorTrait);
 ++NumHeaderSearchEntries;
@@ -2634,6 +2641,18 @@
   Stream.EmitRecord(SUBMODULE_IMPORTS, Record);
 }
 
+// Emit the imported header's UIDs.
+{
+  auto it = PP->Submodules.find(Mod);
+  if (it != PP->Submodules.end() && !it->second.IncludedFiles.empty() ) {
+RecordData Record;
+for (auto FileUID : it->second.IncludedFiles) {
+  Record.push_back(FileUID);
+}
+Stream.EmitRecord(SUBMODULE_IMPORTED_HEADERS, Record);
+  }
+}
+
 // Emit the exports.
 if (!Mod->Exports.empty()) {
   RecordData Record;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,13 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  // Read the file old UID
+  {
+HFI.UID = endian::readNext(d);
+//TODO: seems the index is not needed
+const uint32_t OldIndex = endian::readNext(d);
+  }
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -9271,6 +9278,37 @@
   for (auto *ND : PendingMergedDefinitionsToDeduplicate)
 getContext().deduplicateMergedDefinitonsFor(ND);
   PendingMergedDefinitionsToDeduplicate.clear();
+
+  // Fix up the HeaderSearchInfo UIDs.
+  if (!PendingImportedHeaders.empty()){
+std::map OldToNewUID;
+
+// These HFIs were deserialized and assigned their "old"
+// UID.
+// We need to update them and populate the OldToNewUID map
+// for use next.
+HeaderSearch& HS = PP->getHeaderSearchInfo();
+for (unsigned NewUID = 0; NewUID < HS.FileInfo.size(); ++NewUID) {
+  OldToNewUID[HS.FileInfo[NewUID].UID] = NewUID;
+  HS.FileInfo[NewUID].UID = NewUID;
+}
+
+auto& Iter = PendingImportedHeaders.begin();
+for (unsigned I = 0; I < PendingImportedHeaders.size(); ++I){
+  ModuleFile* ModFile = Iter[I].first;
+  auto& HeaderUIDs = Iter[I].second;
+  Module *M = HS.lookupModule(ModFile->ModuleName);
+
+  SubmoduleState& SubState = PP.Submodulels[M];
+  for (unsigned OldUid : HeaderUIDs) {
+auto NewUIDIt = OldToNewUID.find(OldUid);
+assert(NewUIDIt != OldToNewUID.end());
+
+SubState.IncludedFiles.insert(NewUIDIt->second);
+  }
+}
+PendingImportedHeaders.clear();
+  }
 }
 
 void ASTReader::diagnoseOdrViolations() {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,21 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * 

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-23 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252118.
oontvoo added a comment.

Clear pending action.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1676,6 +1676,14 @@
   }
   LE.write(Offset);
 
+  // Writes the number of importers.
+  LE.write(Data.HFI.Importers.size());
+  if (!Data.HFI.Importers.empty()){
+for (const FileEntry* F : Data.HFI.Importers) {
+  LE.write(F->getUID());
+}
+  }
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,20 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  {
+const uint32_t ImportersCount = endian::readNext(d));
+if (ImportersCount > 0) {
+  // Read the file UIDs and temporarily save it because we don't have
+  // the FileEntry for these yet.
+  for (int i = 0; i < ImportersCount; ++i) {
+HFI.ImportersUIDs.push_back(endian::readNext(d));
+  }
+  // TODO: This is a little inefficient. But don't know of a way to
+  // stores only this HFI.
+  Reader.addPendingHeaderSearch(HS);
+}
+  }
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -9068,7 +9082,7 @@
   while (!PendingIdentifierInfos.empty() || !PendingFunctionTypes.empty() ||
  !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
  !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
- !PendingUpdateRecords.empty()) {
+ !PendingUpdateRecords.empty() || !PendingHeaderSearch.empty()) {
 // If any identifiers with corresponding top-level declarations have
 // been loaded, load those declarations now.
 using TopLevelDeclsMap =
@@ -9143,6 +9157,18 @@
 }
 PendingMacroIDs.clear();
 
+for (auto PendingHS : PendingHeaderSearch) {
+  for (HeaderFileInfo& HFI : PendingHS->FileInfo){
+if (!HFI.FinishedLoadingImporters) {
+  for (uint32_t FUID : HFI.ImporterUIDs) {
+// TODO: find the FileEntry based on UID??
+  }
+  HFI.FinishedLoadingImporters = true;
+}
+  }
+}
+PendingHeaderSearch.clear();
+
 // Wire up the DeclContexts for Decls that we delayed setting until
 // recursive loading is completed.
 while (!PendingDeclContextInfos.empty()) {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,22 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// After module map parsing, this expands to:
-//
-//module stddef {
-//  header "/path_to_builtin_dirs/stddef.h"
-//  textual "stddef.h"
-//}
-//
-// It's common that libc++ and system modules will both define such
-// submodules. Make sure cached results for a builtin header won't
-// prevent other builtin modules to potentially enter the builtin header.
-// Note that builtins are header guarded and the decision to actually
-// enter them is postponed to the controlling macros logic below.
-bool TryEnterHdr = false;
-if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-  TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-ModuleMap::isBuiltinHeader(
-llvm::sys::path::filename(File->getName()));
-
-// Textual headers can be #imported from different modules. Since ObjC
-// headers find in the wild might rely only on #import and do not contain
-// cont

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-23 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252117.
oontvoo marked an inline comment as done.
oontvoo added a comment.

Add a PendingHeaderSearch set


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1676,6 +1676,14 @@
   }
   LE.write(Offset);
 
+  // Writes the number of importers.
+  LE.write(Data.HFI.Importers.size());
+  if (!Data.HFI.Importers.empty()){
+for (const FileEntry* F : Data.HFI.Importers) {
+  LE.write(F->getUID());
+}
+  }
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,20 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  {
+const uint32_t ImportersCount = endian::readNext(d));
+if (ImportersCount > 0) {
+  // Read the file UIDs and temporarily save it because we don't have
+  // the FileEntry for these yet.
+  for (int i = 0; i < ImportersCount; ++i) {
+HFI.ImportersUIDs.push_back(endian::readNext(d));
+  }
+  // TODO: This is a little inefficient. But don't know of a way to
+  // stores only this HFI.
+  Reader.addPendingHeaderSearch(HS);
+}
+  }
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
@@ -9068,7 +9082,7 @@
   while (!PendingIdentifierInfos.empty() || !PendingFunctionTypes.empty() ||
  !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
  !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
- !PendingUpdateRecords.empty()) {
+ !PendingUpdateRecords.empty() || !PendingHeaderSearch.empty()) {
 // If any identifiers with corresponding top-level declarations have
 // been loaded, load those declarations now.
 using TopLevelDeclsMap =
@@ -9143,6 +9157,17 @@
 }
 PendingMacroIDs.clear();
 
+for (auto PendingHS : PendingHeaderSearch) {
+  for (HeaderFileInfo& HFI : PendingHS->FileInfo){
+if (!HFI.FinishedLoadingImporters) {
+  for (uint32_t FUID : HFI.ImporterUIDs) {
+// TODO: find the FileEntry based on UID??
+  }
+  HFI.FinishedLoadingImporters = true;
+}
+  }
+}
+
 // Wire up the DeclContexts for Decls that we delayed setting until
 // recursive loading is completed.
 while (!PendingDeclContextInfos.empty()) {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,22 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// After module map parsing, this expands to:
-//
-//module stddef {
-//  header "/path_to_builtin_dirs/stddef.h"
-//  textual "stddef.h"
-//}
-//
-// It's common that libc++ and system modules will both define such
-// submodules. Make sure cached results for a builtin header won't
-// prevent other builtin modules to potentially enter the builtin header.
-// Note that builtins are header guarded and the decision to actually
-// enter them is postponed to the controlling macros logic below.
-bool TryEnterHdr = false;
-if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-  TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-ModuleMap::isBuiltinHeader(
-llvm::sys::path::filename(File->getName()));
-
-// Textual headers can be #imported from different modules. Since ObjC
-// headers find in the wild might rely only on #import and do not cont

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-23 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 252110.
oontvoo added a comment.

Updated the reader to read the UIDs first, then we'll build up the Importers 
list at the end.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1676,6 +1676,14 @@
   }
   LE.write(Offset);
 
+  // Writes the number of importers.
+  LE.write(Data.HFI.Importers.size());
+  if (!Data.HFI.Importers.empty()){
+for (const FileEntry* F : Data.HFI.Importers) {
+  LE.write(F->getUID());
+}
+  }
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,21 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  {
+const uint32_t ImportersCount = endian::readNext(d));
+if (ImportersCount > 0) {
+
+  // TODO: I don't think this is right because these importers
+  // are NOT guaranteed to be read/loaded before this header???
+  //
+  // Read the file UIDs and temporarily save it because we don't have
+  // the FileEntry for these yet.
+  for (int i = 0; i < ImportersCount; ++i) {
+HFI.ImportersUIDs.push_back(endian::readNext(d));
+  }
+}
+  }
+
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,22 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// After module map parsing, this expands to:
-//
-//module stddef {
-//  header "/path_to_builtin_dirs/stddef.h"
-//  textual "stddef.h"
-//}
-//
-// It's common that libc++ and system modules will both define such
-// submodules. Make sure cached results for a builtin header won't
-// prevent other builtin modules to potentially enter the builtin header.
-// Note that builtins are header guarded and the decision to actually
-// enter them is postponed to the controlling macros logic below.
-bool TryEnterHdr = false;
-if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-  TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-ModuleMap::isBuiltinHeader(
-llvm::sys::path::filename(File->getName()));
-
-// Textual headers can be #imported from different modules. Since ObjC
-// headers find in the wild might rely only on #import and do not contain
-// controlling macros, be conservative and only try to enter textual headers
-// if such macro is present.
-if (!FileInfo.isModuleHeader &&
-FileInfo.getControllingMacro(ExternalLookup))
-  TryEnterHdr = true;
-return TryEnterHdr;
-  };
-
   // If this is a #import directive, check that we have not already imported
   // this header.
   if (isImport) {
 // If this has already been imported, don't import it again.
 FileInfo.isImport = true;
+  }
 
-// Has this already been #import'ed or #include'd?
-if (FileInfo.NumIncludes && !TryEnterImported())
-  return false;
-  } else {
-// Otherwise, if this is a #include of a file that was previously #import'd
-// or if this is the second #include of a #pragma once file, ignore it.
-if (FileInfo.isImport && !TryEnterImported())
-  return false;
+  if (FileInfo.isPragmaOnce || FileInfo.isImport) {
+if (PP.isIncludeVisible(File))return false;
+else {
+  // Mark as 'included'.
+  PP.setIncludeVisible(File);
+
+  // Also record the importer.
+  FileInfo.Importers.push_back(PP.g

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-20 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 251804.
oontvoo added a comment.

Removed accidentally committed file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1676,6 +1676,14 @@
   }
   LE.write(Offset);
 
+  // Writes the number of importers.
+  LE.write(Data.HFI.Importers.size());
+  if (!Data.HFI.Importers.empty()){
+for (const FileEntry* F : Data.HFI.Importers) {
+  LE.write(F->getUID());
+}
+  }
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,12 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  {
+uint32_t ImportersCount = endian::readNext(uint32_t, little>(d));
+if (ImportersCount > 0) {
+  // TODO: read the fileIDs and find the FileEntry* ???
+}
+  }
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,22 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// After module map parsing, this expands to:
-//
-//module stddef {
-//  header "/path_to_builtin_dirs/stddef.h"
-//  textual "stddef.h"
-//}
-//
-// It's common that libc++ and system modules will both define such
-// submodules. Make sure cached results for a builtin header won't
-// prevent other builtin modules to potentially enter the builtin header.
-// Note that builtins are header guarded and the decision to actually
-// enter them is postponed to the controlling macros logic below.
-bool TryEnterHdr = false;
-if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-  TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-ModuleMap::isBuiltinHeader(
-llvm::sys::path::filename(File->getName()));
-
-// Textual headers can be #imported from different modules. Since ObjC
-// headers find in the wild might rely only on #import and do not contain
-// controlling macros, be conservative and only try to enter textual headers
-// if such macro is present.
-if (!FileInfo.isModuleHeader &&
-FileInfo.getControllingMacro(ExternalLookup))
-  TryEnterHdr = true;
-return TryEnterHdr;
-  };
-
   // If this is a #import directive, check that we have not already imported
   // this header.
   if (isImport) {
 // If this has already been imported, don't import it again.
 FileInfo.isImport = true;
+  }
 
-// Has this already been #import'ed or #include'd?
-if (FileInfo.NumIncludes && !TryEnterImported())
-  return false;
-  } else {
-// Otherwise, if this is a #include of a file that was previously #import'd
-// or if this is the second #include of a #pragma once file, ignore it.
-if (FileInfo.isImport && !TryEnterImported())
-  return false;
+  if (FileInfo.isPragmaOnce || FileInfo.isImport) {
+if (PP.isIncludeVisible(File))return false;
+else {
+  // Mark as 'included'.
+  PP.setIncludeVisible(File);
+
+  // Also record the importer.
+  FileInfo.Importers.push_back(PP.getCurrentFileLexer()->getFileEntry());
+}
   }
 
   // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
Index: clang/include/clang/Lex/Preprocessor.h
===
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -51,6 +51,7 @@
 #include 
 #inc

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-20 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo updated this revision to Diff 251801.
oontvoo marked an inline comment as done.
oontvoo added a comment.

Additional change: Also keep "Importers" and de/serialise these.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951

Files:
  clang/include/clang/Lex/#Preprocessor.h#
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/Preprocessor.h
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1676,6 +1676,14 @@
   }
   LE.write(Offset);
 
+  // Writes the number of importers.
+  LE.write(Data.HFI.Importers.size());
+  if (!Data.HFI.Importers.empty()){
+for (const FileEntry* F : Data.HFI.Importers) {
+  LE.write(F->getUID());
+}
+  }
+
   auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(M)) {
   uint32_t Value = (ModID << 2) | (unsigned)Role;
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1898,6 +1898,12 @@
 HFI.Framework = HS->getUniqueFrameworkName(FrameworkName);
   }
 
+  {
+uint32_t ImportersCount = endian::readNext(uint32_t, little>(d));
+if (ImportersCount > 0) {
+  // TODO: read the fileIDs and find the FileEntry* ???
+}
+  }
   assert((End - d) % 4 == 0 &&
  "Wrong data length in HeaderFileInfo deserialization");
   while (d != End) {
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1253,60 +1253,22 @@
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&]() -> bool {
-if (!ModulesEnabled)
-  return false;
-// Ensure FileInfo bits are up to date.
-ModMap.resolveHeaderDirectives(File);
-// Modules with builtins are special; multiple modules use builtins as
-// modular headers, example:
-//
-//module stddef { header "stddef.h" export * }
-//
-// After module map parsing, this expands to:
-//
-//module stddef {
-//  header "/path_to_builtin_dirs/stddef.h"
-//  textual "stddef.h"
-//}
-//
-// It's common that libc++ and system modules will both define such
-// submodules. Make sure cached results for a builtin header won't
-// prevent other builtin modules to potentially enter the builtin header.
-// Note that builtins are header guarded and the decision to actually
-// enter them is postponed to the controlling macros logic below.
-bool TryEnterHdr = false;
-if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-  TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-ModuleMap::isBuiltinHeader(
-llvm::sys::path::filename(File->getName()));
-
-// Textual headers can be #imported from different modules. Since ObjC
-// headers find in the wild might rely only on #import and do not contain
-// controlling macros, be conservative and only try to enter textual headers
-// if such macro is present.
-if (!FileInfo.isModuleHeader &&
-FileInfo.getControllingMacro(ExternalLookup))
-  TryEnterHdr = true;
-return TryEnterHdr;
-  };
-
   // If this is a #import directive, check that we have not already imported
   // this header.
   if (isImport) {
 // If this has already been imported, don't import it again.
 FileInfo.isImport = true;
+  }
 
-// Has this already been #import'ed or #include'd?
-if (FileInfo.NumIncludes && !TryEnterImported())
-  return false;
-  } else {
-// Otherwise, if this is a #include of a file that was previously #import'd
-// or if this is the second #include of a #pragma once file, ignore it.
-if (FileInfo.isImport && !TryEnterImported())
-  return false;
+  if (FileInfo.isPragmaOnce || FileInfo.isImport) {
+if (PP.isIncludeVisible(File))return false;
+else {
+  // Mark as 'included'.
+  PP.setIncludeVisible(File);
+
+  // Also record the importer.
+  FileInfo.Importers.push_back(PP.getCurrentFileLexer()->getFileEntry());
+}
   }
 
   // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
Index: clang/include/clang/Lex/HeaderSearch.h
===
--- cla

[PATCH] D75951: Keep a list of already-included pragma-once files for mods.

2020-03-16 Thread Vy Nguyen via Phabricator via cfe-commits
oontvoo marked an inline comment as done and an inline comment as not done.
oontvoo added inline comments.



Comment at: clang/lib/Lex/HeaderSearch.cpp:1266
+  if (PP.isIncludeVisibleInLocalModule(File, M)) return false;
+  else  PP.setIncludeVisibleForHeader(File, M);
+} else {

oontvoo wrote:
> jyknight wrote:
> > I wonder if this should be just using the CurSubmoduleState. Actually, is 
> > "M" even needed in this function at all -- why isn't everything just using 
> > CurSubmoduleState? (It's very likely I'm just confused about what the 
> > semantics of this are...).
> > "Is M needed ...  ?"
> 
> Yes - I think so because if we're looking at Module header, then I *think* 
> the header's content will/should be visible to the submods in it.
> 
> On the other hand (ie., the else branch), if we're looking a "regular" 
> header, then it should not be visible to the submods  
[not done - re-opening for question]


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75951/new/

https://reviews.llvm.org/D75951



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >