[clang] [Modules] Detect ODR mismatches for enums in non-C++ like in C++. (PR #90298)

2024-05-07 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

In C++ we reject mismatched types coming from different Clang modules. Haven't 
checked the behavior for C++20 modules as I'm not changing it.

In C modules aren't a part of any standard as far as I know. But for Clang 
modules we reject most of the mismatched types coming from different modules. 
The current change extends the set of "most of the mismatched types" to include 
enums.

https://github.com/llvm/llvm-project/pull/90298
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] Detect ODR mismatches for enums in non-C++ like in C++. (PR #90298)

2024-05-02 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai closed 
https://github.com/llvm/llvm-project/pull/90298
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] Detect ODR mismatches for enums in non-C++ like in C++. (PR #90298)

2024-05-01 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

@dwblaikie if you have no further comments, I'll merge this approved change 
some time soon (in a day or two).

https://github.com/llvm/llvm-project/pull/90298
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] Detect ODR mismatches for enums in non-C++ like in C++. (PR #90298)

2024-04-29 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

> Not sure I'm following the response here - but I guess what I'm trying to 
> say, with more words, is that my understanding was that C doesn't have an 
> ODR, and you can have different definitions of a type, with the same name, in 
> C and that's OK.

In different translation units you can still use different types with the same 
name. And you can use enum constant with the same name but different values. It 
is still OK from the compiler's perspective.

> And it sounds like this change makes that not OK in some way? (either by 
> diagnosing/erroring on such divergent types, or assuming they won't diverge 
> and carrying on silently)

The change is for Clang modules only. In the non-modular world including the 
same file twice (no header guards, no pragma once) would result in a type 
redefinition. But with modules it is more likely to find the same type 
definition in multiple modules. To make the compiler more practical we don't 
reject such situations. Though we detect when the types aren't identical and 
don't try to use them interchangeably. The change extends the existing behavior 
for structs/unions to enums.

If you have use cases when different enums should be used interchangeably, I 
can see how to accommodate such use cases.

https://github.com/llvm/llvm-project/pull/90298
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] Detect ODR mismatches for enums in non-C++ like in C++. (PR #90298)

2024-04-29 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

> C doesn't have an odr, does it?

For non-C++ "ODR" has a meaning more like "ODR-inspired checks". But there is 
no language rule that would require enforcement and there is no impact on 
linkage (at least during deserialization).

https://github.com/llvm/llvm-project/pull/90298
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] Detect ODR mismatches for enums in non-C++ like in C++. (PR #90298)

2024-04-26 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai created 
https://github.com/llvm/llvm-project/pull/90298

There is no reason for C and Objective-C to differ from C++ in this matter.

rdar://85531830

>From 8dafc9af06eef1a4b3fba8b5cffeece62967a6fd Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai 
Date: Fri, 26 Apr 2024 16:33:26 -0700
Subject: [PATCH] [Modules] Detect ODR mismatches for enums in non-C++ like in
 C++.

There is no reason for C and Objective-C to differ from C++ in this matter.

rdar://85531830
---
 clang/lib/Serialization/ASTReaderDecl.cpp |  7 +--
 clang/test/Modules/odr_hash-enum.c| 75 +++
 2 files changed, 77 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Modules/odr_hash-enum.c

diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 744f11de88c2f8..6afbbfe20f26b7 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -805,9 +805,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->isCompleteDefinition() &&
-  Reader.getContext().getLangOpts().Modules &&
-  Reader.getContext().getLangOpts().CPlusPlus) {
+  if (ED->isCompleteDefinition() && Reader.getContext().getLangOpts().Modules) 
{
 EnumDecl * = Reader.EnumDefinitions[ED->getCanonicalDecl()];
 if (!OldDef) {
   // This is the first time we've seen an imported definition. Look for a
@@ -3304,8 +3302,7 @@ DeclContext 
*ASTDeclReader::getPrimaryContextForMerging(ASTReader ,
 return RD->getDefinition();
 
   if (auto *ED = dyn_cast(DC))
-return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
-  : nullptr;
+return ED->getDefinition();
 
   if (auto *OID = dyn_cast(DC))
 return OID->getDefinition();
diff --git a/clang/test/Modules/odr_hash-enum.c 
b/clang/test/Modules/odr_hash-enum.c
new file mode 100644
index 00..f8ede923fe2caa
--- /dev/null
+++ b/clang/test/Modules/odr_hash-enum.c
@@ -0,0 +1,75 @@
+// Clear and create directories
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: mkdir %t/cache
+// RUN: mkdir %t/Inputs
+
+// Build first header file
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h
+// RUN: cat %s   >> %t/Inputs/first.h
+
+// Build second header file
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h
+// RUN: cat %s>> %t/Inputs/second.h
+
+// Test that each header can compile
+// RUN: %clang_cc1 -fsyntax-only -x c %t/Inputs/first.h
+// RUN: %clang_cc1 -fsyntax-only -x c %t/Inputs/second.h
+
+// Build module map file
+// RUN: echo "module FirstModule {" >> %t/Inputs/module.modulemap
+// RUN: echo "header \"first.h\""   >> %t/Inputs/module.modulemap
+// RUN: echo "}">> %t/Inputs/module.modulemap
+// RUN: echo "module SecondModule {">> %t/Inputs/module.modulemap
+// RUN: echo "header \"second.h\""  >> %t/Inputs/module.modulemap
+// RUN: echo "}">> %t/Inputs/module.modulemap
+
+// Run test
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/cache -x c -I%t/Inputs -verify %s
+
+#if !defined(FIRST) && !defined(SECOND)
+#include "first.h"
+#include "second.h"
+#endif
+
+#if defined(FIRST)
+enum DifferentEnumConstants { kDifferentEnumConstantsValueFirst };
+#elif defined(SECOND)
+enum DifferentEnumConstants { kDifferentEnumConstantsValueSecond };
+#else
+enum DifferentEnumConstants differentEnumConstants;
+// expected-error@second.h:* {{'kDifferentEnumConstantsValueSecond' from 
module 'SecondModule' is not present in definition of 'enum 
DifferentEnumConstants' in module 'FirstModule'}}
+// expected-note@first.h:* {{definition has no member 
'kDifferentEnumConstantsValueSecond'}}
+#endif
+
+#if defined(FIRST)
+enum DifferentEnumValues { kDifferentEnumValue = 0 };
+#elif defined(SECOND)
+enum DifferentEnumValues { kDifferentEnumValue = 1 };
+#else
+enum DifferentEnumValues differentEnumValue;
+// expected-error@first.h:* {{'DifferentEnumValues' has different definitions 
in different modules; definition in module 'FirstModule' first difference is 
1st element 'kDifferentEnumValue' has an initializer}}
+// expected-note@second.h:* {{but in 'SecondModule' found 1st element 
'kDifferentEnumValue' has different initializer}}
+#endif
+
+#if defined(FIRST)
+enum {
+kAnonymousEnumValueFirst = 1,
+};
+#elif defined(SECOND)
+enum {
+kAnonymousEnumValueSecond = 2,
+};
+#else
+// Anonymous enums don't have to match, no errors expected.
+int anonymousEnumValue = kAnonymousEnumValueFirst + kAnonymousEnumValueSecond;
+#endif
+
+// Keep macros contained to one file.
+#ifdef FIRST
+#undef FIRST
+#endif
+
+#ifdef SECOND
+#undef SECOND
+#endif

___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[clang] [unused-includes] PCHContainerOperations uses MemoryBufferRef, not MemoryBuffer. NFC. (PR #88794)

2024-04-16 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai closed 
https://github.com/llvm/llvm-project/pull/88794
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [unused-includes][Serialization] Remove unused includes. NFC. (PR #88790)

2024-04-16 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai closed 
https://github.com/llvm/llvm-project/pull/88790
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [unused-includes] PCHContainerOperations uses MemoryBufferRef, not MemoryBuffer. NFC. (PR #88794)

2024-04-15 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai created 
https://github.com/llvm/llvm-project/pull/88794

None

>From b95289569d0441ff799282e125e4f9ad16969f12 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai 
Date: Mon, 15 Apr 2024 13:44:54 -0700
Subject: [PATCH] [unused-includes] PCHContainerOperations uses
 MemoryBufferRef, not MemoryBuffer. NFC.

---
 clang/include/clang/Serialization/PCHContainerOperations.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Serialization/PCHContainerOperations.h 
b/clang/include/clang/Serialization/PCHContainerOperations.h
index ddfddf2dafadf9..c9a7e334ce6eb3 100644
--- a/clang/include/clang/Serialization/PCHContainerOperations.h
+++ b/clang/include/clang/Serialization/PCHContainerOperations.h
@@ -12,7 +12,7 @@
 #include "clang/Basic/Module.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryBufferRef.h"
 #include 
 
 namespace llvm {

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


[clang] [unused-includes][Serialization] Remove unused includes. NFC. (PR #88790)

2024-04-15 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai created 
https://github.com/llvm/llvm-project/pull/88790

None

>From 72f8208752d188aa32e9989faecd7c4b11779eb9 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai 
Date: Mon, 15 Apr 2024 13:22:48 -0700
Subject: [PATCH] [unused-includes][Serialization] Remove unused includes. NFC.

---
 clang/include/clang/Serialization/ModuleFileExtension.h | 1 -
 clang/lib/Serialization/ASTReader.cpp   | 1 -
 clang/lib/Serialization/ASTWriterDecl.cpp   | 1 -
 clang/lib/Serialization/ASTWriterStmt.cpp   | 1 -
 clang/lib/Serialization/GeneratePCH.cpp | 1 -
 clang/lib/Serialization/GlobalModuleIndex.cpp   | 1 -
 clang/lib/Serialization/ModuleFileExtension.cpp | 2 +-
 clang/lib/Serialization/PCHContainerOperations.cpp  | 2 --
 8 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/clang/include/clang/Serialization/ModuleFileExtension.h 
b/clang/include/clang/Serialization/ModuleFileExtension.h
index d7d456c8b5db8e..50ce401516275c 100644
--- a/clang/include/clang/Serialization/ModuleFileExtension.h
+++ b/clang/include/clang/Serialization/ModuleFileExtension.h
@@ -9,7 +9,6 @@
 #ifndef LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
 #define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H
 
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/Support/ExtensibleRTTI.h"
 #include "llvm/Support/HashBuilder.h"
 #include "llvm/Support/MD5.h"
diff --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 8c4b460970ad2b..c68f093ebe63f6 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -31,7 +31,6 @@
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/ODRDiagsEmitter.h"
-#include "clang/AST/ODRHash.h"
 #include "clang/AST/OpenACCClause.h"
 #include "clang/AST/OpenMPClause.h"
 #include "clang/AST/RawCommentList.h"
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index 276b6257f1d841..b8003ac2f95f8e 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -16,7 +16,6 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ODRHash.h"
 #include "clang/AST/OpenMPClause.h"
 #include "clang/AST/PrettyDeclStackTrace.h"
 #include "clang/Basic/SourceManager.h"
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp 
b/clang/lib/Serialization/ASTWriterStmt.cpp
index e3816181e2b2b9..a736a7b0ef726c 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -19,7 +19,6 @@
 #include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Lex/Token.h"
-#include "clang/Sema/DeclSpec.h"
 #include "clang/Serialization/ASTRecordWriter.h"
 #include "llvm/Bitstream/BitstreamWriter.h"
 using namespace clang;
diff --git a/clang/lib/Serialization/GeneratePCH.cpp 
b/clang/lib/Serialization/GeneratePCH.cpp
index 2fece29f34487e..bed74399098d7f 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -17,7 +17,6 @@
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/SemaConsumer.h"
-#include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTWriter.h"
 #include "llvm/Bitstream/BitstreamWriter.h"
 
diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp 
b/clang/lib/Serialization/GlobalModuleIndex.cpp
index dd4fc3e009050f..8a8c3cd4acb8e0 100644
--- a/clang/lib/Serialization/GlobalModuleIndex.cpp
+++ b/clang/lib/Serialization/GlobalModuleIndex.cpp
@@ -13,7 +13,6 @@
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "ASTReaderInternals.h"
 #include "clang/Basic/FileManager.h"
-#include "clang/Lex/HeaderSearch.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ModuleFile.h"
 #include "clang/Serialization/PCHContainerOperations.h"
diff --git a/clang/lib/Serialization/ModuleFileExtension.cpp 
b/clang/lib/Serialization/ModuleFileExtension.cpp
index 95fff41e0d7a85..729529b5fca18c 100644
--- a/clang/lib/Serialization/ModuleFileExtension.cpp
+++ b/clang/lib/Serialization/ModuleFileExtension.cpp
@@ -6,7 +6,7 @@
 //
 
//===--===//
 #include "clang/Serialization/ModuleFileExtension.h"
-#include "llvm/ADT/Hashing.h"
+
 using namespace clang;
 
 char ModuleFileExtension::ID = 0;
diff --git a/clang/lib/Serialization/PCHContainerOperations.cpp 
b/clang/lib/Serialization/PCHContainerOperations.cpp
index 56ca3394385b4f..4aedb7debcff28 100644
--- a/clang/lib/Serialization/PCHContainerOperations.cpp
+++ b/clang/lib/Serialization/PCHContainerOperations.cpp
@@ -12,8 +12,6 @@
 
 #include "clang/Serialization/PCHContainerOperations.h"
 #include "clang/AST/ASTConsumer.h"
-#include 

[clang] [clang-scan-deps] Fix contention when updating `TrackingStatistic`s in hot code paths in `FileManager`. (PR #88427)

2024-04-12 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

The bigger idea is that not enabled stats should be negligibly cheap. As for 
me, the problem is in that not being true. Let me check how we have expensive 
stats all the time.

Extra fixes are good but I'm concerned they help only with these specific stats 
while others might still cause problems in different contexts.

https://github.com/llvm/llvm-project/pull/88427
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (PR #84127)

2024-03-12 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

I'm not excited by the complexity we are moving toward with the builtin 
headers. But I don't have any alternatives.

Given the situation we are in, I think the change is ok. But I'd like someone 
else to look at it as it is tricky to reason about it. No blockers from me but 
want more people to review the change.

https://github.com/llvm/llvm-project/pull/84127
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] Headers meant to be included multiple times can be completely invisible in clang module builds (PR #83660)

2024-03-12 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

> Sometimes it does confuse clang, at least I saw problems with a `typedef 
> enum` when I made an include-once header `textual`.

Ok, I see. I would just consider it a bug, not a design decision.

> That's correct. `#import` is an external source - often it comes from the 
> users of the header and not the author, and the users might not be consistent 
> with each other. `textual` comes from the author and a much stronger 
> indicator of intent.

Hmm, I need to think more about it. Usually I prefer for modular builds to act 
like non-modular as it minimizes the surprises and allows to have a portable 
code. But I haven't really considered the implications of such preference.

I see why you prefer to give more priority to `textual`. To give a different 
perspective, what if a developer wants to use a newer library, for example, 
ncurses. The rest of SDK expects an older version and the developer might need 
to do some header gymnastics to make it work. So there are cases when 
developers need to go against library author's intent. I'm thinking that 
library authors aren't able to predict all the ways their library is used, so 
it is useful to have some flexibility around that, even at the cost of misusing 
the library. But this is a general opinion, I don't have specific data about 
the needs to tweak libraries or the risks of a library misuse. So the opinion 
isn't particularly strong.

https://github.com/llvm/llvm-project/pull/83660
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (PR #84127)

2024-03-12 Thread Volodymyr Sapsai via cfe-commits


@@ -7,6 +7,11 @@
  *===---===
  */
 
-#ifndef offsetof
+/*
+ * When -fbuiltin-headers-in-system-modules is set this is a non-modular header
+ * and needs to behave as if it was textual.
+ */
+#if !defined(offsetof) ||  
\
+(__has_feature(modules) && !__building_module(_Builtin_stddef))

vsapsai wrote:

I was thinking about `offsetof` being defined in some header, not in the 
intended system one. And then we [transitively] include 
"\_\_stddef_offsetof.h". Does it mean that in this case "\_\_stddef_offsetof.h" 
is processed only when building module "_Builtin_stddef"?

https://github.com/llvm/llvm-project/pull/84127
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (PR #84127)

2024-03-11 Thread Volodymyr Sapsai via cfe-commits


@@ -7,6 +7,11 @@
  *===---===
  */
 
-#ifndef offsetof
+/*
+ * When -fbuiltin-headers-in-system-modules is set this is a non-modular header
+ * and needs to behave as if it was textual.
+ */
+#if !defined(offsetof) ||  
\
+(__has_feature(modules) && !__building_module(_Builtin_stddef))

vsapsai wrote:

What should happen when `offsetof` is defined and we are building 
non-`_Builtin_stddef` module?

https://github.com/llvm/llvm-project/pull/84127
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (PR #84127)

2024-03-11 Thread Volodymyr Sapsai via cfe-commits


@@ -2498,9 +2498,12 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind 
LeadingToken,
   }
 
   bool NeedsFramework = false;
-  // Don't add the top level headers to the builtin modules if the builtin 
headers
-  // belong to the system modules.
-  if (!Map.LangOpts.BuiltinHeadersInSystemModules || 
ActiveModule->isSubModule() || !isBuiltInModuleName(ActiveModule->Name))
+  // Don't add headers to the builtin modules if the builtin headers belong to
+  // the system modules, with the exception of __stddef_max_align_t.h which
+  // always had its own module.
+  if (!Map.LangOpts.BuiltinHeadersInSystemModules ||
+  !isBuiltInModuleName(ActiveModule->getTopLevelModuleName()) ||
+  ActiveModule->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}))

vsapsai wrote:

Should `_Builtin_stddef_wint_t` be a part of this check too? I don't know the 
right answer, just trying to understand.

https://github.com/llvm/llvm-project/pull/84127
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (PR #84127)

2024-03-11 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai commented:

Still kinda confused. Have a few questions trying to improve my understanding.

https://github.com/llvm/llvm-project/pull/84127
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] giving the __stddef_ headers their own modules can cause redeclaration errors with -fbuiltin-headers-in-system-modules (PR #84127)

2024-03-11 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai edited 
https://github.com/llvm/llvm-project/pull/84127
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][modules] Headers meant to be included multiple times can be completely invisible in clang module builds (PR #83660)

2024-03-11 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

To clarify a little bit
> [...] The "already included" state is global across all modules (which is 
> necessary so that non-modular headers don't get compiled into multiple 
> translation units and cause redeclaration errors).

The necessity isn't actually true. The same definition in multiple modules 
shouldn't confuse clang as long as these definitions are identical. But this is 
a side issue.

To re-iterate what this change is about:
1. `#import` implies a file is a single-include
2. Textual header in a module map implies a file is a multi-include (aka 
re-entrant)
3. When we have both `#import` and the header marked as textual, `#import` 
"wins", i.e. the file is single-include
4. You want to make that when we have both `#import` and a textual header, 
textual should "win", i.e. the file should be multi-include

Is it correct?

https://github.com/llvm/llvm-project/pull/83660
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -22,7 +58,10 @@
 #define WANT_BAR 1 // expected-note{{macro was defined here}}
 @import config; // expected-warning{{definition of configuration macro 
'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on 
the command line to configure the module}}
 
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c 
-fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config 
%S/Inputs/module.modulemap
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify
+//--- config_error.m

vsapsai wrote:

That works. I like how for other cases we have the *intention* of the test 
written down. And I don't think it would lead to the proliferation of 
"config_error2.m", "config_error3.m".

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -2006,6 +2021,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
 // Use the cached result, which may be nullptr.
 Module = *MaybeModule;
+// Config macros are already checked before building a module, but they 
need
+// to be checked at each import location in case any of the config macros
+// have a new value at the current `ImportLoc`.
+if (Module)
+  checkConfigMacros(getPreprocessor(), Module, ImportLoc);
   } else if (ModuleName == getLangOpts().CurrentModule) {
 // This is the module we're building.
 Module = PP->getHeaderSearchInfo().lookupModule(

vsapsai wrote:

Thanks for checking this case!

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai approved this pull request.


https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai edited 
https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -22,7 +58,10 @@
 #define WANT_BAR 1 // expected-note{{macro was defined here}}
 @import config; // expected-warning{{definition of configuration macro 
'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on 
the command line to configure the module}}
 
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c 
-fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config 
%S/Inputs/module.modulemap
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify
+//--- config_error.m

vsapsai wrote:

I was thinking about having a more descriptive name because it's not the only 
way to get an error. Does "config_macro_required_not_on_command_line.m" capture 
the purpose of the test?

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -1,3 +1,39 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c 
-fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config 
%t/module.modulemap
+// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t -I %t -DWANT_FOO=1 %t/config.m -verify
+// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t -I %t -DTEST_ERROR %t/config_error.m -verify
+
+//--- module.modulemap
+
+module config {
+  header "config.h"
+  config_macros [exhaustive] WANT_FOO, WANT_BAR
+}
+
+module config_error {
+  header "config_error.h"
+  config_macros SOME_VALUE
+}
+
+//--- config.h
+
+#ifdef WANT_FOO
+int* foo(void);
+#endif
+
+#ifdef WANT_BAR
+char *bar(void);
+#endif
+
+//--- config_error.h
+
+struct my_thing {
+  char buf[SOME_VALUE];

vsapsai wrote:

Don't think it is worth verifying in the test but we have a diagnostic
```
error: use of undeclared identifier 'SOME_VALUE'
```
which is still useful when we have no corresponding macro defined anywhere.

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -22,7 +58,10 @@
 #define WANT_BAR 1 // expected-note{{macro was defined here}}
 @import config; // expected-warning{{definition of configuration macro 
'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on 
the command line to configure the module}}
 
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c 
-fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config 
%S/Inputs/module.modulemap
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify
+//--- config_error.m
 
+#ifdef TEST_ERROR
+#define SOME_VALUE 5 // expected-note{{macro was defined here}}
+@import config_error; // expected-error{{could not build module}} \
+  // expected-warning{{definition of configuration macro 
'SOME_VALUE' has no effect on the import of 'config_error';}}

vsapsai wrote:

Not sure if it is worth testing the part `pass '-DSOME_VALUE=...' on the 
command line to configure the module` but can confirm there is an actionable 
recommendation here.

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -2006,6 +2021,11 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
   if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {
 // Use the cached result, which may be nullptr.
 Module = *MaybeModule;
+// Config macros are already checked before building a module, but they 
need
+// to be checked at each import location in case any of the config macros
+// have a new value at the current `ImportLoc`.
+if (Module)
+  checkConfigMacros(getPreprocessor(), Module, ImportLoc);
   } else if (ModuleName == getLangOpts().CurrentModule) {
 // This is the module we're building.
 Module = PP->getHeaderSearchInfo().lookupModule(

vsapsai wrote:

Do we need to `checkConfigMacros` for a module in this case? It is that we have
```
if
  check
else if
  no check <- comment about this block
else
  check in the called method
```

Don't know the code good enough to tell if it is required or not, just noticed 
an inconsistency.

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Diagnose config_macros before building modules (PR #83641)

2024-03-04 Thread Volodymyr Sapsai via cfe-commits


@@ -22,7 +58,10 @@
 #define WANT_BAR 1 // expected-note{{macro was defined here}}
 @import config; // expected-warning{{definition of configuration macro 
'WANT_BAR' has no effect on the import of 'config'; pass '-DWANT_BAR=...' on 
the command line to configure the module}}
 
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps -x objective-c 
-fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config 
%S/Inputs/module.modulemap
-// RUN: %clang_cc1 -std=c99 -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify
+//--- config_error.m
 
+#ifdef TEST_ERROR

vsapsai wrote:

What is the point of wrapping everything in `TEST_ERROR`?

https://github.com/llvm/llvm-project/pull/83641
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits


@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/foo.cpp -I%t -fsyntax-only -verify
+
+//--- i.h
+#ifndef FOO_H
+#pragma once
+struct S{};
+#endif
+
+//--- foo.cpp

vsapsai wrote:

Personally I would name the file as test.cpp but don't have a strong opinion.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits


@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/foo.cpp -I%t -fsyntax-only -verify

vsapsai wrote:

You don't really need `-I%t`, the test works without it. But don't have a 
strong opinion.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits


@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/foo.cpp -I%t -fsyntax-only -verify
+
+//--- i.h
+#ifndef FOO_H

vsapsai wrote:

The mismatch between i.h and FOO_H is slightly annoying but don't think it is 
bad enough to block the change.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits


@@ -1458,7 +1458,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor 
,
   } 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.isPragmaOnce || FileInfo.isImport) && !TryEnterImported())

vsapsai wrote:

Technically, `TryEnterImported` can be inlined at another call site but I think 
it's not worth it and we can keep things the way you have in PR.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits


@@ -1458,7 +1458,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor 
,
   } 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.

vsapsai wrote:

Surprisingly, the comment is more correct now.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai approved this pull request.

Overall, the change works fine and it is pretty small. Have a few minor 
suggestion for the test but nothing blocking.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits

https://github.com/vsapsai edited 
https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-23 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

So far the testing shows there are no regressions.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2024-01-17 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

Started some of the tests. Expect to have results by the end of this week or 
early next week.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Modules] [HeaderSearch] Don't reenter headers if it is pragma once (PR #76119)

2023-12-23 Thread Volodymyr Sapsai via cfe-commits

vsapsai wrote:

I'll need to test this change on the real code to see the consequences. Sorry, 
I'll be able to do that in January only.

https://github.com/llvm/llvm-project/pull/76119
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 52c62d4 - Reland "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays."

2023-08-16 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-08-16T18:27:17-07:00
New Revision: 52c62d46a0c8ebf6023233cabc5beb4ee2687c78

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

LOG: Reland "[modules] Fix error about the same module being defined in 
different .pcm files when using VFS overlays."

Fixing Windows buildbot by not using "BuildTemporaries/module.modulemap"
because it is interpreted as defining a module in "BuildTemporaries" directory.

Fix errors like
> module 'MultiPath' is defined in both 
> 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-1352QHUF8RNMU.pcm' and 
> 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-20HNSLLIUDDV1.pcm'

To avoid building extra identical modules `-ivfsoverlay` option is not a
part of the hash like "/3JR48BPRU7BCG/". And it is build system's
responsibility to provide `-ivfsoverlay` options that don't cause
observable differences.  We also need to make sure the hash like
"-1352QHUF8RNMU" is not affected by `-ivfsoverlay`. As this hash is
defined by the module map path, use the path prior to any VFS
remappings.

rdar://111921464

Differential Revision: https://reviews.llvm.org/D156749

Added: 
clang/test/VFS/module-map-path.m

Modified: 
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Serialization/ASTWriter.cpp

Removed: 




diff  --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index f42d51d65dcdf3..80e1bad72ce9b7 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -177,7 +177,7 @@ std::string HeaderSearch::getCachedModuleFileName(Module 
*Module) {
   // *.modulemap file. In this case, just return an empty string.
   if (!ModuleMap)
 return {};
-  return getCachedModuleFileName(Module->Name, ModuleMap->getName());
+  return getCachedModuleFileName(Module->Name, 
ModuleMap->getNameAsRequested());
 }
 
 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 8b0015f1ee9f6c..289c0383cd4b0e 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1327,7 +1327,8 @@ void ASTWriter::WriteControlBlock(Preprocessor , 
ASTContext ,
 
 auto  = PP.getHeaderSearchInfo().getModuleMap();
 AddPath(WritingModule->PresumedModuleMapFile.empty()
-? Map.getModuleMapFileForUniquing(WritingModule)->getName()
+? Map.getModuleMapFileForUniquing(WritingModule)
+  ->getNameAsRequested()
 : StringRef(WritingModule->PresumedModuleMapFile),
 Record);
 

diff  --git a/clang/test/VFS/module-map-path.m 
b/clang/test/VFS/module-map-path.m
new file mode 100644
index 00..bd9b961ba860ce
--- /dev/null
+++ b/clang/test/VFS/module-map-path.m
@@ -0,0 +1,110 @@
+// Test the module map path is consistent between clang invocations when using 
VFS overlays.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// Pre-populate the module cache with the modules that don't use VFS overlays.
+// RUN: %clang_cc1 -fsyntax-only -F%t/Frameworks -I%t/include 
%t/prepopulate_module_cache.m \
+// RUN: -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+
+// Execute a compilation with VFS overlay. .pcm file path looks like 
/ModuleName-.pcm.
+//  corresponds to the compilation settings like language options.
+//  corresponds to the module map path. So if any of those change, we 
should use a 
diff erent module.
+// But for VFS overlay we make an exception that it's not a part of  to 
reduce the number of built .pcm files.
+// Test that paths in overlays don't leak into  and don't cause using 2 
.pcm files for the same module.
+// DEFINE: %{command} = %clang_cc1 -fsyntax-only -verify -F%t/Frameworks 
-I%t/include %t/test.m \
+// DEFINE:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@@g" %t/overlay.yaml.template > 
%t/external-names-default.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-default.yaml
+
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': true,@g" 
%t/overlay.yaml.template > %t/external-names-true.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-true.yaml
+
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': false,@g" 
%t/overlay.yaml.template > %t/external-names-false.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-false.yaml
+
+//--- prepopulate_module_cache.m
+#import 
+
+//--- test.m
+// At first import multi-path modules directly, so clang decides which .pcm 
file they should belong to.
+#import 
+#import 
+
+// 

[clang] fe9c332 - Revert "Reland "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays.""

2023-08-10 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-08-10T15:14:26-07:00
New Revision: fe9c332408603e50ab846c1ad8aeb705df2950b1

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

LOG: Revert "Reland "[modules] Fix error about the same module being defined in 
different .pcm files when using VFS overlays.""

This reverts commit b070be82bb8fb4414a8a6eb4fbfc77921d89fa4b.

Added: 


Modified: 
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Serialization/ASTWriter.cpp

Removed: 
clang/test/VFS/module-map-path.m



diff  --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 80e1bad72ce9b7..f42d51d65dcdf3 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -177,7 +177,7 @@ std::string HeaderSearch::getCachedModuleFileName(Module 
*Module) {
   // *.modulemap file. In this case, just return an empty string.
   if (!ModuleMap)
 return {};
-  return getCachedModuleFileName(Module->Name, 
ModuleMap->getNameAsRequested());
+  return getCachedModuleFileName(Module->Name, ModuleMap->getName());
 }
 
 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 289c0383cd4b0e..8b0015f1ee9f6c 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1327,8 +1327,7 @@ void ASTWriter::WriteControlBlock(Preprocessor , 
ASTContext ,
 
 auto  = PP.getHeaderSearchInfo().getModuleMap();
 AddPath(WritingModule->PresumedModuleMapFile.empty()
-? Map.getModuleMapFileForUniquing(WritingModule)
-  ->getNameAsRequested()
+? Map.getModuleMapFileForUniquing(WritingModule)->getName()
 : StringRef(WritingModule->PresumedModuleMapFile),
 Record);
 

diff  --git a/clang/test/VFS/module-map-path.m 
b/clang/test/VFS/module-map-path.m
deleted file mode 100644
index da7fb3f0089578..00
--- a/clang/test/VFS/module-map-path.m
+++ /dev/null
@@ -1,110 +0,0 @@
-// Test the module map path is consistent between clang invocations when using 
VFS overlays.
-
-// RUN: rm -rf %t
-// RUN: split-file %s %t
-
-// Pre-populate the module cache with the modules that don't use VFS overlays.
-// RUN: %clang_cc1 -fsyntax-only -F%/t/Frameworks -I%/t/include 
%t/prepopulate_module_cache.m \
-// RUN: -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
-
-// Execute a compilation with VFS overlay. .pcm file path looks like 
/ModuleName-.pcm.
-//  corresponds to the compilation settings like language options.
-//  corresponds to the module map path. So if any of those change, we 
should use a 
diff erent module.
-// But for VFS overlay we make an exception that it's not a part of  to 
reduce the number of built .pcm files.
-// Test that paths in overlays don't leak into  and don't cause using 2 
.pcm files for the same module.
-// DEFINE: %{command} = %clang_cc1 -fsyntax-only -verify -F%/t/Frameworks 
-I%/t/include %t/test.m \
-// DEFINE:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
-// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@@g" %t/overlay.yaml.template > 
%t/external-names-default.yaml
-// RUN: %{command} -ivfsoverlay %t/external-names-default.yaml
-
-// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': true,@g" 
%t/overlay.yaml.template > %t/external-names-true.yaml
-// RUN: %{command} -ivfsoverlay %t/external-names-true.yaml
-
-// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': false,@g" 
%t/overlay.yaml.template > %t/external-names-false.yaml
-// RUN: %{command} -ivfsoverlay %t/external-names-false.yaml
-
-//--- prepopulate_module_cache.m
-#import 
-
-//--- test.m
-// At first import multi-path modules directly, so clang decides which .pcm 
file they should belong to.
-#import 
-#import 
-
-// Then import a module from the module cache and all its transitive 
dependencies.
-// Make sure the .pcm files loaded directly are the same as 'Redirecting' is 
referencing.
-#import 
-// expected-no-diagnostics
-
-
-//--- Frameworks/MultiPath.framework/Headers/MultiPath.h
-void multiPathFramework(void);
-
-//--- Frameworks/MultiPath.framework/Modules/module.modulemap
-framework module MultiPath {
-header "MultiPath.h"
-export *
-}
-
-
-//--- include/MultiPathHeader.h
-void multiPathHeader(void);
-
-//--- include/module.modulemap
-module MultiPathHeader {
-header "MultiPathHeader.h"
-export *
-}
-
-
-//--- Frameworks/Redirecting.framework/Headers/Redirecting.h
-#import 
-#import 
-
-//--- 

[clang] b070be8 - Reland "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays."

2023-08-10 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-08-10T14:52:49-07:00
New Revision: b070be82bb8fb4414a8a6eb4fbfc77921d89fa4b

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

LOG: Reland "[modules] Fix error about the same module being defined in 
different .pcm files when using VFS overlays."

Fixing Windows buildbot by using the same separators for `-F` and `-I`
paths both in VFS overlay and on command line.

Fix errors like
> module 'MultiPath' is defined in both 
> 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-1352QHUF8RNMU.pcm' and 
> 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-20HNSLLIUDDV1.pcm'

To avoid building extra identical modules `-ivfsoverlay` option is not a
part of the hash like "/3JR48BPRU7BCG/". And it is build system's
responsibility to provide `-ivfsoverlay` options that don't cause
observable differences.  We also need to make sure the hash like
"-1352QHUF8RNMU" is not affected by `-ivfsoverlay`. As this hash is
defined by the module map path, use the path prior to any VFS
remappings.

rdar://111921464

Differential Revision: https://reviews.llvm.org/D156749

Added: 
clang/test/VFS/module-map-path.m

Modified: 
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Serialization/ASTWriter.cpp

Removed: 




diff  --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index f42d51d65dcdf3..80e1bad72ce9b7 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -177,7 +177,7 @@ std::string HeaderSearch::getCachedModuleFileName(Module 
*Module) {
   // *.modulemap file. In this case, just return an empty string.
   if (!ModuleMap)
 return {};
-  return getCachedModuleFileName(Module->Name, ModuleMap->getName());
+  return getCachedModuleFileName(Module->Name, 
ModuleMap->getNameAsRequested());
 }
 
 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 8b0015f1ee9f6c..289c0383cd4b0e 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1327,7 +1327,8 @@ void ASTWriter::WriteControlBlock(Preprocessor , 
ASTContext ,
 
 auto  = PP.getHeaderSearchInfo().getModuleMap();
 AddPath(WritingModule->PresumedModuleMapFile.empty()
-? Map.getModuleMapFileForUniquing(WritingModule)->getName()
+? Map.getModuleMapFileForUniquing(WritingModule)
+  ->getNameAsRequested()
 : StringRef(WritingModule->PresumedModuleMapFile),
 Record);
 

diff  --git a/clang/test/VFS/module-map-path.m 
b/clang/test/VFS/module-map-path.m
new file mode 100644
index 00..da7fb3f0089578
--- /dev/null
+++ b/clang/test/VFS/module-map-path.m
@@ -0,0 +1,110 @@
+// Test the module map path is consistent between clang invocations when using 
VFS overlays.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// Pre-populate the module cache with the modules that don't use VFS overlays.
+// RUN: %clang_cc1 -fsyntax-only -F%/t/Frameworks -I%/t/include 
%t/prepopulate_module_cache.m \
+// RUN: -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+
+// Execute a compilation with VFS overlay. .pcm file path looks like 
/ModuleName-.pcm.
+//  corresponds to the compilation settings like language options.
+//  corresponds to the module map path. So if any of those change, we 
should use a 
diff erent module.
+// But for VFS overlay we make an exception that it's not a part of  to 
reduce the number of built .pcm files.
+// Test that paths in overlays don't leak into  and don't cause using 2 
.pcm files for the same module.
+// DEFINE: %{command} = %clang_cc1 -fsyntax-only -verify -F%/t/Frameworks 
-I%/t/include %t/test.m \
+// DEFINE:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@@g" %t/overlay.yaml.template > 
%t/external-names-default.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-default.yaml
+
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': true,@g" 
%t/overlay.yaml.template > %t/external-names-true.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-true.yaml
+
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': false,@g" 
%t/overlay.yaml.template > %t/external-names-false.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-false.yaml
+
+//--- prepopulate_module_cache.m
+#import 
+
+//--- test.m
+// At first import multi-path modules directly, so clang decides which .pcm 
file they should belong to.
+#import 
+#import 
+
+// Then import a module from the 

[clang] 91b10f6 - Revert "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays."

2023-08-10 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-08-10T11:27:08-07:00
New Revision: 91b10f69740ec91ca80ec45323d9807c39252334

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

LOG: Revert "[modules] Fix error about the same module being defined in 
different .pcm files when using VFS overlays."

This reverts commit 97dfaf4cd27814bdf9aa9d2eafc21fdb4f76c56d.

llvm-clang-x86_64-sie-win buildbot is failing with the added test.

Added: 


Modified: 
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Serialization/ASTWriter.cpp

Removed: 
clang/test/VFS/module-map-path.m



diff  --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 80e1bad72ce9b7..f42d51d65dcdf3 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -177,7 +177,7 @@ std::string HeaderSearch::getCachedModuleFileName(Module 
*Module) {
   // *.modulemap file. In this case, just return an empty string.
   if (!ModuleMap)
 return {};
-  return getCachedModuleFileName(Module->Name, 
ModuleMap->getNameAsRequested());
+  return getCachedModuleFileName(Module->Name, ModuleMap->getName());
 }
 
 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 289c0383cd4b0e..8b0015f1ee9f6c 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1327,8 +1327,7 @@ void ASTWriter::WriteControlBlock(Preprocessor , 
ASTContext ,
 
 auto  = PP.getHeaderSearchInfo().getModuleMap();
 AddPath(WritingModule->PresumedModuleMapFile.empty()
-? Map.getModuleMapFileForUniquing(WritingModule)
-  ->getNameAsRequested()
+? Map.getModuleMapFileForUniquing(WritingModule)->getName()
 : StringRef(WritingModule->PresumedModuleMapFile),
 Record);
 

diff  --git a/clang/test/VFS/module-map-path.m 
b/clang/test/VFS/module-map-path.m
deleted file mode 100644
index 0f3c0a7aa499eb..00
--- a/clang/test/VFS/module-map-path.m
+++ /dev/null
@@ -1,110 +0,0 @@
-// Test the module map path is consistent between clang invocations when using 
VFS overlays.
-
-// RUN: rm -rf %t
-// RUN: split-file %s %t
-
-// Pre-populate the module cache with the modules that don't use VFS overlays.
-// RUN: %clang_cc1 -fsyntax-only -F%t/Frameworks -I%t/include 
%t/prepopulate_module_cache.m \
-// RUN: -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
-
-// Execute a compilation with VFS overlay. .pcm file path looks like 
/ModuleName-.pcm.
-//  corresponds to the compilation settings like language options.
-//  corresponds to the module map path. So if any of those change, we 
should use a 
diff erent module.
-// But for VFS overlay we make an exception that it's not a part of  to 
reduce the number of built .pcm files.
-// Test that paths in overlays don't leak into  and don't cause using 2 
.pcm files for the same module.
-// DEFINE: %{command} = %clang_cc1 -fsyntax-only -verify -F%t/Frameworks 
-I%t/include %t/test.m \
-// DEFINE:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
-// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@@g" %t/overlay.yaml.template > 
%t/external-names-default.yaml
-// RUN: %{command} -ivfsoverlay %t/external-names-default.yaml
-
-// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': true,@g" 
%t/overlay.yaml.template > %t/external-names-true.yaml
-// RUN: %{command} -ivfsoverlay %t/external-names-true.yaml
-
-// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': false,@g" 
%t/overlay.yaml.template > %t/external-names-false.yaml
-// RUN: %{command} -ivfsoverlay %t/external-names-false.yaml
-
-//--- prepopulate_module_cache.m
-#import 
-
-//--- test.m
-// At first import multi-path modules directly, so clang decides which .pcm 
file they should belong to.
-#import 
-#import 
-
-// Then import a module from the module cache and all its transitive 
dependencies.
-// Make sure the .pcm files loaded directly are the same as 'Redirecting' is 
referencing.
-#import 
-// expected-no-diagnostics
-
-
-//--- Frameworks/MultiPath.framework/Headers/MultiPath.h
-void multiPathFramework(void);
-
-//--- Frameworks/MultiPath.framework/Modules/module.modulemap
-framework module MultiPath {
-header "MultiPath.h"
-export *
-}
-
-
-//--- include/MultiPathHeader.h
-void multiPathHeader(void);
-
-//--- include/module.modulemap
-module MultiPathHeader {
-header "MultiPathHeader.h"
-export *
-}
-
-
-//--- Frameworks/Redirecting.framework/Headers/Redirecting.h
-#import 
-#import 
-

[clang] 97dfaf4 - [modules] Fix error about the same module being defined in different .pcm files when using VFS overlays.

2023-08-10 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-08-10T10:47:51-07:00
New Revision: 97dfaf4cd27814bdf9aa9d2eafc21fdb4f76c56d

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

LOG: [modules] Fix error about the same module being defined in different .pcm 
files when using VFS overlays.

Fix errors like
> module 'MultiPath' is defined in both 
> 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-1352QHUF8RNMU.pcm' and 
> 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-20HNSLLIUDDV1.pcm'

To avoid building extra identical modules `-ivfsoverlay` option is not a
part of the hash like "/3JR48BPRU7BCG/". And it is build system's
responsibility to provide `-ivfsoverlay` options that don't cause
observable differences.  We also need to make sure the hash like
"-1352QHUF8RNMU" is not affected by `-ivfsoverlay`. As this hash is
defined by the module map path, use the path prior to any VFS
remappings.

rdar://111921464

Differential Revision: https://reviews.llvm.org/D156749

Added: 
clang/test/VFS/module-map-path.m

Modified: 
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Serialization/ASTWriter.cpp

Removed: 




diff  --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index f42d51d65dcdf3..80e1bad72ce9b7 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -177,7 +177,7 @@ std::string HeaderSearch::getCachedModuleFileName(Module 
*Module) {
   // *.modulemap file. In this case, just return an empty string.
   if (!ModuleMap)
 return {};
-  return getCachedModuleFileName(Module->Name, ModuleMap->getName());
+  return getCachedModuleFileName(Module->Name, 
ModuleMap->getNameAsRequested());
 }
 
 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 8b0015f1ee9f6c..289c0383cd4b0e 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1327,7 +1327,8 @@ void ASTWriter::WriteControlBlock(Preprocessor , 
ASTContext ,
 
 auto  = PP.getHeaderSearchInfo().getModuleMap();
 AddPath(WritingModule->PresumedModuleMapFile.empty()
-? Map.getModuleMapFileForUniquing(WritingModule)->getName()
+? Map.getModuleMapFileForUniquing(WritingModule)
+  ->getNameAsRequested()
 : StringRef(WritingModule->PresumedModuleMapFile),
 Record);
 

diff  --git a/clang/test/VFS/module-map-path.m 
b/clang/test/VFS/module-map-path.m
new file mode 100644
index 00..0f3c0a7aa499eb
--- /dev/null
+++ b/clang/test/VFS/module-map-path.m
@@ -0,0 +1,110 @@
+// Test the module map path is consistent between clang invocations when using 
VFS overlays.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// Pre-populate the module cache with the modules that don't use VFS overlays.
+// RUN: %clang_cc1 -fsyntax-only -F%t/Frameworks -I%t/include 
%t/prepopulate_module_cache.m \
+// RUN: -fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+
+// Execute a compilation with VFS overlay. .pcm file path looks like 
/ModuleName-.pcm.
+//  corresponds to the compilation settings like language options.
+//  corresponds to the module map path. So if any of those change, we 
should use a 
diff erent module.
+// But for VFS overlay we make an exception that it's not a part of  to 
reduce the number of built .pcm files.
+// Test that paths in overlays don't leak into  and don't cause using 2 
.pcm files for the same module.
+// DEFINE: %{command} = %clang_cc1 -fsyntax-only -verify -F%t/Frameworks 
-I%t/include %t/test.m \
+// DEFINE:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@@g" %t/overlay.yaml.template > 
%t/external-names-default.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-default.yaml
+
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': true,@g" 
%t/overlay.yaml.template > %t/external-names-true.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-true.yaml
+
+// RUN: sed -e "s@TMP_DIR@%{/t:regex_replacement}@g" -e 
"s@USE_EXTERNAL_NAMES_OPTION@'use-external-names': false,@g" 
%t/overlay.yaml.template > %t/external-names-false.yaml
+// RUN: %{command} -ivfsoverlay %t/external-names-false.yaml
+
+//--- prepopulate_module_cache.m
+#import 
+
+//--- test.m
+// At first import multi-path modules directly, so clang decides which .pcm 
file they should belong to.
+#import 
+#import 
+
+// Then import a module from the module cache and all its transitive 
dependencies.
+// Make sure the .pcm files loaded directly are the same as 'Redirecting' is 

[clang] 32056aa - [docs] Fix doxygen markers for grouping methods. NFC.

2023-08-03 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-08-03T11:16:42-07:00
New Revision: 32056aa3443786822963e6e469d98deb7b857d79

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

LOG: [docs] Fix doxygen markers for grouping methods. NFC.

Added: 


Modified: 
clang/include/clang/Frontend/CompilerInstance.h

Removed: 




diff  --git a/clang/include/clang/Frontend/CompilerInstance.h 
b/clang/include/clang/Frontend/CompilerInstance.h
index c6af1fd5dd010f..377055e8f6f924 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -189,7 +189,7 @@ class CompilerInstance : public ModuleLoader {
   ~CompilerInstance() override;
 
   /// @name High-Level Operations
-  /// {
+  /// @{
 
   /// ExecuteAction - Execute the provided action against the compiler's
   /// CompilerInvocation object.
@@ -223,9 +223,9 @@ class CompilerInstance : public ModuleLoader {
   /// Load the list of plugins requested in the \c FrontendOptions.
   void LoadRequestedPlugins();
 
-  /// }
+  /// @}
   /// @name Compiler Invocation and Options
-  /// {
+  /// @{
 
   bool hasInvocation() const { return Invocation != nullptr; }
 
@@ -248,9 +248,9 @@ class CompilerInstance : public ModuleLoader {
 BuildGlobalModuleIndex = Build;
   }
 
-  /// }
+  /// @}
   /// @name Forwarding Methods
-  /// {
+  /// @{
 
   AnalyzerOptionsRef getAnalyzerOpts() {
 return Invocation->getAnalyzerOpts();
@@ -329,9 +329,9 @@ class CompilerInstance : public ModuleLoader {
 return Invocation->getTargetOpts();
   }
 
-  /// }
+  /// @}
   /// @name Diagnostics Engine
-  /// {
+  /// @{
 
   bool hasDiagnostics() const { return Diagnostics != nullptr; }
 
@@ -355,9 +355,9 @@ class CompilerInstance : public ModuleLoader {
 return *Diagnostics->getClient();
   }
 
-  /// }
+  /// @}
   /// @name VerboseOutputStream
-  /// }
+  /// @{
 
   /// Replace the current stream for verbose output.
   void setVerboseOutputStream(raw_ostream );
@@ -370,9 +370,9 @@ class CompilerInstance : public ModuleLoader {
 return *VerboseOutputStream;
   }
 
-  /// }
+  /// @}
   /// @name Target Info
-  /// {
+  /// @{
 
   bool hasTarget() const { return Target != nullptr; }
 
@@ -389,9 +389,9 @@ class CompilerInstance : public ModuleLoader {
   /// Replace the current Target.
   void setTarget(TargetInfo *Value);
 
-  /// }
+  /// @}
   /// @name AuxTarget Info
-  /// {
+  /// @{
 
   TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
 
@@ -401,15 +401,15 @@ class CompilerInstance : public ModuleLoader {
   // Create Target and AuxTarget based on current options
   bool createTarget();
 
-  /// }
+  /// @}
   /// @name Virtual File System
-  /// {
+  /// @{
 
   llvm::vfs::FileSystem () const;
 
-  /// }
+  /// @}
   /// @name File Manager
-  /// {
+  /// @{
 
   bool hasFileManager() const { return FileMgr != nullptr; }
 
@@ -432,9 +432,9 @@ class CompilerInstance : public ModuleLoader {
   /// Replace the current file manager and virtual file system.
   void setFileManager(FileManager *Value);
 
-  /// }
+  /// @}
   /// @name Source Manager
-  /// {
+  /// @{
 
   bool hasSourceManager() const { return SourceMgr != nullptr; }
 
@@ -457,9 +457,9 @@ class CompilerInstance : public ModuleLoader {
   /// setSourceManager - Replace the current source manager.
   void setSourceManager(SourceManager *Value);
 
-  /// }
+  /// @}
   /// @name Preprocessor
-  /// {
+  /// @{
 
   bool hasPreprocessor() const { return PP != nullptr; }
 
@@ -478,9 +478,9 @@ class CompilerInstance : public ModuleLoader {
   /// Replace the current preprocessor.
   void setPreprocessor(std::shared_ptr Value);
 
-  /// }
+  /// @}
   /// @name ASTContext
-  /// {
+  /// @{
 
   bool hasASTContext() const { return Context != nullptr; }
 
@@ -506,9 +506,9 @@ class CompilerInstance : public ModuleLoader {
   /// of S.
   void setSema(Sema *S);
 
-  /// }
+  /// @}
   /// @name ASTConsumer
-  /// {
+  /// @{
 
   bool hasASTConsumer() const { return (bool)Consumer; }
 
@@ -525,9 +525,9 @@ class CompilerInstance : public ModuleLoader {
   /// takes ownership of \p Value.
   void setASTConsumer(std::unique_ptr Value);
 
-  /// }
+  /// @}
   /// @name Semantic analysis
-  /// {
+  /// @{
   bool hasSema() const { return (bool)TheSema; }
 
   Sema () const {
@@ -538,9 +538,9 @@ class CompilerInstance : public ModuleLoader {
   std::unique_ptr takeSema();
   void resetAndLeakSema();
 
-  /// }
+  /// @}
   /// @name Module Management
-  /// {
+  /// @{
 
   IntrusiveRefCntPtr getASTReader() const;
   void setASTReader(IntrusiveRefCntPtr Reader);
@@ -581,9 +581,9 @@ class CompilerInstance : public ModuleLoader {
 return *Reader;
   }
 
-  /// }
+  /// @}
   /// @name Code Completion
-  /// {
+  /// @{
 
   bool 

[clang] d1e8df8 - [clang] Fix a typo "mdoule" in comments. NFC.

2023-07-06 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-07-06T17:19:26-07:00
New Revision: d1e8df85e6d1f9f823f2de5e0eb88d9a08d1763f

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

LOG: [clang] Fix a typo "mdoule" in comments. NFC.

Added: 


Modified: 
clang/include/clang/Serialization/ModuleFile.h
clang/test/CodeGenCXX/modules-vtable.cppm

Removed: 




diff  --git a/clang/include/clang/Serialization/ModuleFile.h 
b/clang/include/clang/Serialization/ModuleFile.h
index 45fb75df8a4352..e96f3ce06c2ceb 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -164,7 +164,7 @@ class ModuleFile {
   /// Whether this precompiled header is a relocatable PCH file.
   bool RelocatablePCH = false;
 
-  /// Whether this mdoule file is a standard c++ module.
+  /// Whether this module file is a standard C++ module.
   bool StandardCXXModule = false;
 
   /// Whether timestamps are included in this module file.

diff  --git a/clang/test/CodeGenCXX/modules-vtable.cppm 
b/clang/test/CodeGenCXX/modules-vtable.cppm
index 5d13225697b4da..fb179b1de4880b 100644
--- a/clang/test/CodeGenCXX/modules-vtable.cppm
+++ b/clang/test/CodeGenCXX/modules-vtable.cppm
@@ -68,7 +68,7 @@ int use() {
 
 // Check the case that the declaration of the key function comes from another
 // module unit but the definition of the key function comes from the current
-// mdoule unit.
+// module unit.
 
 //--- M-A.cppm
 export module M:A;



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


[clang] f7e0aae - [ODRHash] Stop hashing `ObjCMethodDecl::isPropertyAccessor` as it doesn't capture inherent method quality.

2023-07-05 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-07-05T18:04:50-07:00
New Revision: f7e0aae7284b7ad0cf3cc277c5ef8731f564443d

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

LOG: [ODRHash] Stop hashing `ObjCMethodDecl::isPropertyAccessor` as it doesn't 
capture inherent method quality.

`isPropertyAccessor` depends on the surrounding code and not on the method
itself. That's why it can be different in different modules. And
mismatches shouldn't be an error.

rdar://109481753

Differential Revision: https://reviews.llvm.org/D154460

Added: 


Modified: 
clang/lib/AST/ODRHash.cpp
clang/test/Modules/compare-objc-nonisolated-methods.m

Removed: 




diff  --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 3ea023d3cee66a..507fb0b49f8ad3 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -373,7 +373,6 @@ class ODRDeclVisitor : public 
ConstDeclVisitor {
   void VisitObjCMethodDecl(const ObjCMethodDecl *Method) {
 ID.AddInteger(Method->getDeclKind());
 Hash.AddBoolean(Method->isInstanceMethod()); // false if class method
-Hash.AddBoolean(Method->isPropertyAccessor());
 Hash.AddBoolean(Method->isVariadic());
 Hash.AddBoolean(Method->isSynthesizedAccessorStub());
 Hash.AddBoolean(Method->isDefined());

diff  --git a/clang/test/Modules/compare-objc-nonisolated-methods.m 
b/clang/test/Modules/compare-objc-nonisolated-methods.m
index a60114148420bd..41e861547af420 100644
--- a/clang/test/Modules/compare-objc-nonisolated-methods.m
+++ b/clang/test/Modules/compare-objc-nonisolated-methods.m
@@ -5,12 +5,17 @@
 // is not an error because it depends on the surrounding code and not on the 
method itself.
 // RUN: %clang_cc1 -fsyntax-only -verify -I%t/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=%t/modules.cache 
-fmodule-name=Override %t/test-overriding.m
 
+// Test that 
diff erent values of `ObjCMethodDecl::isPropertyAccessor` in 
diff erent modules
+// is not an error because it depends on the surrounding code and not on the 
method itself.
+// RUN: %clang_cc1 -fsyntax-only -verify -I%t/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=%t/modules.cache 
-fmodule-name=PropertyAccessor %t/test-property_accessor.m
+
 //--- include/Common.h
 @interface NSObject
 @end
 
 //--- include/Indirection.h
 #import 
+#import 
 
 //--- include/module.modulemap
 module Common {
@@ -25,6 +30,10 @@ @interface NSObject
   header "Override.h"
   export *
 }
+module PropertyAccessor {
+  header "PropertyAccessor.h"
+  export *
+}
 
 //--- include/Override.h
 #import 
@@ -52,3 +61,31 @@ - (void)potentialOverride;
 void triggerOverrideCheck(SubClass *sc) {
   [sc potentialOverride];
 }
+
+//--- include/PropertyAccessor.h
+#import 
+@interface PropertySubClass: NSObject
+- (int)potentialProperty;
+- (void)setPotentialProperty:(int)p;
+@end
+
+//--- PropertyAccessor_Internal.h
+#import 
+@interface PropertySubClass()
+@property int potentialProperty;
+@end
+
+//--- test-property_accessor.m
+//expected-no-diagnostics
+// Get a version of `PropertySubClass` where `-[PropertySubClass 
potentialProperty]`
+// is a property accessor.
+#import "PropertyAccessor_Internal.h"
+
+// Get a version of `PropertySubClass` where `-[PropertySubClass 
potentialProperty]`
+// is not a property accessor because module "PropertyAccessor" doesn't know 
about PropertyAccessor_Internal.h.
+#import 
+
+void triggerPropertyAccessorCheck(PropertySubClass *x) {
+  int tmp = [x potentialProperty];
+  [x setPotentialProperty: tmp];
+}



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


[clang] 18530e5 - [ODRHash] Stop hashing `ObjCMethodDecl::isOverriding` as it doesn't capture inherent method quality.

2023-07-05 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-07-05T18:04:32-07:00
New Revision: 18530e5d0770098bc33ff6f02a7b63ea887692a6

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

LOG: [ODRHash] Stop hashing `ObjCMethodDecl::isOverriding` as it doesn't 
capture inherent method quality.

`isOverriding` depends on the surrounding code and not on the method
itself. That's why it can be different in different modules. And
mismatches shouldn't be an error.

rdar://109481753

Differential Revision: https://reviews.llvm.org/D154459

Added: 
clang/test/Modules/compare-objc-nonisolated-methods.m

Modified: 
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp

Removed: 




diff  --git a/clang/lib/AST/ODRDiagsEmitter.cpp 
b/clang/lib/AST/ODRDiagsEmitter.cpp
index d1c59bd1f2ca23..1994f0865428bd 100644
--- a/clang/lib/AST/ODRDiagsEmitter.cpp
+++ b/clang/lib/AST/ODRDiagsEmitter.cpp
@@ -2096,7 +2096,8 @@ bool ODRDiagsEmitter::diagnoseMismatch(
   << FirstDecl->getSourceRange();
   Diag(SecondDecl->getLocation(),
diag::note_module_odr_violation_mismatch_decl_unknown)
-  << SecondModule << FirstDiffType << SecondDecl->getSourceRange();
+  << SecondModule.empty() << SecondModule << FirstDiffType
+  << SecondDecl->getSourceRange();
   return true;
 }
 

diff  --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 0ead0940479d85..3ea023d3cee66a 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -377,7 +377,6 @@ class ODRDeclVisitor : public 
ConstDeclVisitor {
 Hash.AddBoolean(Method->isVariadic());
 Hash.AddBoolean(Method->isSynthesizedAccessorStub());
 Hash.AddBoolean(Method->isDefined());
-Hash.AddBoolean(Method->isOverriding());
 Hash.AddBoolean(Method->isDirectMethod());
 Hash.AddBoolean(Method->isThisDeclarationADesignatedInitializer());
 Hash.AddBoolean(Method->hasSkippedBody());

diff  --git a/clang/test/Modules/compare-objc-nonisolated-methods.m 
b/clang/test/Modules/compare-objc-nonisolated-methods.m
new file mode 100644
index 00..a60114148420bd
--- /dev/null
+++ b/clang/test/Modules/compare-objc-nonisolated-methods.m
@@ -0,0 +1,54 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// Test that 
diff erent values of `ObjCMethodDecl::isOverriding` in 
diff erent modules
+// is not an error because it depends on the surrounding code and not on the 
method itself.
+// RUN: %clang_cc1 -fsyntax-only -verify -I%t/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=%t/modules.cache 
-fmodule-name=Override %t/test-overriding.m
+
+//--- include/Common.h
+@interface NSObject
+@end
+
+//--- include/Indirection.h
+#import 
+
+//--- include/module.modulemap
+module Common {
+  header "Common.h"
+  export *
+}
+module Indirection {
+  header "Indirection.h"
+  export *
+}
+module Override {
+  header "Override.h"
+  export *
+}
+
+//--- include/Override.h
+#import 
+@interface SubClass: NSObject
+- (void)potentialOverride;
+@end
+
+//--- Override_Internal.h
+#import 
+@interface NSObject(InternalCategory)
+- (void)potentialOverride;
+@end
+
+//--- test-overriding.m
+//expected-no-diagnostics
+// Get non-modular version of `SubClass`, so that `-[SubClass 
potentialOverride]`
+// is an override of a method in `InternalCategory`.
+#import "Override_Internal.h"
+#import 
+
+// Get modular version of `SubClass` where `-[SubClass potentialOverride]` is
+// not an override because module "Override" doesn't know about 
Override_Internal.h.
+#import 
+
+void triggerOverrideCheck(SubClass *sc) {
+  [sc potentialOverride];
+}



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


[clang] 2e16df3 - [ASTStructuralEquivalence] Fix crash when ObjCCategoryDecl doesn't have corresponding ObjCInterfaceDecl.

2023-06-09 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-06-09T17:09:28-07:00
New Revision: 2e16df352c7acb910313c80ac90b650ad9c14a3d

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

LOG: [ASTStructuralEquivalence] Fix crash when ObjCCategoryDecl doesn't have 
corresponding ObjCInterfaceDecl.

When this happens, it is invalid code and there is diagnostic
```
error: cannot find interface declaration for '...'
```

But clang shouldn't crash even if code is invalid. Though subsequent
diagnostic can be imperfect because without ObjCInterfaceDecl we don't have
a type for error messages.

rdar://108818430

Differential Revision: https://reviews.llvm.org/D151523

Added: 


Modified: 
clang/lib/AST/ASTStructuralEquivalence.cpp
clang/unittests/AST/StructuralEquivalenceTest.cpp

Removed: 




diff  --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index a9470782c634e..f867b6bf84beb 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -2057,8 +2057,13 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   if (!IsStructurallyEquivalent(D1->getIdentifier(), D2->getIdentifier()))
 return false;
 
-  if (!IsStructurallyEquivalent(D1->getClassInterface()->getIdentifier(),
-D2->getClassInterface()->getIdentifier()))
+  const ObjCInterfaceDecl *Intf1 = D1->getClassInterface(),
+  *Intf2 = D2->getClassInterface();
+  if ((!Intf1 || !Intf2) && (Intf1 != Intf2))
+return false;
+
+  if (Intf1 &&
+  !IsStructurallyEquivalent(Intf1->getIdentifier(), 
Intf2->getIdentifier()))
 return false;
 
   // Compare protocols.
@@ -2077,7 +2082,8 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
 return false;
 
   // Compare ivars.
-  QualType D2Type = 
Context.ToCtx.getObjCInterfaceType(D2->getClassInterface());
+  QualType D2Type =
+  Intf2 ? Context.ToCtx.getObjCInterfaceType(Intf2) : QualType();
   ObjCCategoryDecl::ivar_iterator Ivar2 = D2->ivar_begin(),
   Ivar2End = D2->ivar_end();
   for (ObjCCategoryDecl::ivar_iterator Ivar1 = D1->ivar_begin(),

diff  --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp 
b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 8efb9a905c2f1..319eefe1e6ba3 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1143,6 +1143,18 @@ TEST_F(StructuralEquivalenceObjCCategoryTest, 
CategoriesWithDifferentNames) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceObjCCategoryTest, CategoriesWithoutInterfaces) {
+  auto t = makeDecls("  @interface A(X) 
@end",
+   "@interface A @end @interface A(X) 
@end",
+   Lang_OBJC, objcCategoryDecl());
+  EXPECT_FALSE(testStructuralMatch(t));
+
+  auto t2 = makeDecls("@interface A(X) @end",
+"@interface A(X) @end",
+Lang_OBJC, objcCategoryDecl());
+  EXPECT_TRUE(testStructuralMatch(t2));
+}
+
 TEST_F(StructuralEquivalenceObjCCategoryTest, CategoryAndExtension) {
   auto t = makeDecls("@interface A @end @interface A(X) 
@end",
"@interface A @end @interface A() @end",



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


[clang] 24f36a2 - [Modules] Move modulemaps to header search directories. NFC intended.

2023-05-03 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-05-03T13:07:47-07:00
New Revision: 24f36a215b4eabd1d0e4abcce0c9277085d88a96

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

LOG: [Modules] Move modulemaps to header search directories. NFC intended.

In code we use `#include "llvm/Lib/Header.h"` which is located in
"llvm/include/llvm/Lib/Header.h", so we use "llvm/include/" as a header
search path. We should put modulemaps in the same directory and
shouldn't rely on clang to search in immediate subdirectories.

rdar://106677321

Differential Revision: https://reviews.llvm.org/D148776

Added: 
clang/include/module.modulemap
lldb/include/module.modulemap
llvm/include/CMakeLists.txt
llvm/include/module.extern.modulemap
llvm/include/module.install.modulemap
llvm/include/module.modulemap
llvm/include/module.modulemap.build

Modified: 
llvm/CMakeLists.txt
llvm/include/llvm/CMakeLists.txt

Removed: 
clang/include/clang-c/module.modulemap
clang/include/clang/module.modulemap
lldb/include/lldb/module.modulemap
llvm/include/llvm-c/module.modulemap
llvm/include/llvm/module.extern.modulemap
llvm/include/llvm/module.install.modulemap
llvm/include/llvm/module.modulemap
llvm/include/llvm/module.modulemap.build



diff  --git a/clang/include/clang-c/module.modulemap 
b/clang/include/clang-c/module.modulemap
deleted file mode 100644
index 95a59d62344cc..0
--- a/clang/include/clang-c/module.modulemap
+++ /dev/null
@@ -1,4 +0,0 @@
-module Clang_C {
-  umbrella "."
-  module * { export * }
-}

diff  --git a/clang/include/clang/module.modulemap 
b/clang/include/clang/module.modulemap
deleted file mode 100644
index 624045dc4c57b..0
--- a/clang/include/clang/module.modulemap
+++ /dev/null
@@ -1,199 +0,0 @@
-module Clang_Analysis {
-  requires cplusplus
-  umbrella "Analysis"
-
-  textual header "Analysis/Analyses/ThreadSafetyOps.def"
-
-  module * { export * }
-
-  // FIXME: Exclude these headers to avoid pulling all of the AST matchers
-  // library into clang. Due to inline key functions in the headers,
-  // importing the AST matchers library gives a link dependency on the AST
-  // matchers (and thus the AST), which clang-format should not have.
-  exclude header "Analysis/Analyses/ExprMutationAnalyzer.h"
-}
-
-module Clang_AST {
-  requires cplusplus
-  umbrella "AST"
-
-  textual header "AST/BuiltinTypes.def"
-  textual header "AST/CXXRecordDeclDefinitionBits.def"
-  textual header "AST/OperationKinds.def"
-  textual header "AST/TypeLocNodes.def"
-
-  module * { export * }
-}
-
-module Clang_ASTMatchers { requires cplusplus umbrella "ASTMatchers" module * 
{ export * } }
-
-module Clang_Basic {
-  requires cplusplus
-  umbrella "Basic"
-
-  textual header "Basic/AArch64SVEACLETypes.def"
-  textual header "Basic/BuiltinsAArch64.def"
-  textual header "Basic/BuiltinsAMDGPU.def"
-  textual header "Basic/BuiltinsAArch64NeonSVEBridge.def"
-  textual header "Basic/BuiltinsAArch64NeonSVEBridge_cg.def"
-  textual header "Basic/BuiltinsARM.def"
-  textual header "Basic/BuiltinsBPF.def"
-  textual header "Basic/Builtins.def"
-  textual header "Basic/BuiltinHeaders.def"
-  textual header "Basic/BuiltinsHexagon.def"
-  textual header "Basic/BuiltinsHexagonDep.def"
-  textual header "Basic/BuiltinsHexagonMapCustomDep.def"
-  textual header "Basic/BuiltinsLoongArch.def"
-  textual header "Basic/BuiltinsMips.def"
-  textual header "Basic/BuiltinsNEON.def"
-  textual header "Basic/BuiltinsNVPTX.def"
-  textual header "Basic/BuiltinsPPC.def"
-  textual header "Basic/BuiltinsRISCV.def"
-  textual header "Basic/BuiltinsRISCVVector.def"
-  textual header "Basic/BuiltinsSVE.def"
-  textual header "Basic/BuiltinsSystemZ.def"
-  textual header "Basic/BuiltinsVE.def"
-  textual header "Basic/BuiltinsVEVL.gen.def"
-  textual header "Basic/BuiltinsWebAssembly.def"
-  textual header "Basic/BuiltinsX86.def"
-  textual header "Basic/BuiltinsX86_64.def"
-  textual header "Basic/BuiltinsXCore.def"
-  textual header "Basic/CodeGenOptions.def"
-  textual header "Basic/DiagnosticOptions.def"
-  textual header "Basic/Features.def"
-  textual header "Basic/FPOptions.def"
-  textual header "Basic/MSP430Target.def"
-  textual header "Basic/LangOptions.def"
-  textual header "Basic/OpenCLExtensions.def"
-  textual header "Basic/OpenCLImageTypes.def"
-  textual header "Basic/OpenCLExtensionTypes.def"
-  textual header "Basic/OpenMPKinds.def"
-  textual header "Basic/OperatorKinds.def"
-  textual header "Basic/PPCTypes.def"
-  textual header "Basic/RISCVVTypes.def"
-  textual header "Basic/Sanitizers.def"
-  textual header "Basic/TargetCXXABI.def"
-  textual header "Basic/TransformTypeTraits.def"
-  textual header "Basic/TokenKinds.def"
-  textual header 

[clang] e46aa7f - Fix a typo in head comment of `CurPPLexer`.

2023-05-02 Thread Volodymyr Sapsai via cfe-commits

Author: Zhouyi Zhou
Date: 2023-05-02T19:49:21-07:00
New Revision: e46aa7f927293989dae40817c0087cba9cf5fae7

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

LOG: Fix a typo in head comment of `CurPPLexer`.

In head comment of CurPPLexer field of class Preprocessor,
'The current top of the stack what we're lexing from' should be
'The current top of the stack that we're lexing from'.

Differential Revision: https://reviews.llvm.org/D149709

Added: 


Modified: 
clang/include/clang/Lex/Preprocessor.h

Removed: 




diff  --git a/clang/include/clang/Lex/Preprocessor.h 
b/clang/include/clang/Lex/Preprocessor.h
index a34a451f4bad1..8bdaf25e9b870 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -729,7 +729,7 @@ class Preprocessor {
   /// Only one of CurLexer, or CurTokenLexer will be non-null.
   std::unique_ptr CurLexer;
 
-  /// The current top of the stack what we're lexing from
+  /// The current top of the stack that we're lexing from
   /// if not expanding a macro.
   ///
   /// This is an alias for CurLexer.



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


[clang] a845aeb - [Driver] Allow to collect `-save-stats` data to a file specified in the environment variable.

2023-03-16 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-03-16T11:57:59-07:00
New Revision: a845aeb5d6c869146fa24194a7d0182a4787cad8

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

LOG: [Driver] Allow to collect `-save-stats` data to a file specified in the 
environment variable.

Using two environment variables `CC_PRINT_INTERNAL_STAT` and
`CC_PRINT_INTERNAL_STAT_FILE` to work like `CC_PRINT_PROC_STAT`.

The purpose of the change is to allow collecting the internal stats
without modifying the build scripts. Write all stats to a single file
to simplify aggregating the data.

Differential Revision: https://reviews.llvm.org/D144981

Added: 


Modified: 
clang/docs/CommandGuide/clang.rst
clang/include/clang/Driver/Driver.h
clang/include/clang/Driver/Options.td
clang/include/clang/Frontend/FrontendOptions.h
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Frontend/CompilerInstance.cpp
clang/test/Driver/save-stats.c
clang/tools/driver/driver.cpp

Removed: 




diff  --git a/clang/docs/CommandGuide/clang.rst 
b/clang/docs/CommandGuide/clang.rst
index e076818697eb1..0722979885afb 100644
--- a/clang/docs/CommandGuide/clang.rst
+++ b/clang/docs/CommandGuide/clang.rst
@@ -598,6 +598,16 @@ Driver Options
   directory (:option:`-save-stats`/"-save-stats=cwd") or the directory
   of the output file ("-save-state=obj").
 
+  You can also use environment variables to control the statistics reporting.
+  Setting ``CC_PRINT_INTERNAL_STAT`` to ``1`` enables the feature, the report
+  goes to stdout in JSON format.
+
+  Setting ``CC_PRINT_INTERNAL_STAT_FILE`` to a file path makes it report
+  statistics to the given file in the JSON format.
+
+  Note that ``-save-stats`` take precedence over ``CC_PRINT_INTERNAL_STAT``
+  and ``CC_PRINT_INTERNAL_STAT_FILE``.
+
 .. option:: -integrated-as, -no-integrated-as
 
   Used to enable and disable, respectively, the use of the integrated

diff  --git a/clang/include/clang/Driver/Driver.h 
b/clang/include/clang/Driver/Driver.h
index c85658d7c56e3..e3e98bad99127 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -194,6 +194,9 @@ class Driver {
   /// The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
   std::string CCPrintStatReportFilename;
 
+  /// The file to log CC_PRINT_INTERNAL_STAT_FILE output to, if enabled.
+  std::string CCPrintInternalStatReportFilename;
+
   /// The file to log CC_PRINT_OPTIONS output to, if enabled.
   std::string CCPrintOptionsFilename;
 
@@ -258,6 +261,10 @@ class Driver {
   /// performance report to CC_PRINT_PROC_STAT_FILE or to stdout.
   unsigned CCPrintProcessStats : 1;
 
+  /// Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal
+  /// performance report to CC_PRINT_INTERNAL_STAT_FILE or to stdout.
+  unsigned CCPrintInternalStats : 1;
+
   /// Pointer to the ExecuteCC1Tool function, if available.
   /// When the clangDriver lib is used through clang.exe, this provides a
   /// shortcut for executing the -cc1 command-line directly, in the same

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index a2dbef1cc7cfe..a05e61ac0e92f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6147,6 +6147,9 @@ def print_stats : Flag<["-"], "print-stats">,
 def stats_file : Joined<["-"], "stats-file=">,
   HelpText<"Filename to write statistics to">,
   MarshallingInfoString>;
+def stats_file_append : Flag<["-"], "stats-file-append">,
+  HelpText<"If stats should be appended to stats-file instead of overwriting 
it">,
+  MarshallingInfoFlag>;
 def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">,
   HelpText<"Dump record layout information in a simple form used for testing">,
   MarshallingInfoFlag>;

diff  --git a/clang/include/clang/Frontend/FrontendOptions.h 
b/clang/include/clang/Frontend/FrontendOptions.h
index ef04f3b236d87..85183a3812b42 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -278,6 +278,8 @@ class FrontendOptions {
   /// Show frontend performance metrics and statistics.
   unsigned ShowStats : 1;
 
+  unsigned AppendStats : 1;
+
   /// print the supported cpus for the current target
   unsigned PrintSupportedCPUs : 1;
 
@@ -511,16 +513,16 @@ class FrontendOptions {
 public:
   FrontendOptions()
   : DisableFree(false), RelocatablePCH(false), ShowHelp(false),
-ShowStats(false), TimeTrace(false), ShowVersion(false),
-FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
-FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
-

[clang] 2893d55 - [Serialization] Don't warn when a deserialized category is equivalent to an existing one.

2023-02-22 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-02-22T11:01:40-08:00
New Revision: 2893d55f8f61edb2c253b960cab1107ea6c163c2

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

LOG: [Serialization] Don't warn when a deserialized category is equivalent to 
an existing one.

A single class allows multiple categories to be defined for it. But if
two of such categories have the same name, we emit a warning. It's not a
hard error but a good indication of a potential mistake.

With modules, we can end up with the same category in different modules.
Diagnosing such a situation has little value as the categories in
different modules are equivalent and don't reflect the usage of the same
name for different purposes. When we deserialize a duplicate category,
compare it to an existing one and warn only when the new one is
different.

rdar://104582081

Differential Revision: https://reviews.llvm.org/D144149

Added: 


Modified: 
clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/Modules/compare-objc-interface.m
clang/test/Modules/hidden-duplicates.m
clang/test/Modules/objc-categories.m

Removed: 




diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 8cb513eff13e0..b9bbc0ec9eb28 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -14,6 +14,7 @@
 #include "ASTCommon.h"
 #include "ASTReaderInternals.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTStructuralEquivalence.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/AttrIterator.h"
 #include "clang/AST/Decl.h"
@@ -4181,23 +4182,22 @@ namespace {
   // Check for duplicate categories.
   if (Cat->getDeclName()) {
 ObjCCategoryDecl * = NameCategoryMap[Cat->getDeclName()];
-if (Existing &&
-Reader.getOwningModuleFile(Existing)
-  != Reader.getOwningModuleFile(Cat)) {
-  // FIXME: We should not warn for duplicates in diamond:
-  //
-  //   MT //
-  //  /  \//
-  // ML  MR   //
-  //  \  ///
-  //   MB //
-  //
-  // If there are duplicates in ML/MR, there will be warning when
-  // creating MB *and* when importing MB. We should not warn when
-  // importing.
-  Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
-<< Interface->getDeclName() << Cat->getDeclName();
-  Reader.Diag(Existing->getLocation(), diag::note_previous_definition);
+if (Existing && Reader.getOwningModuleFile(Existing) !=
+Reader.getOwningModuleFile(Cat)) {
+  llvm::DenseSet> NonEquivalentDecls;
+  StructuralEquivalenceContext Ctx(
+  Cat->getASTContext(), Existing->getASTContext(),
+  NonEquivalentDecls, StructuralEquivalenceKind::Default,
+  /*StrictTypeSpelling =*/false,
+  /*Complain =*/false,
+  /*ErrorOnTagTypeMismatch =*/true);
+  if (!Ctx.IsEquivalent(Cat, Existing)) {
+// Warn only if the categories with the same name are 
diff erent.
+Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
+<< Interface->getDeclName() << Cat->getDeclName();
+Reader.Diag(Existing->getLocation(),
+diag::note_previous_definition);
+  }
 } else if (!Existing) {
   // Record this category.
   Existing = Cat;

diff  --git a/clang/test/Modules/compare-objc-interface.m 
b/clang/test/Modules/compare-objc-interface.m
index 17a03de3ce29b..cc3b5fe60b1f5 100644
--- a/clang/test/Modules/compare-objc-interface.m
+++ b/clang/test/Modules/compare-objc-interface.m
@@ -444,3 +444,54 @@ @interface CompareLastImplAttribute: NSObject
 // expected-error@first.h:* {{'CompareLastImplAttribute' has 
diff erent definitions in 
diff erent modules; first 
diff erence is definition in module 'First.Hidden' found property 
'lastImplAttribute' with 'direct' attribute}}
 // expected-note-re@second.h:* {{but in {{'Second'|definition here}} found 
property 'lastImplAttribute' with 
diff erent 'direct' attribute}}
 #endif
+
+#if defined(FIRST)
+@interface CompareMatchingCategories: NSObject @end
+@interface CompareMatchingCategories(Matching)
+- (int)testMethod;
+@end
+
+@interface CompareMismatchingCategories1: NSObject @end
+@interface CompareMismatchingCategories1(Category1)
+- (void)presentMethod;
+@end
+@interface CompareMismatchingCategories2: NSObject @end
+@interface CompareMismatchingCategories2(Category2)
+@end
+
+@interface CompareDifferentCategoryNames: NSObject @end
+@interface CompareDifferentCategoryNames(CategoryFirst)
+- 

[clang] ed7a46a - [modules] Allow parsing a duplicate Obj-C interface if a previous one comes from a hidden [sub]module.

2023-01-20 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-01-20T10:18:18-06:00
New Revision: ed7a46a8de77087447936965044e2faf734102e5

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

LOG: [modules] Allow parsing a duplicate Obj-C interface if a previous one 
comes from a hidden [sub]module.

Instead of emitting a redefinition error, check that definitions are
equivalent and allow such scenario.

A few non-obvious implementation details:
* to avoid multiple definitions in the redeclaration chain we just drop
  the new definition after checking for equivalence;
* for checking definition equivalence use ODR hash instead of
  ASTStructuralEquivalence because it avoids excessive recursive
  deserialization. Though after detecting a mismatch we do deserialize
  multiple entities to provide a better error message.

rdar://82908223

Differential Revision: https://reviews.llvm.org/D124286

Added: 


Modified: 
clang/include/clang/AST/DeclObjC.h
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/AST/DeclObjC.cpp
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/Parse/ParseObjc.cpp
clang/lib/Sema/SemaDeclObjC.cpp
clang/test/Modules/compare-objc-interface.m
clang/test/Modules/hidden-duplicates.m

Removed: 




diff  --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 77fde99b6b60b..3d650b82f2b9b 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1542,6 +1542,13 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
   /// a forward declaration (\@class) to a definition (\@interface).
   void startDefinition();
 
+  /// Starts the definition without sharing it with other redeclarations.
+  /// Such definition shouldn't be used for anything but only to compare if
+  /// a duplicate is compatible with previous definition or if it is
+  /// a distinct duplicate.
+  void startDuplicateDefinitionForComparison();
+  void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition);
+
   /// Retrieve the superclass type.
   const ObjCObjectType *getSuperClassType() const {
 if (TypeSourceInfo *TInfo = getSuperClassTInfo())

diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index fdbd85cb10e5b..1f7faaa06e540 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -58,6 +58,15 @@ class ODRDiagsEmitter {
   const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
   const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const;
 
+  /// Diagnose ODR mismatch between ObjCInterfaceDecl with 
diff erent
+  /// definitions.
+  bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID,
+const ObjCInterfaceDecl *SecondID) const {
+assert(FirstID->data().Definition != SecondID->data().Definition &&
+   "Don't diagnose 
diff erences when definitions are merged already");
+return diagnoseMismatch(FirstID, SecondID, >data());
+  }
+
   /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
   ///
   /// Returns true if found a mismatch and diagnosed it.

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 715249b9d6f5e..28120d13fd9e7 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -624,12 +624,12 @@ def err_module_odr_violation_objc_interface : Error <
 "%select{|@private|@protected|@public|@package}5"
   "}3">;
 def note_module_odr_violation_objc_interface : Note <
-  "but in '%0' found "
+  "but in %select{'%1'|definition here}0 found "
   "%select{"
-  "%select{no super class|super class with type %3}2|"
-  "instance variable '%2' access control is "
-"%select{|@private|@protected|@public|@package}3"
-  "}1">;
+  "%select{no super class|super class with type %4}3|"
+  "instance variable '%3' access control is "
+"%select{|@private|@protected|@public|@package}4"
+  "}2">;
 
 def err_module_odr_violation_template_parameter : Error <
   "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
@@ -778,16 +778,17 @@ def err_module_odr_violation_field : Error<
   "field %4 with %select{no|an}5 initalizer|"
   "field %4 with an initializer"
   "}3">;
-def note_module_odr_violation_field : Note<"but in '%0' found "
+def note_module_odr_violation_field : Note<
+  "but in %select{'%1'|definition here}0 found "
   "%select{"
-  "field %2|"
-  "field %2 with type %3|"
-  "%select{non-|}3bitfield %2|"
-  "bitfield %2 with 
diff erent width expression|"
-  "%select{non-|}3mutable field %2|"
-  "field %2 with 

[clang] 6ba4afb - [ODRHash] Hash `ObjCInterfaceDecl` and diagnose discovered mismatches.

2023-01-20 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-01-20T10:18:18-06:00
New Revision: 6ba4afb4d6f2f8f293ad704a37de4139c5c8c0f0

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

LOG: [ODRHash] Hash `ObjCInterfaceDecl` and diagnose discovered mismatches.

When two modules contain interfaces with the same name, check the
definitions are equivalent and diagnose if they are not.

Differential Revision: https://reviews.llvm.org/D140073

Added: 
clang/test/Modules/compare-objc-interface.m

Modified: 
clang/include/clang/AST/DeclObjC.h
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/AST/ODRHash.h
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/DeclObjC.cpp
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ASTWriterDecl.cpp
clang/test/Modules/interface-diagnose-missing-import.m
clang/test/Modules/method_pool.m

Removed: 




diff  --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 7c72ec9507bf1..77fde99b6b60b 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1146,6 +1146,7 @@ class ObjCContainerDecl : public NamedDecl, public 
DeclContext {
 class ObjCInterfaceDecl : public ObjCContainerDecl
 , public Redeclarable {
   friend class ASTContext;
+  friend class ODRDiagsEmitter;
 
   /// TypeForDecl - This indicates the Type object that represents this
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -1203,6 +1204,12 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
 /// One of the \c InheritedDesignatedInitializersState enumeratos.
 mutable unsigned InheritedDesignatedInitializers : 2;
 
+/// Tracks whether a ODR hash has been computed for this interface.
+unsigned HasODRHash : 1;
+
+/// A hash of parts of the class to help in ODR checking.
+unsigned ODRHash = 0;
+
 /// The location of the last location in this declaration, before
 /// the properties/methods. For example, this will be the '>', '}', or
 /// identifier,
@@ -1211,7 +1218,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
 DefinitionData()
 : ExternallyCompleted(false), IvarListMissingImplementation(true),
   HasDesignatedInitializers(false),
-  InheritedDesignatedInitializers(IDI_Unknown) {}
+  InheritedDesignatedInitializers(IDI_Unknown), HasODRHash(false) {}
   };
 
   /// The type parameters associated with this class, if any.
@@ -1892,10 +1899,17 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
   const Type *getTypeForDecl() const { return TypeForDecl; }
   void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
 
+  /// Get precomputed ODRHash or add a new one.
+  unsigned getODRHash();
+
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ObjCInterface; }
 
 private:
+  /// True if a valid hash is stored in ODRHash.
+  bool hasODRHash() const;
+  void setHasODRHash(bool HasHash);
+
   const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
   bool inheritsDesignatedInitializers() const;
 };

diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index 00a681b78a5eb..fdbd85cb10e5b 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -51,6 +51,13 @@ class ODRDiagsEmitter {
   bool diagnoseMismatch(const RecordDecl *FirstRecord,
 const RecordDecl *SecondRecord) const;
 
+  /// Diagnose ODR mismatch between 2 ObjCInterfaceDecl.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool diagnoseMismatch(
+  const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
+  const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const;
+
   /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
   ///
   /// Returns true if found a mismatch and diagnosed it.
@@ -97,6 +104,7 @@ class ODRDiagsEmitter {
 Friend,
 FunctionTemplate,
 ObjCMethod,
+ObjCIvar,
 ObjCProperty,
 Other
   };

diff  --git a/clang/include/clang/AST/ODRHash.h 
b/clang/include/clang/AST/ODRHash.h
index a489bb73deb67..cedf644520fc3 100644
--- a/clang/include/clang/AST/ODRHash.h
+++ b/clang/include/clang/AST/ODRHash.h
@@ -59,6 +59,10 @@ class ODRHash {
   // method compares more information than the AddDecl class.
   void AddRecordDecl(const RecordDecl *Record);
 
+  // Use this for ODR checking ObjC interfaces. 

[clang] f33b5b1 - [ODRHash] Detect mismatches in anonymous `RecordDecl`.

2023-01-19 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-01-19T15:58:31-06:00
New Revision: f33b5b1bf703ee5ff73126fefe2a9bcbd54db457

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

LOG: [ODRHash] Detect mismatches in anonymous `RecordDecl`.

Allow completing a redeclaration check for anonymous structs/unions
inside `RecordDecl`, so we deserialize and compare anonymous entities
from different modules.

Completing the redeclaration chain for `RecordDecl` in
`ASTContext::getASTRecordLayout` mimics the behavior in
`CXXRecordDecl::dataPtr`. Instead of completing the redeclaration chain
every time we request a definition, do that right before we need a
complete definition in `ASTContext::getASTRecordLayout`.

Such code is required only for anonymous `RecordDecl` because we
deserialize named decls when we look them up by name. But it doesn't
work for anonymous decls as they don't have a name. That's why need to
force deserialization of anonymous decls in a different way.

rdar://81864186

Differential Revision: https://reviews.llvm.org/D140055

Added: 


Modified: 
clang/lib/AST/RecordLayoutBuilder.cpp
clang/lib/Serialization/ASTReader.cpp
clang/test/Modules/compare-record.c

Removed: 




diff  --git a/clang/lib/AST/RecordLayoutBuilder.cpp 
b/clang/lib/AST/RecordLayoutBuilder.cpp
index 52bd3f20221f4..da27f73ea94e2 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -3280,6 +3280,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const 
{
 
   if (D->hasExternalLexicalStorage() && !D->getDefinition())
 getExternalSource()->CompleteType(const_cast(D));
+  // Complete the redecl chain (if necessary).
+  (void)D->getMostRecentDecl();
 
   D = D->getDefinition();
   assert(D && "Cannot get layout of forward declarations!");

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 77f29f6be4063..88d548a45b37d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7301,7 +7301,7 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {
   //
   // FIXME: Merging a function definition should merge
   // all mergeable entities within it.
-  if (isa(DC)) {
+  if (isa(DC)) {
 if (DeclarationName Name = cast(D)->getDeclName()) {
   if (!getContext().getLangOpts().CPlusPlus &&
   isa(DC)) {

diff  --git a/clang/test/Modules/compare-record.c 
b/clang/test/Modules/compare-record.c
index 23dbe8191a343..a07843341296d 100644
--- a/clang/test/Modules/compare-record.c
+++ b/clang/test/Modules/compare-record.c
@@ -31,6 +31,15 @@
 // REDEFINE: %{macro_flag} = -DCASE3=1
 // RUN: %{command}
 
+// Run tests for anonymous nested structs and unions
+// REDEFINE: %{filename} = test-anonymous.c
+// REDEFINE: %{macro_flag} = -DCASE1=1
+// RUN: %{command}
+// REDEFINE: %{macro_flag} = -DCASE2=1
+// RUN: %{command}
+// REDEFINE: %{macro_flag} = -DCASE3=1
+// RUN: %{command}
+
 // Test that we don't accept 
diff erent structs and unions with the same name
 // from multiple modules but detect mismatches and provide actionable
 // diagnostic.
@@ -44,12 +53,14 @@ module First {
   module Hidden {
 header "first.h"
 header "first-nested-struct.h"
+header "first-anonymous.h"
 export *
   }
 }
 module Second {
   header "second.h"
   header "second-nested-struct.h"
+  header "second-anonymous.h"
   export *
 }
 
@@ -416,3 +427,71 @@ struct CompareIndirectStructPointer 
compareIndirectStructPointer;
 // expected-error@second-nested-struct.h:* 
{{'IndirectStruct::mismatchingField' from module 'Second' is not present in 
definition of 'struct IndirectStruct' in module 'First.Hidden'}}
 // expected-note@first-nested-struct.h:* {{declaration of 'mismatchingField' 
does not match}}
 #endif
+
+//--- include/first-anonymous.h
+struct CompareAnonymousNestedUnion {
+  union {
+int anonymousNestedUnionField;
+  };
+};
+
+struct CompareAnonymousNestedStruct {
+  struct {
+int anonymousNestedStructField;
+  };
+};
+
+struct CompareDeeplyNestedAnonymousUnionsAndStructs {
+  union {
+int x;
+union {
+  int y;
+  struct {
+int z;
+  };
+};
+  };
+};
+
+//--- include/second-anonymous.h
+struct CompareAnonymousNestedUnion {
+  union {
+float anonymousNestedUnionField;
+  };
+};
+
+struct CompareAnonymousNestedStruct {
+  struct {
+float anonymousNestedStructField;
+  };
+};
+
+struct CompareDeeplyNestedAnonymousUnionsAndStructs {
+  union {
+int x;
+union {
+  int y;
+  struct {
+float z;
+  };
+};
+  };
+};
+
+//--- test-anonymous.c
+#include "first-empty.h"
+#include "second-anonymous.h"
+
+#if defined(CASE1)
+struct CompareAnonymousNestedUnion compareAnonymousNestedUnion;
+// 

[clang] 160bc16 - [ODRHash] Hash `RecordDecl` and diagnose discovered mismatches.

2023-01-19 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-01-19T15:57:48-06:00
New Revision: 160bc160b9b114069a8cb9b4cc887aa86e5ca7c4

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

LOG: [ODRHash] Hash `RecordDecl` and diagnose discovered mismatches.

When two modules contain struct/union with the same name, check the
definitions are equivalent and diagnose if they are not. This is similar
to `CXXRecordDecl` where we already discover and diagnose mismatches.

rdar://problem/56764293

Differential Revision: https://reviews.llvm.org/D71734

Added: 
clang/test/Modules/compare-record.c

Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/AST/Decl.h
clang/include/clang/AST/DeclBase.h
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/AST/ODRHash.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/Decl.cpp
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriterDecl.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 541f8e1eb671d..9f9fdc5a97a79 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,10 @@ code bases.
   these definitions were allowed.  Note that such definitions are ODR
   violations if the header is included more than once.
 
+- Clang now diagnoses if structs/unions with the same name are 
diff erent in
+  
diff erent used modules. Behavior in C and Objective-C language modes now is
+  the same as in C++.
+
 What's New in Clang |release|?
 ==
 Some of the major new features and improvements to Clang are listed

diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7322d4bcbc7f3..863f6ac57f2aa 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3998,6 +3998,7 @@ class RecordDecl : public TagDecl {
   // to save some space. Use the provided accessors to access it.
 public:
   friend class DeclContext;
+  friend class ASTDeclReader;
   /// Enum that represents the 
diff erent ways arguments are passed to and
   /// returned from function calls. This takes into account the target-specific
   /// and version-specific rules along with the rules determined by the
@@ -4253,9 +4254,16 @@ class RecordDecl : public TagDecl {
   /// nullptr is returned if no named data member exists.
   const FieldDecl *findFirstNamedDataMember() const;
 
+  /// Get precomputed ODRHash or add a new one.
+  unsigned getODRHash();
+
 private:
   /// Deserialize just the fields.
   void LoadFieldsFromExternalStorage() const;
+
+  /// True if a valid hash is stored in ODRHash.
+  bool hasODRHash() const { return RecordDeclBits.ODRHash; }
+  void setODRHash(unsigned Hash) { RecordDeclBits.ODRHash = Hash; }
 };
 
 class FileScopeAsmDecl : public Decl {

diff  --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index 8a5f75573095b..6134fdde8a2c9 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -1577,10 +1577,14 @@ class DeclContext {
 
 /// Indicates whether this struct has had its field layout randomized.
 uint64_t IsRandomized : 1;
+
+/// True if a valid hash is stored in ODRHash. This should shave off some
+/// extra storage and prevent CXXRecordDecl to store unused bits.
+uint64_t ODRHash : 26;
   };
 
   /// Number of non-inherited bits in RecordDeclBitfields.
-  enum { NumRecordDeclBits = 15 };
+  enum { NumRecordDeclBits = 41 };
 
   /// Stores the bits used by OMPDeclareReductionDecl.
   /// If modified NumOMPDeclareReductionDeclBits and the accessor

diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index d3b7f5e6b4109..00a681b78a5eb 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -45,6 +45,12 @@ class ODRDiagsEmitter {
const CXXRecordDecl *SecondRecord,
const struct CXXRecordDecl::DefinitionData *SecondDD) const;
 
+  /// Diagnose ODR mismatch between 2 RecordDecl that are not CXXRecordDecl.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool diagnoseMismatch(const RecordDecl *FirstRecord,
+const RecordDecl *SecondRecord) const;
+
   /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
   ///
   /// Returns true if found a mismatch and diagnosed it.

diff  --git a/clang/include/clang/AST/ODRHash.h 
b/clang/include/clang/AST/ODRHash.h
index 1ab20013a3670..a489bb73deb67 100644
--- a/clang/include/clang/AST/ODRHash.h
+++ b/clang/include/clang/AST/ODRHash.h
@@ -55,6 +55,10 @@ 

[clang] 304d730 - [clang][Sema] Fix uninitialized `SourceLocation` for types with multiple attributes and macros.

2023-01-18 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-01-18T16:15:53-06:00
New Revision: 304d7307aee15b6eb88d198ae94b595f4e09f485

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

LOG: [clang][Sema] Fix uninitialized `SourceLocation` for types with multiple 
attributes and macros.

Some `TypeLoc`s are considered "sugar" and we go past them in
`GetTypeSourceInfoForDeclarator`. The problem is that we peel off only
the same kind of `TypeLoc` at the time which makes it impossible to
handle mixed sequences like
`AttributedTypeLoc - MacroQualifiedTypeLoc - AttributedTypeLoc - PointerTypeLoc`

In this situation, as shown in the added test, we don't get to
`PointerTypeLoc` and don't set its starLoc leaving it uninitialized.

Address FIXME and peel off "sugar" `TypeLoc`s regardless of their order.

rdar://102149264

Differential Revision: https://reviews.llvm.org/D141424

Added: 


Modified: 
clang/lib/Sema/SemaType.cpp
clang/unittests/AST/SourceLocationTest.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index eb61a5fe4fbae..ac00e87944845 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6515,29 +6515,42 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState 
,
   CurrTL = ATL.getValueLoc().getUnqualifiedLoc();
 }
 
-while (MacroQualifiedTypeLoc TL = CurrTL.getAs()) {
-  TL.setExpansionLoc(
-  State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
-  CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
-}
+bool HasDesugaredTypeLoc = true;
+while (HasDesugaredTypeLoc) {
+  switch (CurrTL.getTypeLocClass()) {
+  case TypeLoc::MacroQualified: {
+auto TL = CurrTL.castAs();
+TL.setExpansionLoc(
+State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
+CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+break;
+  }
 
-while (AttributedTypeLoc TL = CurrTL.getAs()) {
-  fillAttributedTypeLoc(TL, State);
-  CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
-}
+  case TypeLoc::Attributed: {
+auto TL = CurrTL.castAs();
+fillAttributedTypeLoc(TL, State);
+CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+break;
+  }
 
-while (BTFTagAttributedTypeLoc TL = 
CurrTL.getAs())
-  CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+  case TypeLoc::Adjusted:
+  case TypeLoc::BTFTagAttributed: {
+CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
+break;
+  }
 
-while (DependentAddressSpaceTypeLoc TL =
-   CurrTL.getAs()) {
-  fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());
-  CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
-}
+  case TypeLoc::DependentAddressSpace: {
+auto TL = CurrTL.castAs();
+fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());
+CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
+break;
+  }
 
-// FIXME: Ordering here?
-while (AdjustedTypeLoc TL = CurrTL.getAs())
-  CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+  default:
+HasDesugaredTypeLoc = false;
+break;
+  }
+}
 
 DeclaratorLocFiller(S.Context, State, D.getTypeObject(i)).Visit(CurrTL);
 CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();

diff  --git a/clang/unittests/AST/SourceLocationTest.cpp 
b/clang/unittests/AST/SourceLocationTest.cpp
index 43b7149bd1183..ca9e9a2161974 100644
--- a/clang/unittests/AST/SourceLocationTest.cpp
+++ b/clang/unittests/AST/SourceLocationTest.cpp
@@ -438,6 +438,47 @@ TEST(UnaryTransformTypeLoc, ParensRange) {
   loc(unaryTransformType(;
 }
 
+TEST(PointerTypeLoc, StarLoc) {
+  llvm::Annotations Example(R"c(
+int $star^*var;
+  )c");
+
+  auto AST = tooling::buildASTFromCode(Example.code());
+  SourceManager  = AST->getSourceManager();
+  auto  = AST->getASTContext();
+
+  auto *VD = selectFirst("vd", 
match(varDecl(hasName("var")).bind("vd"), Ctx));
+  ASSERT_NE(VD, nullptr);
+
+  auto TL =
+  VD->getTypeSourceInfo()->getTypeLoc().castAs();
+  ASSERT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("star"));
+}
+
+TEST(PointerTypeLoc, StarLocBehindSugar) {
+  llvm::Annotations Example(R"c(
+#define NODEREF __attribute__((noderef))
+char $1st^* NODEREF _Nonnull $2nd^* var;
+  )c");
+
+  auto AST = tooling::buildASTFromCode(Example.code());
+  SourceManager  = AST->getSourceManager();
+  auto  = AST->getASTContext();
+
+  auto *VD = selectFirst("vd", 
match(varDecl(hasName("var")).bind("vd"), Ctx));
+  ASSERT_NE(VD, nullptr);
+
+  auto TL = VD->getTypeSourceInfo()->getTypeLoc().castAs();
+  EXPECT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("2nd"));

[clang] 574a77a - [clang][sema][Matrix] Move code from try-cast to `TypeLocVisitor`. NFC intended.

2023-01-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2023-01-17T15:33:36-06:00
New Revision: 574a77ae85451adc5e2dd9e73652c62bf18eed8d

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

LOG: [clang][sema][Matrix] Move code from try-cast to `TypeLocVisitor`. NFC 
intended.

`MatrixTypeLoc` is not "sugar" `TypeLoc` and doesn't require to use the
underlying `TypeLoc` instead.

Differential Revision: https://reviews.llvm.org/D141422

Added: 


Modified: 
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 826a9ef954ee..eb61a5fe4fba 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6053,6 +6053,21 @@ static void fillAttributedTypeLoc(AttributedTypeLoc TL,
   TL.setAttr(State.takeAttrForAttributedType(TL.getTypePtr()));
 }
 
+static void fillMatrixTypeLoc(MatrixTypeLoc MTL,
+  const ParsedAttributesView ) {
+  for (const ParsedAttr  : Attrs) {
+if (AL.getKind() == ParsedAttr::AT_MatrixType) {
+  MTL.setAttrNameLoc(AL.getLoc());
+  MTL.setAttrRowOperand(AL.getArgAsExpr(0));
+  MTL.setAttrColumnOperand(AL.getArgAsExpr(1));
+  MTL.setAttrOperandParensRange(SourceRange());
+  return;
+}
+  }
+
+  llvm_unreachable("no matrix_type attribute found at the expected location!");
+}
+
 namespace {
   class TypeSpecLocFiller : public TypeLocVisitor {
 Sema 
@@ -6419,6 +6434,9 @@ namespace {
 VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
   TL.setNameLoc(Chunk.Loc);
 }
+void VisitMatrixTypeLoc(MatrixTypeLoc TL) {
+  fillMatrixTypeLoc(TL, Chunk.getAttrs());
+}
 
 void VisitTypeLoc(TypeLoc TL) {
   llvm_unreachable("unsupported TypeLoc kind in declarator!");
@@ -6466,21 +6484,6 @@ 
fillDependentAddressSpaceTypeLoc(DependentAddressSpaceTypeLoc DASTL,
   "no address_space attribute found at the expected location!");
 }
 
-static void fillMatrixTypeLoc(MatrixTypeLoc MTL,
-  const ParsedAttributesView ) {
-  for (const ParsedAttr  : Attrs) {
-if (AL.getKind() == ParsedAttr::AT_MatrixType) {
-  MTL.setAttrNameLoc(AL.getLoc());
-  MTL.setAttrRowOperand(AL.getArgAsExpr(0));
-  MTL.setAttrColumnOperand(AL.getArgAsExpr(1));
-  MTL.setAttrOperandParensRange(SourceRange());
-  return;
-}
-  }
-
-  llvm_unreachable("no matrix_type attribute found at the expected location!");
-}
-
 /// Create and instantiate a TypeSourceInfo with type source information.
 ///
 /// \param T QualType referring to the type as written in source code.
@@ -6532,9 +6535,6 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState ,
   CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
 }
 
-if (MatrixTypeLoc TL = CurrTL.getAs())
-  fillMatrixTypeLoc(TL, D.getTypeObject(i).getAttrs());
-
 // FIXME: Ordering here?
 while (AdjustedTypeLoc TL = CurrTL.getAs())
   CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();



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


[clang] 642c663 - Reland "[clang][deps] During scanning don't emit warnings-as-errors that are ignored with diagnostic pragmas."

2022-12-02 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-12-02T14:30:41-08:00
New Revision: 642c6638a3d78359552f5cf71d24a80a9bd9801f

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

LOG: Reland "[clang][deps] During scanning don't emit warnings-as-errors that 
are ignored with diagnostic pragmas."

This reverts commit 2f8ac1804827026b44f429dce02730da18a73c50.

After committing a fix for previous buildbot failures in D138970,
re-landing the original change.

Added: 
clang/test/ClangScanDeps/diagnostic-pragmas.c

Modified: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Removed: 




diff  --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 50c42087d2fa2..ff2d4b76820ed 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -135,8 +135,8 @@ static void sanitizeDiagOpts(DiagnosticOptions ) {
   DiagOpts.ShowCarets = false;
   // Don't write out diagnostic file.
   DiagOpts.DiagnosticSerializationFile.clear();
-  // Don't treat warnings as errors.
-  DiagOpts.Warnings.push_back("no-error");
+  // Don't emit warnings as errors (and all other warnings too).
+  DiagOpts.IgnoreWarnings = true;
 }
 
 /// A clang tool that runs the preprocessor in a mode that's optimized for

diff  --git a/clang/test/ClangScanDeps/diagnostic-pragmas.c 
b/clang/test/ClangScanDeps/diagnostic-pragmas.c
new file mode 100644
index 0..520f82047d2b1
--- /dev/null
+++ b/clang/test/ClangScanDeps/diagnostic-pragmas.c
@@ -0,0 +1,35 @@
+// Test scanning deps does not have more errors than the regular compilation.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+
+// Check the regular compilation does not fail.
+// RUN: %clang -fsyntax-only %t/test.c -I %t/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=%t/cache 
-Wnon-modular-include-in-module -Werror=non-modular-include-in-module
+
+// And now scanning deps should succeed too.
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1
+
+//--- cdb.json.template
+[
+  {
+"directory": "DIR",
+"command": "clang -fsyntax-only DIR/test.c -I DIR/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=DIR/cache 
-Wnon-modular-include-in-module -Werror=non-modular-include-in-module",
+"file": "DIR/test.c"
+  },
+]
+
+//--- include/nonmodular.h
+// empty
+
+//--- include/modular-includer.h
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-modular-include-in-module"
+#include 
+#pragma clang diagnostic pop
+
+//--- include/module.modulemap
+module ModularIncluder { header "modular-includer.h" }
+
+//--- test.c
+#include 



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


[clang] b4b5469 - [clang][Driver] Don't overwrite `DiagnosticsEngine::IgnoreAllWarnings`, rely on `DiagnosticOptions::IgnoreWarnings` value.

2022-12-02 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-12-02T11:59:22-08:00
New Revision: b4b54697b7aacda1fabef36d4e74d5ee45641618

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

LOG: [clang][Driver] Don't overwrite `DiagnosticsEngine::IgnoreAllWarnings`, 
rely on `DiagnosticOptions::IgnoreWarnings` value.

Driver overwrites `DiagnosticsEngine::IgnoreAllWarnings` based on `-w` flag
without taking into account `DiagnosticOptions::IgnoreWarnings` that is
propagated to `DiagnosticsEngine` in `ProcessWarningOptions` (called from
`CompilerInstance::createDiagnostics`). It makes it hard to manipulate
`DiagnosticOptions` directly and pushes towards string-based API.

Most of in-tree tools use `DiagnosticOptions` already, so migrate
`clang_parseTranslationUnit_Impl` to use it too. Don't parse `-w`
directly but rely on
```
def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>,
  MarshallingInfoFlag>;
```

Allows to reland D138252.

Differential Revision: https://reviews.llvm.org/D138970

Added: 


Modified: 
clang/lib/Driver/Driver.cpp
clang/tools/libclang/CIndex.cpp

Removed: 




diff  --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 5423fdc9855eb..6bd2d38f65744 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1211,9 +1211,6 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) {
   // FIXME: This stuff needs to go into the Compilation, not the driver.
   bool CCCPrintPhases;
 
-  // Silence driver warnings if requested
-  Diags.setIgnoreAllWarnings(Args.hasArg(options::OPT_w));
-
   // -canonical-prefixes, -no-canonical-prefixes are used very early in main.
   Args.ClaimAllArgs(options::OPT_canonical_prefixes);
   Args.ClaimAllArgs(options::OPT_no_canonical_prefixes);

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index dec7efd7bfb14..4210f162569ed 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -3797,8 +3797,10 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char 
*source_filename,
   }
 
   // Configure the diagnostics.
+  std::unique_ptr DiagOpts = CreateAndPopulateDiagOpts(
+  llvm::makeArrayRef(command_line_args, num_command_line_args));
   IntrusiveRefCntPtr Diags(
-  CompilerInstance::createDiagnostics(new DiagnosticOptions));
+  CompilerInstance::createDiagnostics(DiagOpts.release()));
 
   if (options & CXTranslationUnit_KeepGoing)
 Diags->setFatalsAsError(true);



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


[clang] eac90d1 - [clang][deps] During scanning don't emit warnings-as-errors that are ignored with diagnostic pragmas.

2022-11-28 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-11-28T13:48:29-08:00
New Revision: eac90d1236cfd2935fac5cbe5634f09e2cd0981a

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

LOG: [clang][deps] During scanning don't emit warnings-as-errors that are 
ignored with diagnostic pragmas.

Before the fix the scanning would fail with
`-Werror,-Wnon-modular-include-in-module` despite the warning being
suppressed in the source code.

Existing approach with `-Wno-error` is not sufficient because it negates
only general `-Werror` but not specific `-Werror=...` and some warnings
can still emitted as errors. Make the approach stricter by using `-w`
flag and ignore all warnings, including those upgraded to errors. This
approach is still valid as it doesn't affect the dependencies.

rdar://101588531

Differential Revision: https://reviews.llvm.org/D138252

Added: 
clang/test/ClangScanDeps/diagnostic-pragmas.c

Modified: 
clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Removed: 




diff  --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 50c42087d2fa..ff2d4b76820e 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -135,8 +135,8 @@ static void sanitizeDiagOpts(DiagnosticOptions ) {
   DiagOpts.ShowCarets = false;
   // Don't write out diagnostic file.
   DiagOpts.DiagnosticSerializationFile.clear();
-  // Don't treat warnings as errors.
-  DiagOpts.Warnings.push_back("no-error");
+  // Don't emit warnings as errors (and all other warnings too).
+  DiagOpts.IgnoreWarnings = true;
 }
 
 /// A clang tool that runs the preprocessor in a mode that's optimized for

diff  --git a/clang/test/ClangScanDeps/diagnostic-pragmas.c 
b/clang/test/ClangScanDeps/diagnostic-pragmas.c
new file mode 100644
index ..520f82047d2b
--- /dev/null
+++ b/clang/test/ClangScanDeps/diagnostic-pragmas.c
@@ -0,0 +1,35 @@
+// Test scanning deps does not have more errors than the regular compilation.
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+
+// Check the regular compilation does not fail.
+// RUN: %clang -fsyntax-only %t/test.c -I %t/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=%t/cache 
-Wnon-modular-include-in-module -Werror=non-modular-include-in-module
+
+// And now scanning deps should succeed too.
+// RUN: clang-scan-deps -compilation-database %t/cdb.json -j 1
+
+//--- cdb.json.template
+[
+  {
+"directory": "DIR",
+"command": "clang -fsyntax-only DIR/test.c -I DIR/include -fmodules 
-fimplicit-module-maps -fmodules-cache-path=DIR/cache 
-Wnon-modular-include-in-module -Werror=non-modular-include-in-module",
+"file": "DIR/test.c"
+  },
+]
+
+//--- include/nonmodular.h
+// empty
+
+//--- include/modular-includer.h
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-modular-include-in-module"
+#include 
+#pragma clang diagnostic pop
+
+//--- include/module.modulemap
+module ModularIncluder { header "modular-includer.h" }
+
+//--- test.c
+#include 



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


[clang] 0314ba3 - [modules] Fix marking `ObjCMethodDecl::isOverriding` when there are no overrides.

2022-11-24 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-11-24T14:26:02-08:00
New Revision: 0314ba3acbabd8dc6d39b6d49798d22b6dc33802

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

LOG: [modules] Fix marking `ObjCMethodDecl::isOverriding` when there are no 
overrides.

Incorrect `isOverriding` flag triggers the assertion
`!Overridden.empty()` in `ObjCMethodDecl::getOverriddenMethods` when a
method is marked as overriding but we cannot find any overrides.

When a method is declared in a category and defined in implementation,
we don't treat it as an override because it is the same method with
a separate declaration and a definition. But with modules we can find
a method declaration both in a modular category and a non-modular category
with different memory addresses. Thus we erroneously conclude the method
is overriding. Fix by comparing canonical declarations that are the same
for equal entities coming from different modules.

rdar://92845511

Differential Revision: https://reviews.llvm.org/D138630

Added: 
clang/test/Modules/override.m

Modified: 
clang/lib/Sema/SemaDeclObjC.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 97dff49862bb5..0cd764552b932 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -4438,6 +4438,11 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl 
*ObjCMethod,
 ResultTypeCompatibilityKind RTC) {
   if (!ObjCMethod)
 return;
+  auto IsMethodInCurrentClass = [CurrentClass](const ObjCMethodDecl *M) {
+// Checking canonical decl works across modules.
+return M->getClassInterface()->getCanonicalDecl() ==
+   CurrentClass->getCanonicalDecl();
+  };
   // Search for overridden methods and merge information down from them.
   OverrideSearch overrides(*this, ObjCMethod);
   // Keep track if the method overrides any method in the class's base classes,
@@ -4449,8 +4454,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl 
*ObjCMethod,
   for (ObjCMethodDecl *overridden : overrides) {
 if (!hasOverriddenMethodsInBaseOrProtocol) {
   if (isa(overridden->getDeclContext()) ||
-  CurrentClass != overridden->getClassInterface() ||
-  overridden->isOverriding()) {
+  !IsMethodInCurrentClass(overridden) || overridden->isOverriding()) {
 CheckObjCMethodDirectOverrides(ObjCMethod, overridden);
 hasOverriddenMethodsInBaseOrProtocol = true;
   } else if (isa(ObjCMethod->getDeclContext())) {
@@ -4475,7 +4479,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl 
*ObjCMethod,
   OverrideSearch overrides(*this, overridden);
   for (ObjCMethodDecl *SuperOverridden : overrides) {
 if (isa(SuperOverridden->getDeclContext()) ||
-CurrentClass != SuperOverridden->getClassInterface()) {
+!IsMethodInCurrentClass(SuperOverridden)) {
   CheckObjCMethodDirectOverrides(ObjCMethod, SuperOverridden);
   hasOverriddenMethodsInBaseOrProtocol = true;
   overridden->setOverriding(true);

diff  --git a/clang/test/Modules/override.m b/clang/test/Modules/override.m
new file mode 100644
index 0..247c2be76ee14
--- /dev/null
+++ b/clang/test/Modules/override.m
@@ -0,0 +1,69 @@
+// UNSUPPORTED: -aix
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -fsyntax-only -I%t/include %t/test.m \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache -fmodule-name=CheckOverride
+
+// Test that if we have the same method in a 
diff erent module, it's not an
+// override as it is the same method and it has the same DeclContext but a
+// 
diff erent object in the memory.
+
+
+//--- include/CheckOverride.h
+@interface NSObject
+@end
+
+@interface CheckOverrideInterfaceOnly: NSObject
+- (void)potentialOverrideInterfaceOnly;
+@end
+
+@interface CheckOverrideCategoryOnly: NSObject
+@end
+@interface CheckOverrideCategoryOnly(CategoryOnly)
+- (void)potentialOverrideCategoryOnly;
+@end
+
+@interface CheckOverrideImplementationOfInterface: NSObject
+- (void)potentialOverrideImplementationOfInterface;
+@end
+
+@interface CheckOverrideImplementationOfCategory: NSObject
+@end
+@interface CheckOverrideImplementationOfCategory(CategoryImpl)
+- (void)potentialOverrideImplementationOfCategory;
+@end
+
+//--- include/Redirect.h
+// Ensure CheckOverride is imported as the module despite all `-fmodule-name` 
flags.
+#import 
+
+//--- include/module.modulemap
+module CheckOverride {
+  header "CheckOverride.h"
+}
+module Redirect {
+  header "Redirect.h"
+  export *
+}
+
+//--- test.m
+#import 
+#import 
+
+@implementation CheckOverrideImplementationOfInterface

[clang] a65d530 - [ODRHash] Detect duplicate `ObjCProtocolDecl` ODR mismatches during parsing.

2022-11-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-11-17T18:31:32-08:00
New Revision: a65d5309d5b73527efcbdec49a3ba9bba0fd873d

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

LOG: [ODRHash] Detect duplicate `ObjCProtocolDecl` ODR mismatches during 
parsing.

When during parsing we encountered a duplicate `ObjCProtocolDecl`, we
were always emitting an error. With this change we accept
* when a previous `ObjCProtocolDecl` is in a hidden [sub]module;
* parsed `ObjCProtocolDecl` is the same as the previous one.

And in case of mismatches we provide more detailed error messages.

rdar://93069080

Differential Revision: https://reviews.llvm.org/D130327

Added: 
clang/test/Modules/hidden-duplicates.m

Modified: 
clang/include/clang/AST/DeclObjC.h
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/AST/DeclObjC.cpp
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/Parse/ParseObjc.cpp
clang/lib/Sema/SemaDeclObjC.cpp
clang/test/Modules/compare-objc-protocol.m

Removed: 




diff  --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 3d20d172dc631..6e83060d5a4d4 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -2230,6 +2230,13 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
   /// Starts the definition of this Objective-C protocol.
   void startDefinition();
 
+  /// Starts the definition without sharing it with other redeclarations.
+  /// Such definition shouldn't be used for anything but only to compare if
+  /// a duplicate is compatible with previous definition or if it is
+  /// a distinct duplicate.
+  void startDuplicateDefinitionForComparison();
+  void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition);
+
   /// Produce a name to be used for protocol's metadata. It comes either via
   /// objc_runtime_name attribute or protocol name.
   StringRef getObjCRuntimeNameAsString() const;

diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index 4c41a4a6004f1..d3b7f5e6b4109 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -55,6 +55,16 @@ class ODRDiagsEmitter {
   const ObjCProtocolDecl *SecondProtocol,
   const struct ObjCProtocolDecl::DefinitionData *SecondDD) const;
 
+  /// Diagnose ODR mismatch between ObjCProtocolDecl with 
diff erent definitions.
+  bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol,
+const ObjCProtocolDecl *SecondProtocol) const {
+assert(FirstProtocol->data().Definition !=
+   SecondProtocol->data().Definition &&
+   "Don't diagnose 
diff erences when definitions are merged already");
+return diagnoseMismatch(FirstProtocol, SecondProtocol,
+>data());
+  }
+
   /// Get the best name we know for the module that owns the given
   /// declaration, or an empty string if the declaration is not from a module.
   static std::string getOwningModuleNameForDiagnostic(const Decl *D);

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 0f7e256d8056f..15bd9d7c0e49a 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -622,10 +622,11 @@ def err_module_odr_violation_mismatch_decl : Error<
   "%select{end of class|public access specifier|private access specifier|"
   "protected access specifier|static assert|field|method|type alias|typedef|"
   "data member|friend declaration|function template|method|property}3">;
-def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
+def note_module_odr_violation_mismatch_decl : Note<
+  "but in %select{'%1'|definition here}0 found "
   "%select{end of class|public access specifier|private access specifier|"
   "protected access specifier|static assert|field|method|type alias|typedef|"
-  "data member|friend declaration|function template|method|property}1">;
+  "data member|friend declaration|function template|method|property}2">;
 
 def err_module_odr_violation_record : Error<
   "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
@@ -843,11 +844,12 @@ def err_module_odr_violation_referenced_protocols : Error 
<
   "%4 referenced %plural{1:protocol|:protocols}4|"
   "%ordinal4 referenced protocol with name %5"
   "}3">;
-def note_module_odr_violation_referenced_protocols : Note <"but in '%0' found "
+def note_module_odr_violation_referenced_protocols : Note <
+  "but in %select{'%1'|definition here}0 found "
   "%select{"
-  "%2 referenced 

[clang] dcb71b5 - [ODRHash] Hash `ObjCPropertyDecl` and diagnose discovered mismatches.

2022-11-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-11-17T17:22:03-08:00
New Revision: dcb71b5e1d1311c41f409c8dab26e04b084875be

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

LOG: [ODRHash] Hash `ObjCPropertyDecl` and diagnose discovered mismatches.

Differential Revision: https://reviews.llvm.org/D130326

Added: 


Modified: 
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp
clang/test/Modules/compare-objc-protocol.m

Removed: 




diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index cbabaa7e69b41..4c41a4a6004f1 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -81,6 +81,7 @@ class ODRDiagsEmitter {
 Friend,
 FunctionTemplate,
 ObjCMethod,
+ObjCProperty,
 Other
   };
 
@@ -149,6 +150,15 @@ class ODRDiagsEmitter {
  const ObjCMethodDecl *FirstMethod,
  const ObjCMethodDecl *SecondMethod) const;
 
+  /// Check if Objective-C properties are the same and diagnose if 
diff erent.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool
+  diagnoseSubMismatchObjCProperty(const NamedDecl *FirstObjCContainer,
+  StringRef FirstModule, StringRef 
SecondModule,
+  const ObjCPropertyDecl *FirstProp,
+  const ObjCPropertyDecl *SecondProp) const;
+
 private:
   DiagnosticsEngine 
   const ASTContext 

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index af7aec65bf6c8..0f7e256d8056f 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -621,11 +621,11 @@ def err_module_odr_violation_mismatch_decl : Error<
   "%select{definition in module '%2'|defined here}1 found "
   "%select{end of class|public access specifier|private access specifier|"
   "protected access specifier|static assert|field|method|type alias|typedef|"
-  "data member|friend declaration|function template|method}3">;
+  "data member|friend declaration|function template|method|property}3">;
 def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
   "%select{end of class|public access specifier|private access specifier|"
   "protected access specifier|static assert|field|method|type alias|typedef|"
-  "data member|friend declaration|function template|method}1">;
+  "data member|friend declaration|function template|method|property}1">;
 
 def err_module_odr_violation_record : Error<
   "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
@@ -891,18 +891,40 @@ def note_module_odr_violation_method_params : Note<"but 
in '%0' found "
 "with %ordinal4 parameter named %5"
   "}1">;
 
+def err_module_odr_violation_objc_property : Error<
+  "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
+  "%select{definition in module '%2'|defined here}1 found "
+  "%select{"
+  "property %4|"
+  "property %4 with type %5|"
+  "%select{no|'required'|'optional'}4 property control|"
+  "property %4 with %select{default |}6'%select{none|readonly|getter|assign|"
+"readwrite|retain|copy|nonatomic|setter|atomic|weak|strong|"
+"unsafe_unretained|nullability|null_resettable|class|direct}5' attribute"
+  "}3">;
+def note_module_odr_violation_objc_property : Note<
+  "but in '%0' found "
+  "%select{"
+  "property %2|"
+  "property %2 with type %3|"
+  "%select{no|'required'|'optional'}2 property control|"
+  "property %2 with 
diff erent '%select{none|readonly|getter|assign|"
+"readwrite|retain|copy|nonatomic|setter|atomic|weak|strong|"
+"unsafe_unretained|nullability|null_resettable|class|direct}3' attribute"
+  "}1">;
+
 def err_module_odr_violation_mismatch_decl_unknown : Error<
   "%q0 %select{with definition in module '%2'|defined here}1 has 
diff erent "
   "definitions in 
diff erent modules; first 
diff erence is this "
   "%select{static assert|field|method|type alias|typedef|data member|"
   "friend declaration|function template|method|"
-  "unexpected decl}3">;
+  "property|unexpected decl}3">;
 def note_module_odr_violation_mismatch_decl_unknown : Note<
   "but in '%0' found "
   "%select{
diff erent static assert|
diff erent field|
diff erent method|"
   "
diff erent type alias|
diff erent typedef|
diff erent data member|"
   "
diff erent friend declaration|
diff erent function template|
diff erent method|"
-  "another unexpected decl}1">;
+  "
diff erent property|another unexpected decl}1">;
 
 
 def 

[clang] 2662009 - [ODRHash] Hash `ObjCMethodDecl` and diagnose discovered mismatches.

2022-10-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-10-17T18:48:24-07:00
New Revision: 2662009c87f470ec5bc13c237cd62c57b28e4032

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

LOG: [ODRHash] Hash `ObjCMethodDecl` and diagnose discovered mismatches.

Differential Revision: https://reviews.llvm.org/D130325

Added: 


Modified: 
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp
clang/test/Modules/compare-objc-protocol.m

Removed: 




diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index d79b3e1c0649..cbabaa7e69b4 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -62,8 +62,10 @@ class ODRDiagsEmitter {
 private:
   using DeclHashes = llvm::SmallVector, 4>;
 
-  // Used with err_module_odr_violation_mismatch_decl and
-  // note_module_odr_violation_mismatch_decl
+  // Used with err_module_odr_violation_mismatch_decl,
+  // note_module_odr_violation_mismatch_decl,
+  // err_module_odr_violation_mismatch_decl_unknown,
+  // and note_module_odr_violation_mismatch_decl_unknown
   // This list should be the same Decl's as in ODRHash::isSubDeclToBeProcessed
   enum ODRMismatchDecl {
 EndOfClass,
@@ -78,6 +80,7 @@ class ODRDiagsEmitter {
 Var,
 Friend,
 FunctionTemplate,
+ObjCMethod,
 Other
   };
 
@@ -137,6 +140,15 @@ class ODRDiagsEmitter {
 const ObjCContainerDecl *SecondContainer,
 StringRef SecondModule) const;
 
+  /// Check if Objective-C methods are the same and diagnose if 
diff erent.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool diagnoseSubMismatchObjCMethod(const NamedDecl *FirstObjCContainer,
+ StringRef FirstModule,
+ StringRef SecondModule,
+ const ObjCMethodDecl *FirstMethod,
+ const ObjCMethodDecl *SecondMethod) const;
+
 private:
   DiagnosticsEngine 
   const ASTContext 

diff  --git a/clang/include/clang/Basic/DiagnosticASTKinds.td 
b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 2517f52a7cf7..c4f520442549 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -621,11 +621,11 @@ def err_module_odr_violation_mismatch_decl : Error<
   "%select{definition in module '%2'|defined here}1 found "
   "%select{end of class|public access specifier|private access specifier|"
   "protected access specifier|static assert|field|method|type alias|typedef|"
-  "data member|friend declaration|function template}3">;
+  "data member|friend declaration|function template|method}3">;
 def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
   "%select{end of class|public access specifier|private access specifier|"
   "protected access specifier|static assert|field|method|type alias|typedef|"
-  "data member|friend declaration|function template}1">;
+  "data member|friend declaration|function template|method}1">;
 
 def err_module_odr_violation_record : Error<
   "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
@@ -649,12 +649,6 @@ def err_module_odr_violation_record : Error<
 "is %select{not const|const}6|"
   "%select{method %5|constructor|destructor}4 "
 "is %select{not inline|inline}6|"
-  "%select{method %5|constructor|destructor}4 "
-"that has %6 parameter%s6|"
-  "%select{method %5|constructor|destructor}4 "
-"with %ordinal6 parameter of type %7%select{| decayed from %9}8|"
-  "%select{method %5|constructor|destructor}4 "
-"with %ordinal6 parameter named %7|"
   "%select{method %5|constructor|destructor}4 "
 "with %ordinal6 parameter with%select{out|}7 a default argument|"
   "%select{method %5|constructor|destructor}4 "
@@ -706,12 +700,6 @@ def note_module_odr_violation_record : Note<"but in '%0' 
found "
 "is %select{not const|const}4|"
   "%select{method %3|constructor|destructor}2 "
 "is %select{not inline|inline}4|"
-  "%select{method %3|constructor|destructor}2 "
-"that has %4 parameter%s4|"
-  "%select{method %3|constructor|destructor}2 "
-"with %ordinal4 parameter of type %5%select{| decayed from %7}6|"
-  "%select{method %3|constructor|destructor}2 "
-"with %ordinal4 parameter named %5|"
   "%select{method %3|constructor|destructor}2 "
 "with %ordinal4 parameter with%select{out|}5 a default argument|"
   "%select{method %3|constructor|destructor}2 "
@@ -861,17 +849,59 @@ def note_module_odr_violation_referenced_protocols : Note 
<"but in '%0' 

[clang] 37fdca2 - [ODRHash] Rename `isDeclToBeProcessed` to `isSubDeclToBeProcessed`. NFC intended.

2022-10-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-10-17T18:24:44-07:00
New Revision: 37fdca21f7f61dee5426f55b0ee7bf601d95afcd

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

LOG: [ODRHash] Rename `isDeclToBeProcessed` to `isSubDeclToBeProcessed`. NFC 
intended.

The method is used only for sub-Decls, so reflect that in the name.

Added: 


Modified: 
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/AST/ODRHash.h
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index af345310c3a4..d79b3e1c0649 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -64,7 +64,7 @@ class ODRDiagsEmitter {
 
   // Used with err_module_odr_violation_mismatch_decl and
   // note_module_odr_violation_mismatch_decl
-  // This list should be the same Decl's as in ODRHash::isDeclToBeProcessed
+  // This list should be the same Decl's as in ODRHash::isSubDeclToBeProcessed
   enum ODRMismatchDecl {
 EndOfClass,
 PublicSpecifer,

diff  --git a/clang/include/clang/AST/ODRHash.h 
b/clang/include/clang/AST/ODRHash.h
index 59b74cf477dd..1ab20013a367 100644
--- a/clang/include/clang/AST/ODRHash.h
+++ b/clang/include/clang/AST/ODRHash.h
@@ -93,7 +93,7 @@ class ODRHash {
   // Save booleans until the end to lower the size of data to process.
   void AddBoolean(bool value);
 
-  static bool isDeclToBeProcessed(const Decl* D, const DeclContext *Parent);
+  static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent);
 
 private:
   void AddDeclarationNameImpl(DeclarationName Name);

diff  --git a/clang/lib/AST/ODRDiagsEmitter.cpp 
b/clang/lib/AST/ODRDiagsEmitter.cpp
index 3cc280a53a8c..1fda502e323b 100644
--- a/clang/lib/AST/ODRDiagsEmitter.cpp
+++ b/clang/lib/AST/ODRDiagsEmitter.cpp
@@ -630,7 +630,7 @@ bool ODRDiagsEmitter::diagnoseMismatch(
   auto PopulateHashes = [](DeclHashes , const RecordDecl *Record,
const DeclContext *DC) {
 for (const Decl *D : Record->decls()) {
-  if (!ODRHash::isDeclToBeProcessed(D, DC))
+  if (!ODRHash::isSubDeclToBeProcessed(D, DC))
 continue;
   Hashes.emplace_back(D, computeODRHash(D));
 }
@@ -1538,7 +1538,7 @@ bool ODRDiagsEmitter::diagnoseMismatch(const EnumDecl 
*FirstEnum,
 for (const Decl *D : Enum->decls()) {
   // Due to decl merging, the first EnumDecl is the parent of
   // Decls in both records.
-  if (!ODRHash::isDeclToBeProcessed(D, FirstEnum))
+  if (!ODRHash::isSubDeclToBeProcessed(D, FirstEnum))
 continue;
   assert(isa(D) && "Unexpected Decl kind");
   Hashes.emplace_back(cast(D), computeODRHash(D));
@@ -1620,7 +1620,7 @@ bool ODRDiagsEmitter::diagnoseMismatch(
   auto PopulateHashes = [](DeclHashes , const ObjCProtocolDecl *ID,
const DeclContext *DC) {
 for (const Decl *D : ID->decls()) {
-  if (!ODRHash::isDeclToBeProcessed(D, DC))
+  if (!ODRHash::isSubDeclToBeProcessed(D, DC))
 continue;
   Hashes.emplace_back(D, computeODRHash(D));
 }

diff  --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index cbb3e8730517..b485e93f76c2 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -441,7 +441,7 @@ class ODRDeclVisitor : public 
ConstDeclVisitor {
 
 // Only allow a small portion of Decl's to be processed.  Remove this once
 // all Decl's can be handled.
-bool ODRHash::isDeclToBeProcessed(const Decl *D, const DeclContext *Parent) {
+bool ODRHash::isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent) 
{
   if (D->isImplicit()) return false;
   if (D->getDeclContext() != Parent) return false;
 
@@ -488,7 +488,7 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) 
{
   // accurate count of Decl's.
   llvm::SmallVector Decls;
   for (Decl *SubDecl : Record->decls()) {
-if (isDeclToBeProcessed(SubDecl, Record)) {
+if (isSubDeclToBeProcessed(SubDecl, Record)) {
   Decls.push_back(SubDecl);
   if (auto *Function = dyn_cast(SubDecl)) {
 // Compute/Preload ODRHash into FunctionDecl.
@@ -589,7 +589,7 @@ void ODRHash::AddFunctionDecl(const FunctionDecl *Function,
   // accurate count of Decl's.
   llvm::SmallVector Decls;
   for (Decl *SubDecl : Function->decls()) {
-if (isDeclToBeProcessed(SubDecl, Function)) {
+if (isSubDeclToBeProcessed(SubDecl, Function)) {
   Decls.push_back(SubDecl);
 }
   }
@@ -615,7 +615,7 @@ void ODRHash::AddEnumDecl(const EnumDecl *Enum) {
   // accurate count of Decl's.
   llvm::SmallVector Decls;
   for (Decl *SubDecl : Enum->decls()) {
-if (isDeclToBeProcessed(SubDecl, Enum)) {
+if 

[clang] 9c79eab - [ODRHash] Hash `ObjCProtocolDecl` and diagnose discovered mismatches.

2022-10-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-10-17T16:29:52-07:00
New Revision: 9c79eab7fdd5e2bc413e9c4510f759716cd09184

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

LOG: [ODRHash] Hash `ObjCProtocolDecl` and diagnose discovered mismatches.

Differential Revision: https://reviews.llvm.org/D130324

Added: 
clang/test/Modules/compare-objc-protocol.m

Modified: 
clang/include/clang/AST/DeclObjC.h
clang/include/clang/AST/ODRDiagsEmitter.h
clang/include/clang/AST/ODRHash.h
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/DeclObjC.cpp
clang/lib/AST/ODRDiagsEmitter.cpp
clang/lib/AST/ODRHash.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriterDecl.cpp

Removed: 




diff  --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 210b7adebe4cd..3d20d172dc631 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -2055,6 +2055,12 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
 
 /// Referenced protocols
 ObjCProtocolList ReferencedProtocols;
+
+/// Tracks whether a ODR hash has been computed for this protocol.
+unsigned HasODRHash : 1;
+
+/// A hash of parts of the class to help in ODR checking.
+unsigned ODRHash = 0;
   };
 
   /// Contains a pointer to the data associated with this class,
@@ -2091,10 +2097,15 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
 return getMostRecentDecl();
   }
 
+  /// True if a valid hash is stored in ODRHash.
+  bool hasODRHash() const;
+  void setHasODRHash(bool HasHash);
+
 public:
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
   friend class ASTReader;
+  friend class ODRDiagsEmitter;
 
   static ObjCProtocolDecl *Create(ASTContext , DeclContext *DC,
   IdentifierInfo *Id,
@@ -2250,6 +2261,9 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
   ProtocolPropertySet ,
   PropertyDeclOrder ) const;
 
+  /// Get precomputed ODRHash or add a new one.
+  unsigned getODRHash();
+
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ObjCProtocol; }
 };

diff  --git a/clang/include/clang/AST/ODRDiagsEmitter.h 
b/clang/include/clang/AST/ODRDiagsEmitter.h
index 37e7dd4b05c9d..af345310c3a40 100644
--- a/clang/include/clang/AST/ODRDiagsEmitter.h
+++ b/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -11,6 +11,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 
@@ -44,6 +45,16 @@ class ODRDiagsEmitter {
const CXXRecordDecl *SecondRecord,
const struct CXXRecordDecl::DefinitionData *SecondDD) const;
 
+  /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  /// To compare 2 declarations with merged and identical definition data
+  /// you need to provide pre-merge definition data in \p SecondDD.
+  bool diagnoseMismatch(
+  const ObjCProtocolDecl *FirstProtocol,
+  const ObjCProtocolDecl *SecondProtocol,
+  const struct ObjCProtocolDecl::DefinitionData *SecondDD) const;
+
   /// Get the best name we know for the module that owns the given
   /// declaration, or an empty string if the declaration is not from a module.
   static std::string getOwningModuleNameForDiagnostic(const Decl *D);
@@ -116,6 +127,16 @@ class ODRDiagsEmitter {
   const VarDecl *FirstVD,
   const VarDecl *SecondVD) const;
 
+  /// Check if protocol lists are the same and diagnose if they are 
diff erent.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool diagnoseSubMismatchProtocols(const ObjCProtocolList ,
+const ObjCContainerDecl *FirstContainer,
+StringRef FirstModule,
+const ObjCProtocolList ,
+const ObjCContainerDecl *SecondContainer,
+StringRef SecondModule) const;
+
 private:
   DiagnosticsEngine 
   const ASTContext 

diff  --git a/clang/include/clang/AST/ODRHash.h 
b/clang/include/clang/AST/ODRHash.h
index 2e8593e0b8355..59b74cf477dd0 100644
--- a/clang/include/clang/AST/ODRHash.h
+++ b/clang/include/clang/AST/ODRHash.h
@@ -64,6 +64,10 @@ class ODRHash {
   // more information than the AddDecl class.
   void AddEnumDecl(const 

[clang] 1783253 - [Attributes] Improve writing `ExprArgument` value.

2022-10-14 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-10-14T11:20:57-07:00
New Revision: 1783253c41f1b0ac378ab7fa4b6fe5547369c6b0

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

LOG: [Attributes] Improve writing `ExprArgument` value.

Instead of dumping `Expr*` memory address, output `Expr` representation.

Differential Revision: https://reviews.llvm.org/D135931

Added: 


Modified: 
clang/test/SemaCXX/attr-print.cpp
clang/utils/TableGen/ClangAttrEmitter.cpp

Removed: 




diff  --git a/clang/test/SemaCXX/attr-print.cpp 
b/clang/test/SemaCXX/attr-print.cpp
index d7ef42306bd39..fa8059fc8ab36 100644
--- a/clang/test/SemaCXX/attr-print.cpp
+++ b/clang/test/SemaCXX/attr-print.cpp
@@ -43,3 +43,6 @@ class __multiple_inheritance MultipleInheritance;
 
 // CHECK: class __virtual_inheritance VirtualInheritance;
 class __virtual_inheritance VirtualInheritance;
+
+// CHECK: typedef double *aligned_double __attribute__((align_value(64)));
+typedef double * __attribute__((align_value(64))) aligned_double;

diff  --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 79590832f7d1d..b7f7e507dd6cf 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -1216,6 +1216,13 @@ namespace {
   OS << "  }\n";
 }
 
+void writeValue(raw_ostream ) const override {
+  OS << "\";\n";
+  OS << "get" << getUpperName()
+ << "()->printPretty(OS, nullptr, Policy);\n";
+  OS << "OS << \"";
+}
+
 void writeDump(raw_ostream ) const override {}
 
 void writeDumpChildren(raw_ostream ) const override {



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


[clang] a6ebd30 - [modules] Allow to validate system headers less often with `-fmodules-validate-once-per-build-session`.

2022-10-12 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-10-12T11:10:08-07:00
New Revision: a6ebd3083dbf8aadae58f6f2a2f1071976649d56

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

LOG: [modules] Allow to validate system headers less often with 
`-fmodules-validate-once-per-build-session`.

Make flags `-fmodules-validate-system-headers` and
`-fmodules-validate-once-per-build-session` orthogonal, so they have
their own independent responsibilities - if system headers should be
validated and how often.

rdar://8799

Differential Revision: https://reviews.llvm.org/D135232

Added: 


Modified: 
clang/lib/Serialization/ASTReader.cpp
clang/test/Modules/fmodules-validate-once-per-build-session.c
clang/test/Modules/validate-system-headers.m

Removed: 




diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 45a6a474f1d93..e3e1d9eb36ae1 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2639,12 +2639,11 @@ ASTReader::ReadControlBlock(ModuleFile ,
 // so we verify all input files.  Otherwise, verify only user input
 // files.
 
-unsigned N = NumUserInputs;
-if (ValidateSystemInputs ||
-(HSOpts.ModulesValidateOncePerBuildSession &&
- F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp &&
- F.Kind == MK_ImplicitModule))
-  N = NumInputs;
+unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
+if (HSOpts.ModulesValidateOncePerBuildSession &&
+F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp &&
+F.Kind == MK_ImplicitModule)
+  N = NumUserInputs;
 
 for (unsigned I = 0; I < N; ++I) {
   InputFile IF = getInputFile(F, I+1, Complain);

diff  --git a/clang/test/Modules/fmodules-validate-once-per-build-session.c 
b/clang/test/Modules/fmodules-validate-once-per-build-session.c
index 0c97342a8d70a..7ab6f78c194fd 100644
--- a/clang/test/Modules/fmodules-validate-once-per-build-session.c
+++ b/clang/test/Modules/fmodules-validate-once-per-build-session.c
@@ -17,8 +17,8 @@
 
 // ===
 // Compile the module.
-// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
-// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
+// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs 
-fmodules-validate-system-headers -fbuild-session-timestamp=139000 
-fmodules-validate-once-per-build-session %s
+// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs 
-fmodules-validate-system-headers -fbuild-session-timestamp=139000 
-fmodules-validate-once-per-build-session %s
 // RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
 // RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
 // RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
@@ -30,8 +30,8 @@
 
 // ===
 // Use it, and make sure that we did not recompile it.
-// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
-// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
+// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs 
-fmodules-validate-system-headers -fbuild-session-timestamp=139000 
-fmodules-validate-once-per-build-session %s
+// RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs 
-fmodules-validate-system-headers -fbuild-session-timestamp=139000 
-fmodules-validate-once-per-build-session %s
 // RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
 // RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
 // RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
@@ -54,8 +54,8 @@
 // ===
 // Use the module, and make sure that we did not recompile it if foo.h or
 // module.map are system 

[clang] e12f6c2 - [modules] Fix error "malformed or corrupted AST file: 'SourceLocation remap refers to unknown module...'".

2022-09-20 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-09-20T17:55:37-07:00
New Revision: e12f6c26c394bd5b49e7c1e1c157bcee3a33d1de

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

LOG: [modules] Fix error "malformed or corrupted AST file: 'SourceLocation 
remap refers to unknown module...'".

When a framework can be found at a new location, all references to it in
the module cache become outdated. When we try to load such outdated .pcm
file, we shouldn't change any already loaded and processed modules.

If `Module` has `ASTFile`, it means we've read its AST block already and
it is too late to undo that. If `ASTFile` is `None`, there is no value
in setting it to `None` again. So we don't reset `ASTFile` in
`ModuleManager::removeModules` at all.

rdar://97216258

Differential Revision: https://reviews.llvm.org/D134249

Added: 
clang/test/Modules/dependent-module-different-location.m

Modified: 
clang/include/clang/Basic/Module.h
clang/include/clang/Serialization/ModuleManager.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ModuleManager.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/Module.h 
b/clang/include/clang/Basic/Module.h
index a2309f5d7fae..1a1feb9d4d3f 100644
--- a/clang/include/clang/Basic/Module.h
+++ b/clang/include/clang/Basic/Module.h
@@ -608,8 +608,7 @@ class Module {
 
   /// Set the serialized AST file for the top-level module of this module.
   void setASTFile(Optional File) {
-assert((!File || !getASTFile() || getASTFile() == File) &&
-   "file path changed");
+assert((!getASTFile() || getASTFile() == File) && "file path changed");
 getTopLevelModule()->ASTFile = File;
   }
 

diff  --git a/clang/include/clang/Serialization/ModuleManager.h 
b/clang/include/clang/Serialization/ModuleManager.h
index 4305bae5ee95..1623dd446036 100644
--- a/clang/include/clang/Serialization/ModuleManager.h
+++ b/clang/include/clang/Serialization/ModuleManager.h
@@ -250,7 +250,7 @@ class ModuleManager {
 std::string );
 
   /// Remove the modules starting from First (to the end).
-  void removeModules(ModuleIterator First, ModuleMap *modMap);
+  void removeModules(ModuleIterator First);
 
   /// Add an in-memory buffer the list of known buffers
   void addInMemoryBuffer(StringRef FileName,

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 2716a5971c8f..ad6db3ce1993 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4227,10 +4227,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef 
FileName,
   ReadASTCore(FileName, Type, ImportLoc,
   /*ImportedBy=*/nullptr, Loaded, 0, 0, ASTFileSignature(),
   ClientLoadCapabilities)) {
-ModuleMgr.removeModules(ModuleMgr.begin() + NumModules,
-PP.getLangOpts().Modules
-? ().getModuleMap()
-: nullptr);
+ModuleMgr.removeModules(ModuleMgr.begin() + NumModules);
 
 // If we find that any modules are unusable, the global index is going
 // to be out-of-date. Just remove it.

diff  --git a/clang/lib/Serialization/ModuleManager.cpp 
b/clang/lib/Serialization/ModuleManager.cpp
index 4fd217cf7a6e..544dac1716b0 100644
--- a/clang/lib/Serialization/ModuleManager.cpp
+++ b/clang/lib/Serialization/ModuleManager.cpp
@@ -249,7 +249,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind 
Type,
   return NewlyLoaded;
 }
 
-void ModuleManager::removeModules(ModuleIterator First, ModuleMap *modMap) {
+void ModuleManager::removeModules(ModuleIterator First) {
   auto Last = end();
   if (First == Last)
 return;
@@ -280,19 +280,10 @@ void ModuleManager::removeModules(ModuleIterator First, 
ModuleMap *modMap) {
 }
   }
 
-  // Delete the modules and erase them from the various structures.
-  for (ModuleIterator victim = First; victim != Last; ++victim) {
+  // Delete the modules.
+  for (ModuleIterator victim = First; victim != Last; ++victim)
 Modules.erase(victim->File);
 
-if (modMap) {
-  StringRef ModuleName = victim->ModuleName;
-  if (Module *mod = modMap->findModule(ModuleName)) {
-mod->setASTFile(None);
-  }
-}
-  }
-
-  // Delete the modules.
   Chain.erase(Chain.begin() + (First - begin()), Chain.end());
 }
 

diff  --git a/clang/test/Modules/dependent-module-
diff erent-location.m b/clang/test/Modules/dependent-module-
diff erent-location.m
new file mode 100644
index ..f969aa9958bd
--- /dev/null
+++ b/clang/test/Modules/dependent-module-
diff erent-location.m
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+//
+// At first build Stable.pcm that references 

[clang] 246c5a9 - [ODRHash diagnostics] Transform method `ASTReader::diagnoseOdrViolations` into a class `ODRDiagsEmitter`. NFC.

2022-09-02 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-09-02T16:20:05-07:00
New Revision: 246c5a994b753fb52b2d3b70687039afef7a106e

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

LOG: [ODRHash diagnostics] Transform method `ASTReader::diagnoseOdrViolations` 
into a class `ODRDiagsEmitter`. NFC.

Preparing to use diagnostics about ODR hash mismatches outside of ASTReader.

Differential Revision: https://reviews.llvm.org/D128490

Added: 


Modified: 
clang/include/clang/AST/DeclCXX.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/Serialization/ASTReader.cpp

Removed: 




diff  --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index c97301957cb60..89c7fb36aa57f 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -260,6 +260,7 @@ class CXXRecordDecl : public RecordDecl {
   friend class ASTWriter;
   friend class DeclContext;
   friend class LambdaExpr;
+  friend class ODRDiagsEmitter;
 
   friend void FunctionDecl::setPure(bool);
   friend void TagDecl::startDefinition();

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index 19a18a2ef4030..22f317dc6b3f7 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1845,10 +1845,6 @@ class ASTReader
   /// if the declaration is not from a module file.
   ModuleFile *getOwningModuleFile(const Decl *D);
 
-  /// Get the best name we know for the module that owns the given
-  /// declaration, or an empty string if the declaration is not from a module.
-  std::string getOwningModuleNameForDiagnostic(const Decl *D);
-
   /// Returns the source location for the decl \p ID.
   SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
 

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index e7dea40a16100..eef8f9fdb07f1 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9186,19 +9186,6 @@ void ASTReader::visitTopLevelModuleMaps(
   }
 }
 
-std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
-  // If we know the owning module, use it.
-  if (Module *M = D->getImportedOwningModule())
-return M->getFullModuleName();
-
-  // Otherwise, use the name of the top-level module the decl is within.
-  if (ModuleFile *M = getOwningModuleFile(D))
-return M->ModuleName;
-
-  // Not from a module.
-  return {};
-}
-
 void ASTReader::finishPendingActions() {
   while (!PendingIdentifierInfos.empty() || !PendingFunctionTypes.empty() ||
  !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
@@ -9446,6 +9433,114 @@ void ASTReader::finishPendingActions() {
   PendingMergedDefinitionsToDeduplicate.clear();
 }
 
+namespace clang {
+class ODRDiagsEmitter {
+public:
+  ODRDiagsEmitter(DiagnosticsEngine , const ASTContext ,
+  const LangOptions )
+  : Diags(Diags), Context(Context), LangOpts(LangOpts) {}
+
+  /// Diagnose ODR mismatch between 2 FunctionDecl.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool diagnoseMismatch(const FunctionDecl *FirstFunction,
+const FunctionDecl *SecondFunction) const;
+
+  /// Diagnose ODR mismatch between 2 EnumDecl.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  bool diagnoseMismatch(const EnumDecl *FirstEnum,
+const EnumDecl *SecondEnum) const;
+
+  /// Diagnose ODR mismatch between 2 CXXRecordDecl.
+  ///
+  /// Returns true if found a mismatch and diagnosed it.
+  /// To compare 2 declarations with merged and identical definition data
+  /// you need to provide pre-merge definition data in \p SecondDD.
+  bool
+  diagnoseMismatch(const CXXRecordDecl *FirstRecord,
+   const CXXRecordDecl *SecondRecord,
+   const struct CXXRecordDecl::DefinitionData *SecondDD) const;
+
+  /// Get the best name we know for the module that owns the given
+  /// declaration, or an empty string if the declaration is not from a module.
+  static std::string getOwningModuleNameForDiagnostic(const Decl *D);
+
+private:
+  using DeclHashes = llvm::SmallVector, 4>;
+
+  // Used with err_module_odr_violation_mismatch_decl and
+  // note_module_odr_violation_mismatch_decl
+  // This list should be the same Decl's as in ODRHash::isDeclToBeProcessed
+  enum ODRMismatchDecl {
+EndOfClass,
+PublicSpecifer,
+PrivateSpecifer,
+ProtectedSpecifer,
+StaticAssert,
+Field,
+CXXMethod,
+TypeAlias,
+TypeDef,
+Var,
+Friend,
+FunctionTemplate,
+Other
+  };
+
+  struct DiffResult {
+const Decl *FirstDecl = nullptr, *SecondDecl = 

[clang] 1e4478b - Move "clang/Basic/TokenKinds.h" into a separate top-level module.

2022-07-22 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-07-22T16:26:27-07:00
New Revision: 1e4478bbea727dbbffb1023eedfc24eae7185782

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

LOG: Move "clang/Basic/TokenKinds.h" into a separate top-level module.

Fixes modular build for clangPseudoGrammar from clang-tools-extra.

Starting from https://reviews.llvm.org/D126731 clangPseudoGrammar
doesn't depend on generated .inc headers but still depends on
"Basic/TokenKinds.h". It means clangPseudoGrammar depends on module
'Clang_Basic' which does depend on generated .inc headers. To avoid
these coarse dependencies and extra build steps, extract
"clang/Basic/TokenKinds.h" into a top-level module 'Clang_Basic_TokenKinds'.

rdar://97387951

Differential Revision: https://reviews.llvm.org/D130377

Added: 


Modified: 
clang/include/clang/module.modulemap

Removed: 




diff  --git a/clang/include/clang/module.modulemap 
b/clang/include/clang/module.modulemap
index aca4d5ab919a..56c40ab0b001 100644
--- a/clang/include/clang/module.modulemap
+++ b/clang/include/clang/module.modulemap
@@ -71,10 +71,17 @@ module Clang_Basic {
   textual header "Basic/RISCVVTypes.def"
   textual header "Basic/Sanitizers.def"
   textual header "Basic/TargetCXXABI.def"
-  textual header "Basic/TokenKinds.def"
 
   module * { export * }
 }
+module Clang_Basic_TokenKinds {
+  requires cplusplus
+
+  header "Basic/TokenKinds.h"
+  textual header "Basic/TokenKinds.def"
+
+  export *
+}
 
 module Clang_CodeGen { requires cplusplus umbrella "CodeGen" module * { export 
* } }
 module Clang_Config { requires cplusplus umbrella "Config" module * { export * 
} }



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


[clang] 381fcaa - [modules] Replace `-Wauto-import` with `-Rmodule-include-translation`.

2022-07-21 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-07-21T17:42:04-07:00
New Revision: 381fcaa1365b4fd8f9682a6a1e09f5b3fd4bbfc2

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

LOG: [modules] Replace `-Wauto-import` with `-Rmodule-include-translation`.

Diagnostic for `-Wauto-import` shouldn't be a warning because it doesn't
represent a potential problem in code that should be fixed. And the
emitted fix-it is likely to trigger `-Watimport-in-framework-header`
which makes it challenging to have a warning-free codebase. But it is
still useful to see how include directives are translated into modular
imports and which module a header belongs to, that's why keep it as a remark.

Keep `-Wauto-import` for now to allow a gradual migration for codebases
using `-Wno-auto-import`, e.g., `-Weverything -Wno-auto-import`.

rdar://79594287

Differential Revision: https://reviews.llvm.org/D130138

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticLexKinds.td
clang/lib/Lex/PPDirectives.cpp
clang/test/Modules/auto-module-import.m
clang/test/Modules/conflicts.m
clang/test/Modules/cxx20-include-translation.cpp
clang/test/Modules/framework-name.m
clang/test/Modules/global_index.m
clang/test/Modules/implementation-of-module.m
clang/test/Modules/inferred-frameworks.m
clang/test/Modules/inferred-submodules.m
clang/test/Modules/requires.m
clang/test/Modules/requires.mm
clang/test/Modules/resolution-change.m
clang/test/Modules/subframeworks.m
clang/test/Modules/submodules.m
clang/test/VFS/real-path-found-first.m

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 53e246a39ed86..4412c93683ed3 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -35,7 +35,7 @@ def ArrayParameter : DiagGroup<"array-parameter">;
 def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;
 def Availability : DiagGroup<"availability">;
 def Section : DiagGroup<"section">;
-def AutoImport : DiagGroup<"auto-import">;
+def : DiagGroup<"auto-import">;
 def FrameworkHdrQuotedInclude : 
DiagGroup<"quoted-include-in-framework-header">;
 def FrameworkIncludePrivateFromPublic :
   DiagGroup<"framework-include-private-from-public">;
@@ -490,6 +490,7 @@ def ModuleBuild : DiagGroup<"module-build">;
 def ModuleImport : DiagGroup<"module-import">;
 def ModuleConflict : DiagGroup<"module-conflict">;
 def ModuleFileExtension : DiagGroup<"module-file-extension">;
+def ModuleIncludeDirectiveTranslation : 
DiagGroup<"module-include-translation">;
 def RoundTripCC1Args : DiagGroup<"round-trip-cc1-args">;
 def NewlineEOF : DiagGroup<"newline-eof">;
 def Nullability : DiagGroup<"nullability">;

diff  --git a/clang/include/clang/Basic/DiagnosticLexKinds.td 
b/clang/include/clang/Basic/DiagnosticLexKinds.td
index dd09097044926..5d3abb1f9b702 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -851,9 +851,9 @@ def warn_framework_include_private_from_public : Warning<
   "public framework header includes private framework header '%0'"
   >, InGroup;
 
-def warn_auto_module_import : Warning<
+def remark_pp_include_directive_modular_translation : Remark<
   "treating #%select{include|import|include_next|__include_macros}0 as an "
-  "import of module '%1'">, InGroup, DefaultIgnore;
+  "import of module '%1'">, InGroup;
 def note_implicit_top_level_module_import_here : Note<
   "submodule of top-level module '%0' implicitly imported here">;
 def warn_uncovered_module_header : Warning<

diff  --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 352e1f2178193..4679cb4e7a34b 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1806,22 +1806,14 @@ static void diagnoseAutoModuleImport(
 Preprocessor , SourceLocation HashLoc, Token ,
 ArrayRef> Path,
 SourceLocation PathEnd) {
-  StringRef ImportKeyword;
-  if (PP.getLangOpts().ObjC)
-ImportKeyword = "@import";
-  else if (PP.getLangOpts().ModulesTS || PP.getLangOpts().CPlusPlusModules)
-ImportKeyword = "import";
-  else
-return; // no import syntax available
-
   SmallString<128> PathString;
   for (size_t I = 0, N = Path.size(); I != N; ++I) {
 if (I)
   PathString += '.';
 PathString += Path[I].first->getName();
   }
-  int IncludeKind = 0;
 
+  int IncludeKind = 0;
   switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
   case tok::pp_include:
 IncludeKind = 0;
@@ -1843,12 +1835,8 @@ static void diagnoseAutoModuleImport(
 llvm_unreachable("unknown include directive kind");
   }
 
-  

[clang] f693874 - [ODRHash diagnostics] Preparation to minimize subsequent diffs. NFC.

2022-07-19 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-07-19T16:29:33-07:00
New Revision: f693874c53c1b3d3a322de98c1c7557d69157d3d

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

LOG: [ODRHash diagnostics] Preparation to minimize subsequent diffs. NFC.

Specifically, making the following changes:
* Turn lambdas calculating ODR hashes into static functions.
* Move `ODRCXXRecordDifference` where it is used.
* Rename some variables and move some lines of code.
* Replace `auto` with explicit type when the deduced type is not mentioned.
* Add `const` for unmodified objects, so we can pass them to more functions.

Differential Revision: https://reviews.llvm.org/D128690

Added: 


Modified: 
clang/lib/Serialization/ASTReader.cpp

Removed: 




diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 04ade0a3b9d0..76281d26b2ae 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9445,6 +9445,31 @@ void ASTReader::finishPendingActions() {
   PendingMergedDefinitionsToDeduplicate.clear();
 }
 
+static unsigned computeODRHash(QualType Ty) {
+  ODRHash Hasher;
+  Hasher.AddQualType(Ty);
+  return Hasher.CalculateHash();
+}
+
+static unsigned computeODRHash(const Stmt *S) {
+  ODRHash Hasher;
+  Hasher.AddStmt(S);
+  return Hasher.CalculateHash();
+}
+
+static unsigned computeODRHash(const Decl *D) {
+  assert(D);
+  ODRHash Hasher;
+  Hasher.AddSubDecl(D);
+  return Hasher.CalculateHash();
+}
+
+static unsigned computeODRHash(const TemplateArgument ) {
+  ODRHash Hasher;
+  Hasher.AddTemplateArgument(TA);
+  return Hasher.CalculateHash();
+}
+
 void ASTReader::diagnoseOdrViolations() {
   if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty() &&
   PendingFunctionOdrMergeFailures.empty() &&
@@ -9584,42 +9609,6 @@ void ASTReader::diagnoseOdrViolations() {
   // we're producing our diagnostics.
   Deserializing RecursionGuard(this);
 
-  // Common code for hashing helpers.
-  ODRHash Hash;
-  auto ComputeQualTypeODRHash = [](QualType Ty) {
-Hash.clear();
-Hash.AddQualType(Ty);
-return Hash.CalculateHash();
-  };
-
-  auto ComputeODRHash = [](const Stmt *S) {
-assert(S);
-Hash.clear();
-Hash.AddStmt(S);
-return Hash.CalculateHash();
-  };
-
-  auto ComputeSubDeclODRHash = [](const Decl *D) {
-assert(D);
-Hash.clear();
-Hash.AddSubDecl(D);
-return Hash.CalculateHash();
-  };
-
-  auto ComputeTemplateArgumentODRHash = [](const TemplateArgument ) {
-Hash.clear();
-Hash.AddTemplateArgument(TA);
-return Hash.CalculateHash();
-  };
-
-  auto ComputeTemplateParameterListODRHash =
-  [](const TemplateParameterList *TPL) {
-assert(TPL);
-Hash.clear();
-Hash.AddTemplateParameterList(TPL);
-return Hash.CalculateHash();
-  };
-
   // Used with err_module_odr_violation_mismatch_decl and
   // note_module_odr_violation_mismatch_decl
   // This list should be the same Decl's as in ODRHash::isDeclToBeProcessed
@@ -9639,49 +9628,13 @@ void ASTReader::diagnoseOdrViolations() {
 Other
   };
 
-  // Used with err_module_odr_violation_record and
-  // note_module_odr_violation_record
-  enum ODRCXXRecordDifference {
-StaticAssertCondition,
-StaticAssertMessage,
-StaticAssertOnlyMessage,
-MethodName,
-MethodDeleted,
-MethodDefaulted,
-MethodVirtual,
-MethodStatic,
-MethodVolatile,
-MethodConst,
-MethodInline,
-MethodNumberParameters,
-MethodParameterType,
-MethodParameterName,
-MethodParameterSingleDefaultArgument,
-MethodParameterDifferentDefaultArgument,
-MethodNoTemplateArguments,
-MethodDifferentNumberTemplateArguments,
-MethodDifferentTemplateArgument,
-MethodSingleBody,
-MethodDifferentBody,
-FriendTypeFunction,
-FriendType,
-FriendFunction,
-FunctionTemplateDifferentNumberParameters,
-FunctionTemplateParameterDifferentKind,
-FunctionTemplateParameterName,
-FunctionTemplateParameterSingleDefaultArgument,
-FunctionTemplateParameterDifferentDefaultArgument,
-FunctionTemplateParameterDifferentType,
-FunctionTemplatePackParameter,
-  };
-
   // These lambdas have the common portions of the ODR diagnostics.  This
   // has the same return as Diag(), so addition parameters can be passed
   // in with operator<<
-  auto ODRDiagField = [this, , ](
-  NamedDecl *FirstRecord, StringRef FirstModule,
-  StringRef SecondModule, FieldDecl *FirstField,
-  FieldDecl *SecondField) {
+  auto ODRDiagField = [this](NamedDecl *FirstRecord, StringRef FirstModule,
+ StringRef SecondModule,
+ const 

[clang] 2ceb9c3 - [ODRHash diagnostics] Move common code for calculating diag locations in `DiagnoseODRMismatch` into a lambda. NFC.

2022-06-30 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-06-30T19:39:22-07:00
New Revision: 2ceb9c347f14e81a8c71d644724cefd10fce6eaf

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

LOG: [ODRHash diagnostics] Move common code for calculating diag locations in 
`DiagnoseODRMismatch` into a lambda. NFC.

Differential Revision: https://reviews.llvm.org/D128489

Added: 


Modified: 
clang/lib/Serialization/ASTReader.cpp

Removed: 




diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 37371eff28ef..d853805bf97e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -10012,34 +10012,35 @@ void ASTReader::diagnoseOdrViolations() {
 }
   };
 
-  auto DiagnoseODRMismatch =
-  [this](DiffResult , NamedDecl *FirstRecord, StringRef FirstModule,
- NamedDecl *SecondRecord, StringRef SecondModule) {
-SourceLocation FirstLoc;
-SourceRange FirstRange;
-auto *FirstTag = dyn_cast(FirstRecord);
-if (DR.FirstDiffType == EndOfClass && FirstTag) {
-  FirstLoc = FirstTag->getBraceRange().getEnd();
-} else {
-  FirstLoc = DR.FirstDecl->getLocation();
-  FirstRange = DR.FirstDecl->getSourceRange();
-}
-Diag(FirstLoc, diag::err_module_odr_violation_mismatch_decl)
-<< FirstRecord << FirstModule.empty() << FirstModule << FirstRange
-<< DR.FirstDiffType;
-
-SourceLocation SecondLoc;
-SourceRange SecondRange;
-auto *SecondTag = dyn_cast(SecondRecord);
-if (DR.SecondDiffType == EndOfClass && SecondTag) {
-  SecondLoc = SecondTag->getBraceRange().getEnd();
-} else {
-  SecondLoc = DR.SecondDecl->getLocation();
-  SecondRange = DR.SecondDecl->getSourceRange();
-}
-Diag(SecondLoc, diag::note_module_odr_violation_mismatch_decl)
-<< SecondModule << SecondRange << DR.SecondDiffType;
-  };
+  auto DiagnoseODRMismatch = [this](DiffResult , NamedDecl *FirstRecord,
+StringRef FirstModule,
+NamedDecl *SecondRecord,
+StringRef SecondModule) {
+auto GetMismatchedDeclLoc = [](const NamedDecl *Container,
+   ODRMismatchDecl DiffType, const Decl *D) {
+  SourceLocation Loc;
+  SourceRange Range;
+  auto *Tag = dyn_cast(Container);
+  if (DiffType == EndOfClass && Tag) {
+Loc = Tag->getBraceRange().getEnd();
+  } else {
+Loc = D->getLocation();
+Range = D->getSourceRange();
+  }
+  return std::make_pair(Loc, Range);
+};
+
+auto FirstDiagInfo =
+GetMismatchedDeclLoc(FirstRecord, DR.FirstDiffType, DR.FirstDecl);
+Diag(FirstDiagInfo.first, diag::err_module_odr_violation_mismatch_decl)
+<< FirstRecord << FirstModule.empty() << FirstModule
+<< FirstDiagInfo.second << DR.FirstDiffType;
+
+auto SecondDiagInfo =
+GetMismatchedDeclLoc(SecondRecord, DR.SecondDiffType, DR.SecondDecl);
+Diag(SecondDiagInfo.first, diag::note_module_odr_violation_mismatch_decl)
+<< SecondModule << SecondDiagInfo.second << DR.SecondDiffType;
+  };
 
   // Issue any pending ODR-failure diagnostics.
   for (auto  : OdrMergeFailures) {



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


[clang] 15cb180 - [ODRHash diagnostics] Split `err_module_odr_violation_mismatch_decl_diff` into per-entity diagnostics. NFC.

2022-06-30 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-06-30T18:40:46-07:00
New Revision: 15cb180dcbf84701f3af47983e223d0beaac3c9b

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

LOG: [ODRHash diagnostics] Split `err_module_odr_violation_mismatch_decl_diff` 
into per-entity diagnostics. NFC.

We'll need to add more cases for Objective-C entities and adding
everything to `err_module_odr_violation_mismatch_decl_diff` makes it
harder to work with over time.

Differential Revision: https://reviews.llvm.org/D128488

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticSerializationKinds.td
clang/lib/Serialization/ASTReader.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td 
b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 251242e46fe5..0bd3734a4a04 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -177,20 +177,13 @@ def note_module_odr_violation_mismatch_decl : Note<"but 
in '%0' found "
   "protected access specifier|static assert|field|method|type alias|typedef|"
   "data member|friend declaration|function template}1">;
 
-def err_module_odr_violation_mismatch_decl_
diff  : Error<
+def err_module_odr_violation_record : Error<
   "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
   "%select{definition in module '%2'|defined here}1 found "
   "%select{"
   "static assert with condition|"
   "static assert with message|"
   "static assert with %select{|no }4message|"
-  "field %4|"
-  "field %4 with type %5|"
-  "%select{non-|}5bitfield %4|"
-  "bitfield %4 with one width expression|"
-  "%select{non-|}5mutable field %4|"
-  "field %4 with %select{no|an}5 initalizer|"
-  "field %4 with an initializer|"
   "%select{method %5|constructor|destructor}4|"
   "%select{method %5|constructor|destructor}4 "
 "is %select{not deleted|deleted}6|"
@@ -226,13 +219,6 @@ def err_module_odr_violation_mismatch_decl_
diff  : Error<
 "with %select{no body|body}6|"
   "%select{method %5|constructor|destructor}4 "
 "with body|"
-  "%select{typedef|type alias}4 name %5|"
-  "%select{typedef|type alias}4 %5 with underlying type %6|"
-  "data member with name %4|"
-  "data member %4 with type %5|"
-  "data member %4 with%select{out|}5 an initializer|"
-  "data member %4 with an initializer|"
-  "data member %4 %select{is constexpr|is not constexpr}5|"
   "friend %select{class|function}4|"
   "friend %4|"
   "friend function %4|"
@@ -250,18 +236,11 @@ def err_module_odr_violation_mismatch_decl_
diff  : Error<
 "being a template parameter pack|"
   "}3">;
 
-def note_module_odr_violation_mismatch_decl_
diff  : Note<"but in '%0' found "
+def note_module_odr_violation_record : Note<"but in '%0' found "
   "%select{"
   "static assert with 
diff erent condition|"
   "static assert with 
diff erent message|"
   "static assert with %select{|no }2message|"
-  "field %2|"
-  "field %2 with type %3|"
-  "%select{non-|}3bitfield %2|"
-  "bitfield %2 with 
diff erent width expression|"
-  "%select{non-|}3mutable field %2|"
-  "field %2 with %select{no|an}3 initializer|"
-  "field %2 with a 
diff erent initializer|"
   "%select{method %3|constructor|destructor}2|"
   "%select{method %3|constructor|destructor}2 "
 "is %select{not deleted|deleted}4|"
@@ -297,13 +276,6 @@ def note_module_odr_violation_mismatch_decl_
diff  : Note<"but in '%0' found "
 "with %select{no body|body}4|"
   "%select{method %3|constructor|destructor}2 "
 "with 
diff erent body|"
-  "%select{typedef|type alias}2 name %3|"
-  "%select{typedef|type alias}2 %3 with 
diff erent underlying type %4|"
-  "data member with name %2|"
-  "data member %2 with 
diff erent type %3|"
-  "data member %2 with%select{out|}3 an initializer|"
-  "data member %2 with a 
diff erent initializer|"
-  "data member %2 %select{is constexpr|is not constexpr}3|"
   "friend %select{class|function}2|"
   "friend %2|"
   "friend function %2|"
@@ -321,6 +293,61 @@ def note_module_odr_violation_mismatch_decl_
diff  : Note<"but in '%0' found "
 "being a template parameter pack|"
   "}1">;
 
+def err_module_odr_violation_field : Error<
+  "%q0 has 
diff erent definitions in 
diff erent modules; first 
diff erence is "
+  "%select{definition in module '%2'|defined here}1 found "
+  "%select{"
+  "field %4|"
+  "field %4 with type %5|"
+  "%select{non-|}5bitfield %4|"
+  "bitfield %4 with one width expression|"
+  "%select{non-|}5mutable field %4|"
+  "field %4 with %select{no|an}5 initalizer|"
+  "field %4 with an initializer"
+  "}3">;
+def note_module_odr_violation_field : Note<"but in '%0' found "
+  "%select{"
+  "field %2|"
+  "field %2 with type %3|"
+  "%select{non-|}3bitfield %2|"

[clang] 3514131 - [ODRHash diagnostics] Fix typos. NFC.

2022-06-29 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-06-29T14:59:37-07:00
New Revision: 3514131219ffdc94c0c61c5b585b53e97501fbea

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

LOG: [ODRHash diagnostics] Fix typos. NFC.

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticSerializationKinds.td
clang/lib/Serialization/ASTReader.cpp
clang/test/Modules/odr_hash.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td 
b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 33eba6cf0c3f2..251242e46fe5d 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -355,7 +355,7 @@ def err_module_odr_violation_enum : Error<
   "enum with specified type %4|"
   "enum with %4 element%s4|"
   "%ordinal4 element has name %5|"
-  "%ordinal4 element %5 %select{has|does not have}6 an initilizer|"
+  "%ordinal4 element %5 %select{has|does not have}6 an initializer|"
   "%ordinal4 element %5 has an initializer|"
   "}3">;
 

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index f15e0bcce3318..6bfd81634f50b 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -10636,7 +10636,7 @@ void ASTReader::diagnoseOdrViolations() {
 
 // Compare the hash generated to the hash stored.  A 
diff erence means
 // that a body was present in the original source.  Due to merging,
-// the stardard way of detecting a body will not work.
+// the standard way of detecting a body will not work.
 const bool HasFirstBody =
 ComputeCXXMethodODRHash(FirstMethod) != FirstMethod->getODRHash();
 const bool HasSecondBody =
@@ -11166,8 +11166,8 @@ void ASTReader::diagnoseOdrViolations() {
   DifferentSpecifiedTypes,
   DifferentNumberEnumConstants,
   EnumConstantName,
-  EnumConstantSingleInitilizer,
-  EnumConstantDifferentInitilizer,
+  EnumConstantSingleInitializer,
+  EnumConstantDifferentInitializer,
 };
 
 // If we've already pointed out a specific problem with this enum, don't
@@ -11301,18 +11301,18 @@ void ASTReader::diagnoseOdrViolations() {
   continue;
 
 if (!FirstInit || !SecondInit) {
-  ODRDiagError(FirstEnumConstant, EnumConstantSingleInitilizer)
+  ODRDiagError(FirstEnumConstant, EnumConstantSingleInitializer)
   << I + 1 << FirstEnumConstant << (FirstInit != nullptr);
-  ODRDiagNote(SecondEnumConstant, EnumConstantSingleInitilizer)
+  ODRDiagNote(SecondEnumConstant, EnumConstantSingleInitializer)
   << I + 1 << SecondEnumConstant << (SecondInit != nullptr);
   Diagnosed = true;
   break;
 }
 
 if (ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {
-  ODRDiagError(FirstEnumConstant, EnumConstantDifferentInitilizer)
+  ODRDiagError(FirstEnumConstant, EnumConstantDifferentInitializer)
   << I + 1 << FirstEnumConstant;
-  ODRDiagNote(SecondEnumConstant, EnumConstantDifferentInitilizer)
+  ODRDiagNote(SecondEnumConstant, EnumConstantDifferentInitializer)
   << I + 1 << SecondEnumConstant;
   Diagnosed = true;
   break;

diff  --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp
index 81899943bc64c..aed08c1a3a044 100644
--- a/clang/test/Modules/odr_hash.cpp
+++ b/clang/test/Modules/odr_hash.cpp
@@ -3300,7 +3300,7 @@ enum E7 { x71 = 0 };
 enum E7 { x71 };
 #else
 E7 e7;
-// expected-error@second.h:* {{'Enums::E7' has 
diff erent definitions in 
diff erent modules; definition in module 'SecondModule' first 
diff erence is 1st element 'x71' has an initilizer}}
+// expected-error@second.h:* {{'Enums::E7' has 
diff erent definitions in 
diff erent modules; definition in module 'SecondModule' first 
diff erence is 1st element 'x71' has an initializer}}
 // expected-note@first.h:* {{but in 'FirstModule' found 1st element 'x71' does 
not have an initializer}}
 #endif
 
@@ -3310,7 +3310,7 @@ enum E8 { x81 };
 enum E8 { x81 = 0 };
 #else
 E8 e8;
-// expected-error@second.h:* {{'Enums::E8' has 
diff erent definitions in 
diff erent modules; definition in module 'SecondModule' first 
diff erence is 1st element 'x81' does not have an initilizer}}
+// expected-error@second.h:* {{'Enums::E8' has 
diff erent definitions in 
diff erent modules; definition in module 'SecondModule' first 
diff erence is 1st element 'x81' does not have an initializer}}
 // expected-note@first.h:* {{but in 'FirstModule' found 1st element 'x81' has 
an initializer}}
 #endif
 



___
cfe-commits 

[clang] 017c068 - [ODRHash diagnostics] Move repetetive code at lambda calls into lambdas themselves. NFC.

2022-06-29 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-06-29T13:24:55-07:00
New Revision: 017c068f7899b895e654c8efc1c4d02d940dbf8a

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

LOG: [ODRHash diagnostics] Move repetetive code at lambda calls into lambdas 
themselves. NFC.

It helps to avoid copy-paste mistakes and makes custom code paths more
noticeable.

Not funnelling all diagnostic through `ODRDiagDeclError` because plan to
break down `err_module_odr_violation_mismatch_decl_diff` into smaller
pieces instead of making it bigger and bigger.

Differential Revision: https://reviews.llvm.org/D128487

Added: 


Modified: 
clang/lib/Serialization/ASTReader.cpp

Removed: 




diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 36d7f4186af68..f15e0bcce3318 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9690,34 +9690,29 @@ void ASTReader::diagnoseOdrViolations() {
   // These lambdas have the common portions of the ODR diagnostics.  This
   // has the same return as Diag(), so addition parameters can be passed
   // in with operator<<
-  auto ODRDiagDeclError = [this](NamedDecl *FirstRecord, StringRef FirstModule,
- SourceLocation Loc, SourceRange Range,
- ODRMismatchDeclDifference DiffType) {
-return Diag(Loc, diag::err_module_odr_violation_mismatch_decl_
diff )
-   << FirstRecord << FirstModule.empty() << FirstModule << Range
-   << DiffType;
-  };
-  auto ODRDiagDeclNote = [this](StringRef SecondModule, SourceLocation Loc,
-SourceRange Range, ODRMismatchDeclDifference 
DiffType) {
-return Diag(Loc, diag::note_module_odr_violation_mismatch_decl_
diff )
-   << SecondModule << Range << DiffType;
-  };
-
-  auto ODRDiagField = [this, , ,
-   , ](
+  auto ODRDiagField = [this, , ](
   NamedDecl *FirstRecord, StringRef FirstModule,
   StringRef SecondModule, FieldDecl *FirstField,
   FieldDecl *SecondField) {
+auto DiagError = [FirstRecord, FirstField, FirstModule,
+  this](ODRMismatchDeclDifference DiffType) {
+  return Diag(FirstField->getLocation(),
+  diag::err_module_odr_violation_mismatch_decl_
diff )
+ << FirstRecord << FirstModule.empty() << FirstModule
+ << FirstField->getSourceRange() << DiffType;
+};
+auto DiagNote = [SecondField, SecondModule,
+ this](ODRMismatchDeclDifference DiffType) {
+  return Diag(SecondField->getLocation(),
+  diag::note_module_odr_violation_mismatch_decl_
diff )
+ << SecondModule << SecondField->getSourceRange() << DiffType;
+};
+
 IdentifierInfo *FirstII = FirstField->getIdentifier();
 IdentifierInfo *SecondII = SecondField->getIdentifier();
 if (FirstII->getName() != SecondII->getName()) {
-  ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(),
-   FirstField->getSourceRange(), FieldName)
-  << FirstII;
-  ODRDiagDeclNote(SecondModule, SecondField->getLocation(),
-  SecondField->getSourceRange(), FieldName)
-  << SecondII;
-
+  DiagError(FieldName) << FirstII;
+  DiagNote(FieldName) << SecondII;
   return true;
 }
 
@@ -9728,25 +9723,16 @@ void ASTReader::diagnoseOdrViolations() {
 QualType SecondType = SecondField->getType();
 if (ComputeQualTypeODRHash(FirstType) !=
 ComputeQualTypeODRHash(SecondType)) {
-  ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(),
-   FirstField->getSourceRange(), FieldTypeName)
-  << FirstII << FirstType;
-  ODRDiagDeclNote(SecondModule, SecondField->getLocation(),
-  SecondField->getSourceRange(), FieldTypeName)
-  << SecondII << SecondType;
-
+  DiagError(FieldTypeName) << FirstII << FirstType;
+  DiagNote(FieldTypeName) << SecondII << SecondType;
   return true;
 }
 
 const bool IsFirstBitField = FirstField->isBitField();
 const bool IsSecondBitField = SecondField->isBitField();
 if (IsFirstBitField != IsSecondBitField) {
-  ODRDiagDeclError(FirstRecord, FirstModule, FirstField->getLocation(),
-   FirstField->getSourceRange(), FieldSingleBitField)
-  << FirstII << IsFirstBitField;
-  ODRDiagDeclNote(SecondModule, SecondField->getLocation(),
-  SecondField->getSourceRange(), FieldSingleBitField)
-  << SecondII << IsSecondBitField;
+  DiagError(FieldSingleBitField) << FirstII << 

[clang] f3defc2 - [ODRHash][NFC] Add missing 'select' case for `ODRMismatchDecl`.

2022-05-30 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-05-30T10:07:03-07:00
New Revision: f3defc23488eb29c69d2a33c0c5b652c874fb0f3

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

LOG: [ODRHash][NFC] Add missing 'select' case for `ODRMismatchDecl`.

No test changes because `err_module_odr_violation_mismatch_decl_unknown`
is a catch-all when custom diagnostic is missing. And missing custom
diagnostic we should fix by implementing it, not by improving the
general case. But if we pass enum value not covered by 'select', clang
can crash, so protect against that.

Differential Revision: https://reviews.llvm.org/D126566

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticSerializationKinds.td

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td 
b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 3fcdb616bd21a..33eba6cf0c3f2 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -375,12 +375,14 @@ def err_module_odr_violation_mismatch_decl_unknown : 
Error<
   "%q0 %select{with definition in module '%2'|defined here}1 has 
diff erent "
   "definitions in 
diff erent modules; first 
diff erence is this "
   "%select{static assert|field|method|type alias|typedef|data member|"
-  "friend declaration|unexpected decl}3">;
+  "friend declaration|function template|"
+  "unexpected decl}3">;
 def note_module_odr_violation_mismatch_decl_unknown : Note<
   "but in '%0' found "
   "%select{
diff erent static assert|
diff erent field|
diff erent method|"
   "
diff erent type alias|
diff erent typedef|
diff erent data member|"
-  "
diff erent friend declaration|another unexpected decl}1">;
+  "
diff erent friend declaration|
diff erent function template|"
+  "another unexpected decl}1">;
 
 def warn_duplicate_module_file_extension : Warning<
   "duplicate module file extension block name '%0'">,



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


[clang] 3b762b3 - [clang][NFC] In parts of Objective-C Sema use Obj-C-specific types instead of `Decl`.

2022-05-05 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-05-05T19:19:41-07:00
New Revision: 3b762b3ab8d205cd6a7d42c96d39d5f4f701f2ab

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

LOG: [clang][NFC] In parts of Objective-C Sema use Obj-C-specific types instead 
of `Decl`.

Differential Revision: https://reviews.llvm.org/D124285

Added: 


Modified: 
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseObjc.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclObjC.cpp

Removed: 




diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 8f28eb30ad1dc..99fe375f9145f 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -447,7 +447,9 @@ class Parser : public CodeCompletionHandler {
 return Actions.incrementMSManglingNumber();
   }
 
-  Decl  *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
+  ObjCContainerDecl *getObjCDeclContext() const {
+return Actions.getObjCDeclContext();
+  }
 
   // Type forwarding.  All of these are statically 'void*', but they may all be
   // 
diff erent actual classes based on the actions in place.
@@ -1001,18 +1003,18 @@ class Parser : public CodeCompletionHandler {
   /// back.
   class ObjCDeclContextSwitch {
 Parser 
-Decl *DC;
+ObjCContainerDecl *DC;
 SaveAndRestore WithinObjCContainer;
   public:
 explicit ObjCDeclContextSwitch(Parser )
   : P(p), DC(p.getObjCDeclContext()),
 WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
   if (DC)
-
P.Actions.ActOnObjCTemporaryExitContainerContext(cast(DC));
+P.Actions.ActOnObjCTemporaryExitContainerContext(DC);
 }
 ~ObjCDeclContextSwitch() {
   if (DC)
-P.Actions.ActOnObjCReenterContainerContext(cast(DC));
+P.Actions.ActOnObjCReenterContainerContext(DC);
 }
   };
 
@@ -1614,11 +1616,12 @@ class Parser : public CodeCompletionHandler {
   SmallVectorImpl ,
   SourceLocation , bool mayBeProtocolList = true);
 
-  void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation 
atLoc,
+  void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
+SourceLocation atLoc,
 BalancedDelimiterTracker ,
 SmallVectorImpl ,
 bool RBraceMissing);
-  void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
+  void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
tok::ObjCKeywordKind visibility,
SourceLocation atLoc);
   bool ParseObjCProtocolReferences(SmallVectorImpl ,

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 44fbffdda3900..27603f0b891f3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3285,7 +3285,7 @@ class Sema final {
   /// Invoked when we enter a tag definition that we're skipping.
   SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD);
 
-  Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
+  void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl);
 
   /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
   /// C++ record definition's base-specifiers clause and are starting its
@@ -3309,8 +3309,8 @@ class Sema final {
   /// scope for parsing/looking-up C constructs.
   ///
   /// Must be followed by a call to \see ActOnObjCReenterContainerContext
-  void ActOnObjCTemporaryExitContainerContext(DeclContext *DC);
-  void ActOnObjCReenterContainerContext(DeclContext *DC);
+  void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx);
+  void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx);
 
   /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
   /// error parsing the definition of a tag.
@@ -9738,7 +9738,7 @@ class Sema final {
 SourceLocation rAngleLoc);
   void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList);
 
-  Decl *ActOnStartClassInterface(
+  ObjCInterfaceDecl *ActOnStartClassInterface(
   Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
   SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
   IdentifierInfo *SuperName, SourceLocation SuperLoc,
@@ -9772,13 +9772,13 @@ class Sema final {
 SourceLocation , SourceLocation PrevLoc,
 const ObjCList );
 
-  Decl *ActOnStartProtocolInterface(
+  ObjCProtocolDecl *ActOnStartProtocolInterface(
   SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName,

[clang] d32c685 - [modules] Merge equivalent extensions and diagnose ivar redeclarations for extensions loaded from different modules.

2022-04-27 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-04-27T15:52:59-07:00
New Revision: d32c685e1012785c0d2824214740f973d30e1daa

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

LOG: [modules] Merge equivalent extensions and diagnose ivar redeclarations for 
extensions loaded from different modules.

Emitting metadata for the same ivar multiple times can lead to
miscompilations. Objective-C runtime adds offsets to calculate ivar
position in memory and presence of duplicate offsets causes wrong final
position thus overwriting unrelated memory.

Such a situation is impossible with modules disabled as clang diagnoses
ivar redeclarations during sema checks after parsing
(`Sema::ActOnFields`). Fix the case with modules enabled by checking
during deserialization if ivar is already declared. We also support
a use case where the same category ends up in multiple modules. We
don't want to treat this case as ivar redeclaration and instead merge
corresponding ivars.

rdar://83468070

Differential Revision: https://reviews.llvm.org/D121177

Added: 
clang/test/Modules/merge-extension-ivars.m
clang/test/Modules/redecl-ivars.m

Modified: 
clang/include/clang/AST/DeclObjC.h
clang/include/clang/Serialization/ASTReader.h
clang/lib/AST/DeclObjC.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp

Removed: 




diff  --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 110b7dc0c6f2..59a2cf5de234 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1951,7 +1951,10 @@ class ObjCIvarDecl : public FieldDecl {
   /// in; this is either the interface where the ivar was declared, or the
   /// interface the ivar is conceptually a part of in the case of synthesized
   /// ivars.
-  const ObjCInterfaceDecl *getContainingInterface() const;
+  ObjCInterfaceDecl *getContainingInterface();
+  const ObjCInterfaceDecl *getContainingInterface() const {
+return const_cast(this)->getContainingInterface();
+  }
 
   ObjCIvarDecl *getNextIvar() { return NextIvar; }
   const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
@@ -2885,15 +2888,16 @@ 
ObjCInterfaceDecl::filtered_category_iterator::operator++() {
 }
 
 inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
-  return Cat->isUnconditionallyVisible();
+  return !Cat->isInvalidDecl() && Cat->isUnconditionallyVisible();
 }
 
 inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
-  return Cat->IsClassExtension() && Cat->isUnconditionallyVisible();
+  return !Cat->isInvalidDecl() && Cat->IsClassExtension() &&
+ Cat->isUnconditionallyVisible();
 }
 
 inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
-  return Cat->IsClassExtension();
+  return !Cat->isInvalidDecl() && Cat->IsClassExtension();
 }
 
 } // namespace clang

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index d46a6c4500f4..8e8e40a5cd37 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1106,6 +1106,18 @@ class ASTReader
   /// been completed.
   std::deque PendingDeclContextInfos;
 
+  template 
+  using DuplicateObjCDecls = std::pair;
+
+  /// When resolving duplicate ivars from Objective-C extensions we don't error
+  /// out immediately but check if can merge identical extensions. Not checking
+  /// extensions for equality immediately because ivar deserialization isn't
+  /// over yet at that point.
+  llvm::SmallMapVector,
+   llvm::SmallVector, 4>,
+   2>
+  PendingObjCExtensionIvarRedeclarations;
+
   /// The set of NamedDecls that have been loaded, but are members of a
   /// context that has been merged into another context where the corresponding
   /// declaration is either missing or has not yet been loaded.

diff  --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index f15dd78929e2..15c545b59c81 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -1647,6 +1647,11 @@ ObjCIvarDecl 
*ObjCInterfaceDecl::all_declared_ivar_begin() {
 
   ObjCIvarDecl *curIvar = nullptr;
   if (!data().IvarList) {
+// Force ivar deserialization upfront, before building IvarList.
+(void)ivar_empty();
+for (const auto *Ext : known_extensions()) {
+  (void)Ext->ivar_empty();
+}
 if (!ivar_empty()) {
   ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
   data().IvarList = *I; ++I;
@@ -1838,8 +1843,8 @@ ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext 
, unsigned ID) {
   ObjCIvarDecl::None, nullptr, false);
 }
 
-const 

[clang] a7f9f2f - [fixup] Handle enum constant `Lang_OBJC` introduced in 4604db94.

2022-04-22 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-04-22T17:59:17-07:00
New Revision: a7f9f2fea506fa213e4ce9c6230a816cd5bcfa38

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

LOG: [fixup] Handle enum constant `Lang_OBJC` introduced in 4604db94.

Added: 


Modified: 
clang/lib/Testing/CommandLineArgs.cpp

Removed: 




diff  --git a/clang/lib/Testing/CommandLineArgs.cpp 
b/clang/lib/Testing/CommandLineArgs.cpp
index c04702f689028..bf517e2dd312e 100644
--- a/clang/lib/Testing/CommandLineArgs.cpp
+++ b/clang/lib/Testing/CommandLineArgs.cpp
@@ -72,6 +72,9 @@ std::vector getCC1ArgsForTesting(TestLanguage 
Lang) {
   case Lang_CXX20:
 Args = {"-std=c++20"};
 break;
+  case Lang_OBJC:
+Args = {"-xobjective-c"};
+break;
   case Lang_OBJCXX:
 Args = {"-xobjective-c++"};
 break;



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


[clang] 4604db9 - [ASTStructuralEquivalence] Add support for comparing ObjCCategoryDecl.

2022-04-22 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-04-22T16:51:19-07:00
New Revision: 4604db9493ffb22e1f411d907f163bf021193d84

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

LOG: [ASTStructuralEquivalence] Add support for comparing ObjCCategoryDecl.

Differential Revision: https://reviews.llvm.org/D121176

Added: 


Modified: 
clang/include/clang/Testing/CommandLineArgs.h
clang/lib/AST/ASTStructuralEquivalence.cpp
clang/lib/Testing/CommandLineArgs.cpp
clang/unittests/AST/MatchVerifier.h
clang/unittests/AST/StructuralEquivalenceTest.cpp

Removed: 




diff  --git a/clang/include/clang/Testing/CommandLineArgs.h 
b/clang/include/clang/Testing/CommandLineArgs.h
index fe2103a3dce21..e668781ee2ce1 100644
--- a/clang/include/clang/Testing/CommandLineArgs.h
+++ b/clang/include/clang/Testing/CommandLineArgs.h
@@ -29,6 +29,7 @@ enum TestLanguage {
   Lang_CXX17,
   Lang_CXX20,
   Lang_OpenCL,
+  Lang_OBJC,
   Lang_OBJCXX
 };
 

diff  --git a/clang/lib/AST/ASTStructuralEquivalence.cpp 
b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 05f3470a179d2..b15036a11ad92 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1242,10 +1242,10 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   return true;
 }
 
-/// Determine structural equivalence of two fields.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
- FieldDecl *Field1, FieldDecl *Field2) {
-  const auto *Owner2 = cast(Field2->getDeclContext());
+ FieldDecl *Field1, FieldDecl *Field2,
+ QualType Owner2Type) {
+  const auto *Owner2 = cast(Field2->getDeclContext());
 
   // For anonymous structs/unions, match up the anonymous struct/union type
   // declarations directly, so that we don't go off searching for anonymous
@@ -1265,7 +1265,7 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   Context.Diag2(
   Owner2->getLocation(),
   Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
-  << Context.ToCtx.getTypeDeclType(Owner2);
+  << Owner2Type;
   Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
   << Field2->getDeclName();
   Context.Diag1(Field1->getLocation(), diag::note_odr_field_name)
@@ -1280,7 +1280,7 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   Context.Diag2(
   Owner2->getLocation(),
   Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
-  << Context.ToCtx.getTypeDeclType(Owner2);
+  << Owner2Type;
   Context.Diag2(Field2->getLocation(), diag::note_odr_field)
   << Field2->getDeclName() << Field2->getType();
   Context.Diag1(Field1->getLocation(), diag::note_odr_field)
@@ -1296,6 +1296,14 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   return true;
 }
 
+/// Determine structural equivalence of two fields.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ FieldDecl *Field1, FieldDecl *Field2) {
+  const auto *Owner2 = cast(Field2->getDeclContext());
+  return IsStructurallyEquivalent(Context, Field1, Field2,
+  Context.ToCtx.getTypeDeclType(Owner2));
+}
+
 /// Determine structural equivalence of two methods.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  CXXMethodDecl *Method1,
@@ -1610,6 +1618,7 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   }
 
   // Check the fields for consistency.
+  QualType D2Type = Context.ToCtx.getTypeDeclType(D2);
   RecordDecl::field_iterator Field2 = D2->field_begin(),
  Field2End = D2->field_end();
   for (RecordDecl::field_iterator Field1 = D1->field_begin(),
@@ -1628,7 +1637,7 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   return false;
 }
 
-if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
+if (!IsStructurallyEquivalent(Context, *Field1, *Field2, D2Type))
   return false;
   }
 
@@ -1934,6 +1943,126 @@ static bool 
IsStructurallyEquivalent(StructuralEquivalenceContext ,
   return true;
 }
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
+ ObjCIvarDecl *D1, ObjCIvarDecl *D2,
+ QualType Owner2Type) {
+  if (D1->getAccessControl() != D2->getAccessControl())
+return false;
+
+  return IsStructurallyEquivalent(Context, cast(D1),
+  cast(D2), Owner2Type);
+}
+
+static bool 

[clang] 29444f0 - [modules] Merge ObjC interface ivars with anonymous types.

2022-04-04 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-04-04T18:48:30-07:00
New Revision: 29444f0444c6d3586969fd6fbe49c8188c02c244

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

LOG: [modules] Merge ObjC interface ivars with anonymous types.

Without the fix ivars with anonymous types can trigger errors like

> error: 'TestClass::structIvar' from module 'Target' is not present in 
> definition of 'TestClass' provided earlier
> [...]
> note: declaration of 'structIvar' does not match

It happens because types of ivars from different modules are considered
to be different. And it is caused by not merging anonymous `TagDecl`
from different modules.

To fix that I've changed `serialization::needsAnonymousDeclarationNumber`
to handle anonymous `TagDecl` inside `ObjCInterfaceDecl`. But that's not
sufficient as C code inside `ObjCInterfaceDecl` doesn't use interface
decl as a decl context but switches to its parent (TranslationUnit in
most cases).  I'm changing that to make `ObjCContainerDecl` the lexical
decl context but keeping the semantic decl context intact.

Test "check-dup-decls-inside-objc.m" doesn't reflect a change in
functionality but captures the existing behavior to prevent regressions.

rdar://85563013

Differential Revision: https://reviews.llvm.org/D118525

Added: 
clang/test/Modules/merge-anon-record-definition-in-objc.m
clang/test/SemaObjC/check-dup-decls-inside-objc.m

Modified: 
clang/lib/Parse/ParseObjc.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Serialization/ASTCommon.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/AST/ast-dump-decl.mm

Removed: 




diff  --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 719513e7bda09..c56fcb8cc3cfe 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -1871,9 +1871,9 @@ void Parser::HelperActionsForIvarDeclarations(Decl 
*interfaceDecl, SourceLocatio
   if (!RBraceMissing)
 T.consumeClose();
 
-  Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
+  assert(getObjCDeclContext() == interfaceDecl &&
+ "Ivars should have interfaceDecl as their decl context");
   Actions.ActOnLastBitfield(T.getCloseLocation(), AllIvarDecls);
-  Actions.ActOnObjCContainerFinishDefinition();
   // Call ActOnFields() even if we don't have any decls. This is useful
   // for code rewriting tools that need to be aware of the empty list.
   Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, AllIvarDecls,
@@ -1908,8 +1908,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl 
*interfaceDecl,
   assert(Tok.is(tok::l_brace) && "expected {");
   SmallVector AllIvarDecls;
 
-  ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
-  ObjCDeclContextSwitch ObjCDC(*this);
+  ParseScope ClassScope(this, Scope::DeclScope | Scope::ClassScope);
 
   BalancedDelimiterTracker T(*this, tok::l_brace);
   T.consumeOpen();
@@ -1973,13 +1972,13 @@ void Parser::ParseObjCClassInstanceVariables(Decl 
*interfaceDecl,
 }
 
 auto ObjCIvarCallback = [&](ParsingFieldDeclarator ) {
-  Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
+  assert(getObjCDeclContext() == interfaceDecl &&
+ "Ivar should have interfaceDecl as its decl context");
   // Install the declarator into the interface decl.
   FD.D.setObjCIvar(true);
   Decl *Field = Actions.ActOnIvar(
   getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D,
   FD.BitfieldSize, visibility);
-  Actions.ActOnObjCContainerFinishDefinition();
   if (Field)
 AllIvarDecls.push_back(Field);
   FD.complete(Field);

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1e25346fde6f6..0b5b530bc756c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16059,9 +16059,20 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, 
TagUseKind TUK,
   // with C structs, unions, and enums when looking for a matching
   // tag declaration or definition. See the similar lookup tweak
   // in Sema::LookupName; is there a better way to deal with this?
-  while (isa(SearchDC) || isa(SearchDC))
+  while (isa(SearchDC))
+SearchDC = SearchDC->getParent();
+} else if (getLangOpts().CPlusPlus) {
+  // Inside ObjCContainer want to keep it as a lexical decl context but go
+  // past it (most often to TranslationUnit) to find the semantic decl
+  // context.
+  while (isa(SearchDC))
 SearchDC = SearchDC->getParent();
 }
+  } else if (getLangOpts().CPlusPlus) {
+// Don't use ObjCContainerDecl as the semantic decl context for anonymous
+// TagDecl the same way as we skip it for named TagDecl.
+while (isa(SearchDC))
+  SearchDC = 

[clang] a621b0a - [clang][NFC] Remove unused parameter in `Sema::ActOnDuplicateDefinition`.

2022-03-28 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-03-28T12:07:28-07:00
New Revision: a621b0af9cd03bce079a2a6f4d72a6471ca1bb85

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

LOG: [clang][NFC] Remove unused parameter in `Sema::ActOnDuplicateDefinition`.

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Sema/SemaDecl.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 817df4e108433..53ac1d011d9e1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3254,8 +3254,7 @@ class Sema final {
   /// Perform ODR-like check for C/ObjC when merging tag types from modules.
   /// Differently from C++, actually parse the body and reject / error out
   /// in case of a structural mismatch.
-  bool ActOnDuplicateDefinition(DeclSpec , Decl *Prev,
-SkipBodyInfo );
+  bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo );
 
   typedef void *SkippedDefinitionContext;
 

diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index c0fb7e0df1b61..f07758197205f 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4870,7 +4870,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, 
DeclSpec ,
 Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;
 ParseEnumBody(StartLoc, D);
 if (SkipBody.CheckSameAsPrevious &&
-!Actions.ActOnDuplicateDefinition(DS, TagDecl, SkipBody)) {
+!Actions.ActOnDuplicateDefinition(TagDecl, SkipBody)) {
   DS.SetTypeSpecError();
   return;
 }

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp 
b/clang/lib/Parse/ParseDeclCXX.cpp
index 1bb43f56422d7..342ee896bee18 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2049,8 +2049,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind 
TagTokKind,
   // Parse the definition body.
   ParseStructUnionBody(StartLoc, TagType, cast(D));
   if (SkipBody.CheckSameAsPrevious &&
-  !Actions.ActOnDuplicateDefinition(DS, TagOrTempResult.get(),
-SkipBody)) {
+  !Actions.ActOnDuplicateDefinition(TagOrTempResult.get(), SkipBody)) {
 DS.SetTypeSpecError();
 return;
   }

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4051ab29fb26f..298d4fc17617b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16703,8 +16703,7 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl 
*TagD) {
   AddPushedVisibilityAttribute(Tag);
 }
 
-bool Sema::ActOnDuplicateDefinition(DeclSpec , Decl *Prev,
-SkipBodyInfo ) {
+bool Sema::ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo ) {
   if (!hasStructuralCompatLayout(Prev, SkipBody.New))
 return false;
 



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


[clang] fa4a0f1 - [modules] Add a flag for TagDecl if it was a definition demoted to a declaration.

2022-02-14 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2022-02-14T16:04:40-08:00
New Revision: fa4a0f1d31e2f797c3e27eb7cad15755e46a4726

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

LOG: [modules] Add a flag for TagDecl if it was a definition demoted to a 
declaration.

For redeclaration chains we maintain an invariant of having only a
single definition in the chain. In a single translation unit we make
sure not to create duplicates. But modules are separate translation
units and they can contain definitions for the same symbol
independently. When we load such modules together, we need to demote
duplicate definitions to keep the AST invariants.

Some AST clients are interested in distinguishing
declaration-that-was-demoted-from-definition and
declaration-that-was-never-a-definition. For that purpose introducing
`IsThisDeclarationADemotedDefinition`. No functional change intended.

rdar://84677782

Differential Revision: https://reviews.llvm.org/D118855

Added: 


Modified: 
clang/include/clang/AST/Decl.h
clang/include/clang/AST/DeclBase.h
clang/lib/AST/Decl.cpp
clang/lib/Serialization/ASTReaderDecl.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 862e8899d2751..7611bac83419d 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -3486,6 +3486,24 @@ class TagDecl : public TypeDecl,
   /// parameters.
   bool isDependentType() const { return isDependentContext(); }
 
+  /// Whether this declaration was a definition in some module but was forced
+  /// to be a declaration.
+  ///
+  /// Useful for clients checking if a module has a definition of a specific
+  /// symbol and not interested in the final AST with deduplicated definitions.
+  bool isThisDeclarationADemotedDefinition() const {
+return TagDeclBits.IsThisDeclarationADemotedDefinition;
+  }
+
+  /// Mark a definition as a declaration and maintain information it _was_
+  /// a definition.
+  void demoteThisDefinitionToDeclaration() {
+assert(isCompleteDefinition() &&
+   "Should demote definitions only, not forward declarations");
+setCompleteDefinition(false);
+TagDeclBits.IsThisDeclarationADemotedDefinition = true;
+  }
+
   /// Starts the definition of this tag declaration.
   ///
   /// This method should be invoked at the beginning of the definition

diff  --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index 06d2f17d14300..a89f776248c1f 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -1443,10 +1443,14 @@ class DeclContext {
 /// Has the full definition of this type been required by a use somewhere 
in
 /// the TU.
 uint64_t IsCompleteDefinitionRequired : 1;
+
+/// Whether this tag is a definition which was demoted due to
+/// a module merge.
+uint64_t IsThisDeclarationADemotedDefinition : 1;
   };
 
   /// Number of non-inherited bits in TagDeclBitfields.
-  enum { NumTagDeclBits = 9 };
+  enum { NumTagDeclBits = 10 };
 
   /// Stores the bits used by EnumDecl.
   /// If modified NumEnumDeclBit and the accessor

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 060a6d1ad5ed5..030da7f55fac4 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4301,6 +4301,7 @@ TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext 
, DeclContext *DC,
   setEmbeddedInDeclarator(false);
   setFreeStanding(false);
   setCompleteDefinitionRequired(false);
+  TagDeclBits.IsThisDeclarationADemotedDefinition = false;
 }
 
 SourceLocation TagDecl::getOuterLocStart() const {

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 1ab26e58a4040..25d7e9e6a2e68 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -773,7 +773,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->setCompleteDefinition(false);
+  ED->demoteThisDefinitionToDeclaration();
   Reader.mergeDefinitionVisibility(OldDef, ED);
   if (OldDef->getODRHash() != ED->getODRHash())
 Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
@@ -828,7 +828,7 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(RD, OldDef));
-  RD->setCompleteDefinition(false);
+  RD->demoteThisDefinitionToDeclaration();
   Reader.mergeDefinitionVisibility(OldDef, RD);
 } else {
   OldDef = RD;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[clang] 7ad693a - [modules] Update visibility for merged ObjCProtocolDecl definitions.

2021-11-08 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-11-08T13:54:00-08:00
New Revision: 7ad693a322c1b6765f5d06559c2bd73cc3938aaf

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

LOG: [modules] Update visibility for merged ObjCProtocolDecl definitions.

Merge definition visibility the same way we do for other decls. Without
the fix the added test emits `-Wobjc-method-access` as it cannot find a
visible protocol. Make this warning `-Werror` so the test would fail
when protocol visibility regresses.

rdar://83600696

Differential Revision: https://reviews.llvm.org/D111860

Added: 
clang/test/Modules/merge-objc-protocol-visibility.m

Modified: 
clang/lib/Serialization/ASTReaderDecl.cpp

Removed: 




diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 2a617a4fec116..3e4a2416a3cd4 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1250,6 +1250,13 @@ void ASTDeclReader::ReadObjCDefinitionData(
 
 void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D,
  struct ObjCProtocolDecl::DefinitionData &) {
+  struct ObjCProtocolDecl::DefinitionData  = D->data();
+  if (DD.Definition != NewDD.Definition) {
+Reader.MergedDeclContexts.insert(
+std::make_pair(NewDD.Definition, DD.Definition));
+Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition);
+  }
+
   // FIXME: odr checking?
 }
 

diff  --git a/clang/test/Modules/merge-objc-protocol-visibility.m 
b/clang/test/Modules/merge-objc-protocol-visibility.m
new file mode 100644
index 0..04cf60b7e997a
--- /dev/null
+++ b/clang/test/Modules/merge-objc-protocol-visibility.m
@@ -0,0 +1,76 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m 
-Werror=objc-method-access -DHIDDEN_FIRST=1 \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m 
-Werror=objc-method-access -DHIDDEN_FIRST=0 \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+
+// Test a case when Objective-C protocol is imported both as hidden and as 
visible.
+
+//--- Frameworks/Foundation.framework/Headers/Foundation.h
+@interface NSObject
+@end
+
+//--- Frameworks/Foundation.framework/Modules/module.modulemap
+framework module Foundation {
+  header "Foundation.h"
+  export *
+}
+
+//--- Frameworks/Common.framework/Headers/Common.h
+#import 
+@protocol Testing;
+@interface Common : NSObject
+- (id)getProtocolObj;
+@end
+
+//--- Frameworks/Common.framework/Modules/module.modulemap
+framework module Common {
+  header "Common.h"
+  export *
+}
+
+//--- Frameworks/Regular.framework/Headers/Regular.h
+@protocol Testing
+- (void)protocolMethod;
+@end
+
+//--- Frameworks/Regular.framework/Modules/module.modulemap
+framework module Regular {
+  header "Regular.h"
+  export *
+}
+
+//--- Frameworks/RegularHider.framework/Headers/Visible.h
+// Empty, file required to create a module.
+
+//--- Frameworks/RegularHider.framework/Headers/Hidden.h
+@protocol Testing
+- (void)protocolMethod;
+@end
+
+//--- Frameworks/RegularHider.framework/Modules/module.modulemap
+framework module RegularHider {
+  header "Visible.h"
+  export *
+
+  explicit module Hidden {
+header "Hidden.h"
+export *
+  }
+}
+
+//--- test.m
+#import 
+
+#if HIDDEN_FIRST
+#import 
+#import 
+#else
+#import 
+#import 
+#endif
+
+void test(Common *obj) {
+  [[obj getProtocolObj] protocolMethod];
+}



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


[clang] 0a35cc4 - [clang][objc] Speed up populating the global method pool from modules.

2021-11-03 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-11-03T17:11:14-07:00
New Revision: 0a35cc40b881a35c6a7a748f5fdefac4cafc33ce

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

LOG: [clang][objc] Speed up populating the global method pool from modules.

For each selector encountered in the source code, we need to load
selectors from the imported modules and check that we are calling a
selector with compatible types.

At the moment, for each module we are storing methods declared in the
headers belonging to this module and methods from the transitive closure
of imported modules. When a module is imported by a few other modules,
methods from the shared module are duplicated in each importer. As the
result, we can end up with lots of identical methods that we try to add
to the global method pool. Doing this duplicate work is useless and
relatively expensive.

Avoid processing duplicate methods by storing in each module only its
own methods and not storing methods from dependencies. Collect methods
from dependencies by walking the graph of module dependencies.

The issue was discovered and reported by Richard Howell. He has done the
hard work for this fix as he has investigated and provided a detailed
explanation of the performance problem.

Differential Revision: https://reviews.llvm.org/D110123

Added: 
clang/test/Modules/method_pool_transitive.m

Modified: 
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/Modules/lookup.m

Removed: 




diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 0f180d821ed7f..07a0f00aa5357 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8151,13 +8151,16 @@ namespace serialization {
   if (Reader.DeserializationListener)
 Reader.DeserializationListener->SelectorRead(Data.ID, Sel);
 
-  InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
-  FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
+  // Append methods in the reverse order, so that later we can process them
+  // in the order they appear in the source code by iterating through
+  // the vector in the reverse order.
+  InstanceMethods.append(Data.Instance.rbegin(), Data.Instance.rend());
+  FactoryMethods.append(Data.Factory.rbegin(), Data.Factory.rend());
   InstanceBits = Data.InstanceBits;
   FactoryBits = Data.FactoryBits;
   InstanceHasMoreThanOneDecl = Data.InstanceHasMoreThanOneDecl;
   FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl;
-  return true;
+  return false;
 }
 
 /// Retrieve the instance methods found by this visitor.
@@ -8186,9 +8189,8 @@ namespace serialization {
 /// Add the given set of methods to the method list.
 static void addMethodsToPool(Sema , ArrayRef Methods,
  ObjCMethodList ) {
-  for (unsigned I = 0, N = Methods.size(); I != N; ++I) {
-S.addMethodToGlobalList(, Methods[I]);
-  }
+  for (auto I = Methods.rbegin(), E = Methods.rend(); I != E; ++I)
+S.addMethodToGlobalList(, *I);
 }
 
 void ASTReader::ReadMethodPool(Selector Sel) {

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 7c500f30e271e..3e0e5e9c8f752 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3045,11 +3045,11 @@ class ASTMethodPoolTrait {
 unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
 for (const ObjCMethodList *Method =  Method;
  Method = Method->getNext())
-  if (Method->getMethod())
+  if (ShouldWriteMethodListNode(Method))
 DataLen += 4;
 for (const ObjCMethodList *Method =  Method;
  Method = Method->getNext())
-  if (Method->getMethod())
+  if (ShouldWriteMethodListNode(Method))
 DataLen += 4;
 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
   }
@@ -3080,13 +3080,13 @@ class ASTMethodPoolTrait {
 unsigned NumInstanceMethods = 0;
 for (const ObjCMethodList *Method =  Method;
  Method = Method->getNext())
-  if (Method->getMethod())
+  if (ShouldWriteMethodListNode(Method))
 ++NumInstanceMethods;
 
 unsigned NumFactoryMethods = 0;
 for (const ObjCMethodList *Method =  Method;
  Method = Method->getNext())
-  if (Method->getMethod())
+  if (ShouldWriteMethodListNode(Method))
 ++NumFactoryMethods;
 
 unsigned InstanceBits = Methods.Instance.getBits();
@@ -3107,15 +3107,20 @@ class ASTMethodPoolTrait {
 LE.write(FullFactoryBits);
 for (const ObjCMethodList *Method =  Method;
  Method = Method->getNext())
-  if (Method->getMethod())
+  if 

[clang] 048d2c7 - [modules] Update visibility for merged ObjCInterfaceDecl definitions.

2021-10-21 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-10-21T15:06:39-07:00
New Revision: 048d2c76efcddf4265987914e30d3d4f49395496

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

LOG: [modules] Update visibility for merged ObjCInterfaceDecl definitions.

We keep using the first encountered definition and need to take into
account visibility from subsequent definitions. For example, if the
first definition is hidden and the second is visible, we need to make
the first one visible too.

rdar://82263843

Differential Revision: https://reviews.llvm.org/D110453

Added: 
clang/test/Modules/merge-objc-interface-visibility.m

Modified: 
clang/lib/Serialization/ASTReaderDecl.cpp

Removed: 




diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7aab708d00e4a..2a617a4fec116 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1181,6 +1181,7 @@ void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl 
*D,
   if (DD.Definition != NewDD.Definition) {
 Reader.MergedDeclContexts.insert(
 std::make_pair(NewDD.Definition, DD.Definition));
+Reader.mergeDefinitionVisibility(DD.Definition, NewDD.Definition);
   }
 
   // FIXME: odr checking?

diff  --git a/clang/test/Modules/merge-objc-interface-visibility.m 
b/clang/test/Modules/merge-objc-interface-visibility.m
new file mode 100644
index 0..181a2c716c6b3
--- /dev/null
+++ b/clang/test/Modules/merge-objc-interface-visibility.m
@@ -0,0 +1,61 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m 
-DHIDDEN_FIRST=1 \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m 
-DHIDDEN_FIRST=0 \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+
+// Test a case when Objective-C interface is imported both as hidden and as 
visible.
+
+//--- Frameworks/Foundation.framework/Headers/Foundation.h
+@interface NSObject
+@end
+
+//--- Frameworks/Foundation.framework/Modules/module.modulemap
+framework module Foundation {
+  header "Foundation.h"
+  export *
+}
+
+//--- Frameworks/Regular.framework/Headers/Regular.h
+#import 
+@interface Regular : NSObject
+@end
+
+//--- Frameworks/Regular.framework/Modules/module.modulemap
+framework module Regular {
+  header "Regular.h"
+  export *
+}
+
+//--- Frameworks/RegularHider.framework/Headers/Visible.h
+// Empty, file required to create a module.
+
+//--- Frameworks/RegularHider.framework/Headers/Hidden.h
+#import 
+@interface Regular : NSObject
+@end
+
+//--- Frameworks/RegularHider.framework/Modules/module.modulemap
+framework module RegularHider {
+  header "Visible.h"
+  export *
+
+  explicit module Hidden {
+header "Hidden.h"
+export *
+  }
+}
+
+//--- test.m
+
+#if HIDDEN_FIRST
+#import 
+#import 
+#else
+#import 
+#import 
+#endif
+
+@interface SubClass : Regular
+@end



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


[clang] d9eca33 - [modules] Fix tracking ObjCInterfaceType decl when there are multiple definitions.

2021-10-21 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-10-21T12:08:06-07:00
New Revision: d9eca3320a4d8db11ad65229ef6f564d134fc894

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

LOG: [modules] Fix tracking ObjCInterfaceType decl when there are multiple 
definitions.

With the old approach we were updating `ObjCInterfaceType.Decl` to the
last encountered definition. But during loading modules
`ASTDeclReader::VisitObjCInterfaceDecl` keeps the *first* encountered
definition. So with multiple definitions imported there would be a
disagreement between expected definition in `ObjCInterfaceType.Decl` and
actual definition `ObjCInterfaceDecl::getDefinition` which can lead to
incorrect diagnostic.

Fix by not tracking definition in `ObjCInterfaceType` explicitly but by
getting it from redeclaration chain.

Partially reverted 919fc50034b44c48aae8b80283f253ec2ee17f45 keeping the
modified test case as the correct behavior is achieved in a different
way.

Differential Revision: https://reviews.llvm.org/D110452

Added: 


Modified: 
clang/include/clang/AST/Type.h
clang/lib/AST/DeclObjC.cpp
clang/lib/AST/Type.cpp
clang/lib/Sema/SemaLookup.cpp
clang/test/Modules/decldef.mm
clang/test/Modules/interface-diagnose-missing-import.m

Removed: 




diff  --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index f8c1fe91085f0..722add6cd8777 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6016,10 +6016,9 @@ inline ObjCProtocolDecl 
**ObjCTypeParamType::getProtocolStorageImpl() {
 class ObjCInterfaceType : public ObjCObjectType {
   friend class ASTContext; // ASTContext creates these.
   friend class ASTReader;
-  friend class ObjCInterfaceDecl;
   template  friend class serialization::AbstractTypeReader;
 
-  mutable ObjCInterfaceDecl *Decl;
+  ObjCInterfaceDecl *Decl;
 
   ObjCInterfaceType(const ObjCInterfaceDecl *D)
   : ObjCObjectType(Nonce_ObjCInterface),
@@ -6027,7 +6026,7 @@ class ObjCInterfaceType : public ObjCObjectType {
 
 public:
   /// Get the declaration of this interface.
-  ObjCInterfaceDecl *getDecl() const { return Decl; }
+  ObjCInterfaceDecl *getDecl() const;
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }

diff  --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 64eefc245f04a..ba827a79c0225 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -603,10 +603,6 @@ void ObjCInterfaceDecl::allocateDefinitionData() {
   assert(!hasDefinition() && "ObjC class already has a definition");
   Data.setPointer(new (getASTContext()) DefinitionData());
   Data.getPointer()->Definition = this;
-
-  // Make the type point at the definition, now that we have one.
-  if (TypeForDecl)
-cast(TypeForDecl)->Decl = this;
 }
 
 void ObjCInterfaceDecl::startDefinition() {

diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e7cdf58839631..ead3944284aec 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -821,6 +821,13 @@ QualType ObjCObjectType::stripObjCKindOfTypeAndQuals(
/*isKindOf=*/false);
 }
 
+ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {
+  ObjCInterfaceDecl *Canon = Decl->getCanonicalDecl();
+  if (ObjCInterfaceDecl *Def = Canon->getDefinition())
+return Def;
+  return Canon;
+}
+
 const ObjCObjectPointerType 
*ObjCObjectPointerType::stripObjCKindOfTypeAndQuals(
const ASTContext ) const {
   if (!isKindOfType() && qual_empty())

diff  --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index e4e5f57745c61..05529d0556211 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -5323,11 +5323,8 @@ static NamedDecl *getDefinitionToImport(NamedDecl *D) {
 return FD->getDefinition();
   if (TagDecl *TD = dyn_cast(D))
 return TD->getDefinition();
-  // The first definition for this ObjCInterfaceDecl might be in the TU
-  // and not associated with any module. Use the one we know to be complete
-  // and have just seen in a module.
   if (ObjCInterfaceDecl *ID = dyn_cast(D))
-return ID;
+return ID->getDefinition();
   if (ObjCProtocolDecl *PD = dyn_cast(D))
 return PD->getDefinition();
   if (TemplateDecl *TD = dyn_cast(D))

diff  --git a/clang/test/Modules/decldef.mm b/clang/test/Modules/decldef.mm
index e8f070b511591..02883dc1d31e7 100644
--- a/clang/test/Modules/decldef.mm
+++ b/clang/test/Modules/decldef.mm
@@ -1,10 +1,12 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fobjc-arc -I %S/Inputs 
-fmodules-cache-path=%t %s -verify -DUSE_1 -DUSE_2 -DUSE_3 -DUSE_4
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fobjc-arc -I %S/Inputs 

[clang] c593126 - [modules] While merging ObjCInterfaceDecl definitions, merge them as decl contexts too.

2021-10-20 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-10-20T18:48:29-07:00
New Revision: c5931267db26d71351c634df06006d9c818ff158

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

LOG: [modules] While merging ObjCInterfaceDecl definitions, merge them as decl 
contexts too.

While working on https://reviews.llvm.org/D110280 I've tried to merge
decl contexts as it seems to be correct and matching our handling of
decl contexts from different modules. It's not required for the fix in
https://reviews.llvm.org/D110280 but it revealed a missing diagnostic,
so separating this change into a separate commit.

Renamed some variables to distinguish diagnostic like "declaration of
'x' does not match" for different cases.

Differential Revision: https://reviews.llvm.org/D110287

Added: 


Modified: 
clang/lib/Serialization/ASTReaderDecl.cpp
clang/test/Modules/odr_hash.mm

Removed: 




diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index f2c2023cbf233..7aab708d00e4a 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1177,6 +1177,12 @@ void ASTDeclReader::ReadObjCDefinitionData(
 
 void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D,
  struct ObjCInterfaceDecl::DefinitionData &) {
+  struct ObjCInterfaceDecl::DefinitionData  = D->data();
+  if (DD.Definition != NewDD.Definition) {
+Reader.MergedDeclContexts.insert(
+std::make_pair(NewDD.Definition, DD.Definition));
+  }
+
   // FIXME: odr checking?
 }
 

diff  --git a/clang/test/Modules/odr_hash.mm b/clang/test/Modules/odr_hash.mm
index 86ddd16b94fb7..276bd58624eca 100644
--- a/clang/test/Modules/odr_hash.mm
+++ b/clang/test/Modules/odr_hash.mm
@@ -241,12 +241,12 @@ @interface Interface4  {
 @end
 @interface Interface5  {
 @public
-  T x;
+  T y;
 }
 @end
 @interface Interface6  {
 @public
-  T1 x;
+  T1 z;
 }
 @end
 #elif defined(SECOND)
@@ -257,14 +257,21 @@ @interface Interface4  {
 @end
 @interface Interface5  {
 @public
-  T x;
+  T y;
 }
 @end
 @interface Interface6  {
 @public
-  T2 x;
+  T2 z;
 }
 @end
+#else
+// expected-error@first.h:* {{'Interface4::x' from module 'FirstModule' is not 
present in definition of 'Interface4' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'x' does not match}}
+// expected-error@first.h:* {{'Interface5::y' from module 'FirstModule' is not 
present in definition of 'Interface5' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'y' does not match}}
+// expected-error@first.h:* {{'Interface6::z' from module 'FirstModule' is not 
present in definition of 'Interface6' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'z' does not match}}
 #endif
 
 namespace Types {
@@ -276,22 +283,22 @@ @interface Interface6  {
 };
 struct Invalid2 {
   Interface5 *I;
-  decltype(I->x) x;
+  decltype(I->y) y;
 };
 struct Invalid3 {
   Interface6 *I;
-  decltype(I->x) x;
+  decltype(I->z) z;
 };
 #else
 Invalid1 i1;
 // expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid1::x' from module 
'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid1' 
in module 'SecondModule'}}
 // expected-note@second.h:* {{declaration of 'x' does not match}}
 Invalid2 i2;
-// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid2::x' from module 
'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid2' 
in module 'SecondModule'}}
-// expected-note@second.h:* {{declaration of 'x' does not match}}
+// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid2::y' from module 
'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid2' 
in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'y' does not match}}
 Invalid3 i3;
-// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid3::x' from module 
'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid3' 
in module 'SecondModule'}}
-// expected-note@second.h:* {{declaration of 'x' does not match}}
+// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid3::z' from module 
'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid3' 
in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'z' does not match}}
 #endif
 
 }  // namespace ObjCTypeParam



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


[clang] 91e19f6 - [driver] Explicitly specify `-fbuild-session-timestamp` in seconds.

2021-10-19 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-10-19T13:30:26-07:00
New Revision: 91e19f66e51ac3fda2309f5e67b02fcccd4d58a0

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

LOG: [driver] Explicitly specify `-fbuild-session-timestamp` in seconds.

Representation of the file's last modification time depends on the file
system and isn't guaranteed to be in seconds. Cast to seconds explicitly
and tighten the test case to check the magnitude of the calculated
value, so we can catch passing milliseconds or nanoseconds.

rdar://83915615

Differential Revision: https://reviews.llvm.org/D111205

Added: 


Modified: 
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/Driver/modules.m

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b689301e9bb1..8dabfff64f80 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3573,11 +3573,11 @@ static void RenderModulesOptions(Compilation , const 
Driver ,
 llvm::sys::fs::file_status Status;
 if (llvm::sys::fs::status(A->getValue(), Status))
   D.Diag(diag::err_drv_no_such_file) << A->getValue();
-CmdArgs.push_back(
-Args.MakeArgString("-fbuild-session-timestamp=" +
-   Twine((uint64_t)Status.getLastModificationTime()
- .time_since_epoch()
- .count(;
+CmdArgs.push_back(Args.MakeArgString(
+"-fbuild-session-timestamp=" +
+Twine((uint64_t)std::chrono::duration_cast(
+  Status.getLastModificationTime().time_since_epoch())
+  .count(;
   }
 
   if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {

diff  --git a/clang/test/Driver/modules.m b/clang/test/Driver/modules.m
index 73db4e7e0fcc..67140926f176 100644
--- a/clang/test/Driver/modules.m
+++ b/clang/test/Driver/modules.m
@@ -11,7 +11,7 @@
 // RUN: %clang -fbuild-session-file=%t.build-session-file -### %s 2>&1 | 
FileCheck -check-prefix=TIMESTAMP_ONLY %s
 
 // RUN: %clang -fbuild-session-timestamp=1280703457 -### %s 2>&1 | FileCheck 
-check-prefix=TIMESTAMP_ONLY %s
-// TIMESTAMP_ONLY: -fbuild-session-timestamp=128
+// TIMESTAMP_ONLY: 
-fbuild-session-timestamp=128{{([[:digit:]]{7})[^[:digit:]]}}
 
 // RUN: %clang -fbuild-session-file=%t.build-session-file 
-fbuild-session-timestamp=123 -### %s 2>&1 | FileCheck -check-prefix=CONFLICT %s
 // CONFLICT: error: invalid argument 
'-fbuild-session-file={{.*}}.build-session-file' not allowed with 
'-fbuild-session-timestamp'
@@ -21,7 +21,7 @@
 // MODULES_VALIDATE_ONCE: -fmodules-validate-once-per-build-session
 
 // RUN: %clang -fbuild-session-file=%t.build-session-file 
-fmodules-validate-once-per-build-session -### %s 2>&1 | FileCheck 
-check-prefix=MODULES_VALIDATE_ONCE_FILE %s
-// MODULES_VALIDATE_ONCE_FILE: -fbuild-session-timestamp=128
+// MODULES_VALIDATE_ONCE_FILE: 
-fbuild-session-timestamp=128{{([[:digit:]]{7})[^[:digit:]]}}
 // MODULES_VALIDATE_ONCE_FILE: -fmodules-validate-once-per-build-session
 
 // RUN: %clang -fmodules-validate-once-per-build-session -### %s 2>&1 | 
FileCheck -check-prefix=MODULES_VALIDATE_ONCE_ERR %s



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


[clang] d0e7bdc - [modules] Make a module map referenced by a system map a system one too.

2021-10-15 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-10-15T12:46:51-07:00
New Revision: d0e7bdc208491fd5d4245878c1ec2962694e2baa

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

LOG: [modules] Make a module map referenced by a system map a system one too.

Mimic the behavior of including headers where a system includer makes an
includee a system header too.

rdar://84049469

Differential Revision: https://reviews.llvm.org/D111476

Added: 


Modified: 
clang/lib/Lex/ModuleMap.cpp
clang/test/Modules/fmodules-validate-once-per-build-session.c

Removed: 




diff  --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 53b824baba58b..08381d0422058 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -2173,7 +2173,7 @@ void ModuleMapParser::parseExternModuleDecl() {
   }
   if (auto File = SourceMgr.getFileManager().getFile(FileNameRef))
 Map.parseModuleMapFile(
-*File, /*IsSystem=*/false,
+*File, IsSystem,
 Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd
 ? Directory
 : (*File)->getDir(),

diff  --git a/clang/test/Modules/fmodules-validate-once-per-build-session.c 
b/clang/test/Modules/fmodules-validate-once-per-build-session.c
index 840545bb59fc9..0c97342a8d70a 100644
--- a/clang/test/Modules/fmodules-validate-once-per-build-session.c
+++ b/clang/test/Modules/fmodules-validate-once-per-build-session.c
@@ -1,4 +1,5 @@
 #include "foo.h"
+#include "bar.h"
 
 // Clear the module cache.
 // RUN: rm -rf %t
@@ -9,51 +10,74 @@
 // Create a module.  We will use -I or -isystem to determine whether to treat
 // foo.h as a system header.
 // RUN: echo 'void meow(void);' > %t/Inputs/foo.h
+// RUN: echo 'void woof(void);' > %t/Inputs/bar.h
 // RUN: echo 'module Foo { header "foo.h" }' > %t/Inputs/module.map
+// RUN: echo 'extern module Bar "bar.modulemap"' >> %t/Inputs/module.map
+// RUN: echo 'module Bar { header "bar.h" }' > %t/Inputs/bar.modulemap
 
 // ===
 // Compile the module.
 // RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
 // RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
 // RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
+// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
 // RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
+// RUN: ls -R %t/modules-cache-user | grep Bar.pcm.timestamp
 // RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-before.pcm
+// RUN: cp %t/modules-cache/Bar.pcm %t/modules-to-compare/Bar-before.pcm
 // RUN: cp %t/modules-cache-user/Foo.pcm 
%t/modules-to-compare/Foo-before-user.pcm
+// RUN: cp %t/modules-cache-user/Bar.pcm 
%t/modules-to-compare/Bar-before-user.pcm
 
 // ===
 // Use it, and make sure that we did not recompile it.
 // RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache -fsyntax-only -isystem %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
 // RUN: %clang_cc1 -cc1 -fmodules -fimplicit-module-maps -fdisable-module-hash 
-fmodules-cache-path=%t/modules-cache-user -fsyntax-only -I %t/Inputs 
-fbuild-session-timestamp=139000 -fmodules-validate-once-per-build-session 
%s
 // RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
+// RUN: ls -R %t/modules-cache | grep Bar.pcm.timestamp
 // RUN: ls -R %t/modules-cache-user | grep Foo.pcm.timestamp
+// RUN: ls -R %t/modules-cache-user | grep Bar.pcm.timestamp
 // RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
+// RUN: cp %t/modules-cache/Bar.pcm %t/modules-to-compare/Bar-after.pcm
 // RUN: cp %t/modules-cache-user/Foo.pcm 
%t/modules-to-compare/Foo-after-user.pcm
+// RUN: cp %t/modules-cache-user/Bar.pcm 
%t/modules-to-compare/Bar-after-user.pcm
 
 // RUN: 
diff  %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
+// RUN: 
diff  %t/modules-to-compare/Bar-before.pcm %t/modules-to-compare/Bar-after.pcm
 // RUN: 
diff  %t/modules-to-compare/Foo-before-user.pcm 
%t/modules-to-compare/Foo-after-user.pcm
+// RUN: 
diff  %t/modules-to-compare/Bar-before-user.pcm 
%t/modules-to-compare/Bar-after-user.pcm
 
 // ===
 // Change the sources.
 // RUN: echo 'void meow2(void);' > %t/Inputs/foo.h
+// RUN: echo 'module Bar { header "bar.h" export * }' > %t/Inputs/bar.modulemap
 
 // ===
-// Use the module, and make sure that we did not recompile it if foo.h is a
-// system header, 

[clang] 9fad9de - [modules] Fix IRGen assertion on accessing ObjC ivar inside a method.

2021-10-07 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-10-07T17:09:31-07:00
New Revision: 9fad9de5c0032898a481e06bf5f696ca50c804c1

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

LOG: [modules] Fix IRGen assertion on accessing ObjC ivar inside a method.

When have ObjCInterfaceDecl with the same name in 2 different modules,
hitting the assertion

> Assertion failed: (Index < RL->getFieldCount() && "Ivar is not inside record 
> layout!"),
> function lookupFieldBitOffset, file 
> llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp, line 3434.

on accessing an ivar inside a method. The assertion happens because
ivar belongs to one module while its containing interface belongs to
another module and then we fail to find the ivar inside the containing
interface. We already keep a single ObjCInterfaceDecl definition in
redecleration chain and in this case containing interface was correct.
The issue is with ObjCIvarDecl. IVar decl for IRGen is taken from
ObjCIvarRefExpr that is created in `Sema::BuildIvarRefExpr` using ivar
decl returned from `Sema::LookupIvarInObjCMethod`. And ivar lookup
returns a wrong decl because basically we take the first ObjCIvarDecl
found in `ASTReader::FindExternalVisibleDeclsByName` (called by
`DeclContext::lookup`). And in `ASTReader.Lookups` lookup table for a
wrong module comes first because `ASTReader::finishPendingActions`
processes `PendingUpdateRecords` in reverse order and the first
encountered ObjCIvarDecl will end up the last in `ASTReader.Lookups`.

Fix by merging ObjCIvarDecl from different modules correctly and by
using a canonical one in IRGen.

rdar://82854574

Differential Revision: https://reviews.llvm.org/D110280

Added: 
clang/test/Modules/merge-objc-interface.m

Modified: 
clang/include/clang/AST/DeclObjC.h
clang/lib/AST/RecordLayoutBuilder.cpp
clang/lib/Serialization/ASTReaderDecl.cpp

Removed: 




diff  --git a/clang/include/clang/AST/DeclObjC.h 
b/clang/include/clang/AST/DeclObjC.h
index 6bb9cdf67034d..f484dfedbf544 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -1955,6 +1955,13 @@ class ObjCIvarDecl : public FieldDecl {
   const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
   void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
 
+  ObjCIvarDecl *getCanonicalDecl() override {
+return cast(FieldDecl::getCanonicalDecl());
+  }
+  const ObjCIvarDecl *getCanonicalDecl() const {
+return const_cast(this)->getCanonicalDecl();
+  }
+
   void setAccessControl(AccessControl ac) { DeclAccess = ac; }
 
   AccessControl getAccessControl() const { return AccessControl(DeclAccess); }

diff  --git a/clang/lib/AST/RecordLayoutBuilder.cpp 
b/clang/lib/AST/RecordLayoutBuilder.cpp
index d49b0aec42fec..d17d1e26742c2 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -3404,6 +3404,7 @@ uint64_t ASTContext::getFieldOffset(const ValueDecl *VD) 
const {
 uint64_t ASTContext::lookupFieldBitOffset(const ObjCInterfaceDecl *OID,
   const ObjCImplementationDecl *ID,
   const ObjCIvarDecl *Ivar) const {
+  Ivar = Ivar->getCanonicalDecl();
   const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
 
   // FIXME: We should eliminate the need to have ObjCImplementationDecl passed

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index d011d14612d13..f2c2023cbf233 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3350,6 +3350,9 @@ DeclContext 
*ASTDeclReader::getPrimaryContextForMerging(ASTReader ,
 return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
   : nullptr;
 
+  if (auto *OID = dyn_cast(DC))
+return OID->getDefinition();
+
   // We can see the TU here only if we have no Sema object. In that case,
   // there's no TU scope to look in, so using the DC alone is sufficient.
   if (auto *TU = dyn_cast(DC))

diff  --git a/clang/test/Modules/merge-objc-interface.m 
b/clang/test/Modules/merge-objc-interface.m
new file mode 100644
index 0..fba06294a26af
--- /dev/null
+++ b/clang/test/Modules/merge-objc-interface.m
@@ -0,0 +1,105 @@
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks %t/test.m \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+// RUN: %clang_cc1 -emit-llvm -o %t/test.bc -F%t/Frameworks 
%t/test-functions.m \
+// RUN:-fmodules -fimplicit-module-maps 
-fmodules-cache-path=%t/modules.cache
+
+// Test a case when Objective-C interface ivars are present in 

[clang] 64ebf31 - [HeaderSearch] Use `isImport` only for imported headers and not for `#pragma once`.

2021-09-01 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-09-01T17:07:35-07:00
New Revision: 64ebf313a7e485e1a90da9cd69c412e06615a9bc

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

LOG: [HeaderSearch] Use `isImport` only for imported headers and not for 
`#pragma once`.

There is a separate field `isPragmaOnce` and when `isImport` combines
both, it complicates HeaderFileInfo serialization as `#pragma once` is
the inherent property of the header while `isImport` reflects how other
headers use it. The usage of the header can be different in different
contexts, that's why `isImport` requires tracking separate from `#pragma once`.

Differential Revision: https://reviews.llvm.org/D104351

Added: 


Modified: 
clang/include/clang/Lex/HeaderSearch.h
clang/lib/Lex/HeaderSearch.cpp

Removed: 




diff  --git a/clang/include/clang/Lex/HeaderSearch.h 
b/clang/include/clang/Lex/HeaderSearch.h
index a35a394f719b0..7df1127f42735 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -51,7 +51,7 @@ class TargetInfo;
 /// The preprocessor keeps track of this information for each
 /// file that is \#included.
 struct HeaderFileInfo {
-  /// True if this is a \#import'd or \#pragma once file.
+  /// True if this is a \#import'd file.
   unsigned isImport : 1;
 
   /// True if this is a \#pragma once file.
@@ -450,11 +450,10 @@ class HeaderSearch {
 return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
   }
 
-  /// Mark the specified file as a "once only" file, e.g. due to
+  /// Mark the specified file as a "once only" file due to
   /// \#pragma once.
   void MarkFileIncludeOnce(const FileEntry *File) {
 HeaderFileInfo  = getFileInfo(File);
-FI.isImport = true;
 FI.isPragmaOnce = true;
   }
 
@@ -500,8 +499,7 @@ class HeaderSearch {
   /// This routine does not consider the effect of \#import
   bool isFileMultipleIncludeGuarded(const FileEntry *File);
 
-  /// Determine whether the given file is known to have ever been \#imported
-  /// (or if it has been \#included and we've encountered a \#pragma once).
+  /// Determine whether the given file is known to have ever been \#imported.
   bool hasFileBeenImported(const FileEntry *File) {
 const HeaderFileInfo *FI = getExistingFileInfo(File);
 return FI && FI->isImport;

diff  --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index d5adbcf62cbc5..8bf61a2ba5972 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -91,7 +91,7 @@ void HeaderSearch::PrintStats() {
<< FileInfo.size() << " files tracked.\n";
   unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 
0;
   for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
-NumOnceOnlyFiles += FileInfo[i].isImport;
+NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
 if (MaxNumIncludes < FileInfo[i].NumIncludes)
   MaxNumIncludes = FileInfo[i].NumIncludes;
 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
@@ -1325,7 +1325,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor 
,
   } 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())
+if ((FileInfo.isPragmaOnce || FileInfo.isImport) && !TryEnterImported())
   return false;
   }
 



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


[clang] 93764ff - [modules] Fix miscompilation when using two RecordDecl definitions with the same name.

2021-08-30 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-08-30T17:51:38-07:00
New Revision: 93764ff6e2005b92057cffa9b3866307e2de260f

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

LOG: [modules] Fix miscompilation when using two RecordDecl definitions with 
the same name.

When deserializing a RecordDecl we don't enforce that redeclaration
chain contains only a single definition. So if the canonical decl is not
a definition itself, `RecordType::getDecl` can return different objects
before and after an include. It means we can build CGRecordLayout for
one RecordDecl with its set of FieldDecl but try to use it with
FieldDecl belonging to a different RecordDecl. With assertions enabled
it results in

> Assertion failed: (FieldInfo.count(FD) && "Invalid field for record!"),
> function getLLVMFieldNo, file 
> llvm-project/clang/lib/CodeGen/CGRecordLayout.h, line 199.

and with assertions disabled a bunch of fields are treated as their
memory is located at offset 0.

Fix by keeping the first encountered RecordDecl definition and marking
the subsequent ones as non-definitions. Also need to merge FieldDecl
properly, so that `getPrimaryMergedDecl` works correctly and during name
lookup we don't treat fields from same-name RecordDecl as ambiguous.

rdar://80184238

Differential Revision: https://reviews.llvm.org/D106994

Added: 

clang/test/Modules/Inputs/merge-record-definition/RecordDef.framework/Headers/RecordDef.h

clang/test/Modules/Inputs/merge-record-definition/RecordDef.framework/Modules/module.modulemap

clang/test/Modules/Inputs/merge-record-definition/RecordDefCopy.framework/Headers/RecordDefCopy.h

clang/test/Modules/Inputs/merge-record-definition/RecordDefCopy.framework/Modules/module.modulemap

clang/test/Modules/Inputs/merge-record-definition/RecordDefHidden.framework/Headers/Hidden.h

clang/test/Modules/Inputs/merge-record-definition/RecordDefHidden.framework/Headers/Visible.h

clang/test/Modules/Inputs/merge-record-definition/RecordDefHidden.framework/Modules/module.modulemap

clang/test/Modules/Inputs/merge-record-definition/RecordDefIncluder.framework/Headers/RecordDefIncluder.h

clang/test/Modules/Inputs/merge-record-definition/RecordDefIncluder.framework/Modules/module.modulemap
clang/test/Modules/merge-record-definition-nonmodular.m
clang/test/Modules/merge-record-definition-visibility.m
clang/test/Modules/merge-record-definition.m

Modified: 
clang/include/clang/Serialization/ASTReader.h
clang/lib/Serialization/ASTCommon.cpp
clang/lib/Serialization/ASTReaderDecl.cpp

Removed: 




diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index e342a061379eb..f24ccf579aa8f 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1162,6 +1162,10 @@ class ASTReader
   /// definitions. Only populated when using modules in C++.
   llvm::DenseMap EnumDefinitions;
 
+  /// A mapping from canonical declarations of records to their canonical
+  /// definitions. Doesn't cover CXXRecordDecl.
+  llvm::DenseMap RecordDefinitions;
+
   /// When reading a Stmt tree, Stmt operands are placed in this stack.
   SmallVector StmtStack;
 

diff  --git a/clang/lib/Serialization/ASTCommon.cpp 
b/clang/lib/Serialization/ASTCommon.cpp
index 5fe1f96327ddc..db118d8b00776 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -474,7 +474,7 @@ bool serialization::needsAnonymousDeclarationNumber(const 
NamedDecl *D) {
   // Otherwise, we only care about anonymous class members / block-scope decls.
   // FIXME: We need to handle lambdas and blocks within inline / templated
   // variables too.
-  if (D->getDeclName() || !isa(D->getLexicalDeclContext()))
+  if (D->getDeclName() || !isa(D->getLexicalDeclContext()))
 return false;
   return isa(D) || isa(D);
 }

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index ff79f91e5db1b..ef7921212f21b 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -332,7 +332,7 @@ namespace clang {
 RedeclarableResult VisitTagDecl(TagDecl *TD);
 void VisitEnumDecl(EnumDecl *ED);
 RedeclarableResult VisitRecordDeclImpl(RecordDecl *RD);
-void VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); }
+void VisitRecordDecl(RecordDecl *RD);
 RedeclarableResult VisitCXXRecordDeclImpl(CXXRecordDecl *D);
 void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); }
 RedeclarableResult VisitClassTemplateSpecializationDeclImpl(
@@ -808,6 +808,34 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
   return Redecl;
 }
 
+void 

[clang] a4a5c00 - [Modules] Change result of reading AST block to llvm::Error instead

2021-08-27 Thread Volodymyr Sapsai via cfe-commits

Author: Ben Barham
Date: 2021-08-27T20:16:20-07:00
New Revision: a4a5c00b53d0638e2bd9011fa5cce7ef9739eea6

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

LOG: [Modules] Change result of reading AST block to llvm::Error instead

Reading the AST block can never fail with a recoverable error as modules
cannot be removed during this phase. Change the return type of these
functions to return an llvm::Error instead, ie. either success or
failure.

NFC other than the wording of some of the errors.

Differential Revision: https://reviews.llvm.org/D108268

Added: 


Modified: 
clang/include/clang/Serialization/ASTReader.h
clang/lib/Serialization/ASTReader.cpp

Removed: 




diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index 242b75baca6c9..e342a061379eb 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1320,18 +1320,18 @@ class ASTReader
ASTReaderListener *Listener,
bool ValidateDiagnosticOptions);
 
-  ASTReadResult ReadASTBlock(ModuleFile , unsigned ClientLoadCapabilities);
-  ASTReadResult ReadExtensionBlock(ModuleFile );
+  llvm::Error ReadASTBlock(ModuleFile , unsigned ClientLoadCapabilities);
+  llvm::Error ReadExtensionBlock(ModuleFile );
   void ReadModuleOffsetMap(ModuleFile ) const;
-  bool ParseLineTable(ModuleFile , const RecordData );
-  bool ReadSourceManagerBlock(ModuleFile );
+  void ParseLineTable(ModuleFile , const RecordData );
+  llvm::Error ReadSourceManagerBlock(ModuleFile );
   llvm::BitstreamCursor (int ID);
   SourceLocation getImportLocation(ModuleFile *F);
   ASTReadResult ReadModuleMapFileBlock(RecordData , ModuleFile ,
const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
-  ASTReadResult ReadSubmoduleBlock(ModuleFile ,
-   unsigned ClientLoadCapabilities);
+  llvm::Error ReadSubmoduleBlock(ModuleFile ,
+ unsigned ClientLoadCapabilities);
   static bool ParseLanguageOptions(const RecordData , bool Complain,
ASTReaderListener ,
bool AllowCompatibleDifferences);
@@ -1904,8 +1904,9 @@ class ASTReader
   /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
   /// specified cursor.  Read the abbreviations that are at the top of the 
block
   /// and then leave the cursor pointing into the block.
-  static bool ReadBlockAbbrevs(llvm::BitstreamCursor , unsigned BlockID,
-   uint64_t *StartOfBlockOffset = nullptr);
+  static llvm::Error ReadBlockAbbrevs(llvm::BitstreamCursor ,
+  unsigned BlockID,
+  uint64_t *StartOfBlockOffset = nullptr);
 
   /// Finds all the visible declarations with a given name.
   /// The current implementation of this method just loads the entire

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 376dbdf1bd557..128350ce9ff8f 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -10,15 +10,13 @@
 //
 
//===--===//
 
-#include "clang/Basic/OpenMPKinds.h"
-#include "clang/Serialization/ASTRecordReader.h"
 #include "ASTCommon.h"
 #include "ASTReaderInternals.h"
-#include "clang/AST/AbstractTypeReader.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/AbstractTypeReader.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -31,8 +29,8 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/OpenMPClause.h"
 #include "clang/AST/ODRHash.h"
+#include "clang/AST/OpenMPClause.h"
 #include "clang/AST/RawCommentList.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/TemplateName.h"
@@ -42,6 +40,7 @@
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/CommentOptions.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticError.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/ExceptionSpecificationType.h"
 #include "clang/Basic/FileManager.h"
@@ -51,6 +50,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/OperatorKinds.h"
 

[clang] 3220855 - [Modules] Do not remove failed modules after the control block phase

2021-08-17 Thread Volodymyr Sapsai via cfe-commits

Author: Ben Barham
Date: 2021-08-17T16:46:51-07:00
New Revision: 32208555af26c48f3df845a10b049c8eb74e2eb3

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

LOG: [Modules] Do not remove failed modules after the control block phase

Reading modules first reads each control block in the chain and then all
AST blocks.

The first phase is intended to find recoverable errors, eg. an out of
date or missing module. If any error occurs during this phase, it is
safe to remove all modules in the chain as no references to them will
exist.

While reading the AST blocks, however, various fields in ASTReader are
updated with references to the module. Removing modules at this point
can cause dangling pointers which can be accessed later. These would be
otherwise harmless, eg. a binary search over `GlobalSLocEntryMap` may
access a failed module that could error, but shouldn't crash. Do not
remove modules in this phase, regardless of failures.

Since this is the case, it also doesn't make sense to return OutOfDate
during this phase, so remove the two cases where this happens.

When they were originally added these checks would return a failure when
the serialized and current path didn't match up. That was updated to an
OutOfDate as it was found to be hit when using VFS and overriding the
umbrella. Later on the path was changed to instead be the name as
written in the module file, resolved using the serialized base
directory. At this point the check is really only comparing the name of
the umbrella and only works for frameworks since those don't include
`Headers/` in the name (which means the resolved path will never exist)

Given all that, it seems safe to ignore this case entirely for now.
This makes the handling of an umbrella header/directory the same as
regular headers, which also don't check for differences in the path
caused by VFS.

Resolves rdar://79329355

Differential Revision: https://reviews.llvm.org/D107690

Added: 
clang/test/VFS/module-header-mismatches.m

Modified: 
clang/lib/Serialization/ASTReader.cpp

Removed: 
clang/test/VFS/Inputs/UsesFoo.framework/Headers/UsesFoo.h
clang/test/VFS/Inputs/UsesFoo.framework/Modules/module.modulemap
clang/test/VFS/umbrella-mismatch.m



diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 83bade9941b3d..b8c4889b10f9d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4240,8 +4240,11 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef 
FileName,
 PreviousGeneration = incrementGeneration(*ContextObj);
 
   unsigned NumModules = ModuleMgr.size();
-  auto removeModulesAndReturn = [&](ASTReadResult ReadResult) {
-assert(ReadResult && "expected to return error");
+  SmallVector Loaded;
+  if (ASTReadResult ReadResult =
+  ReadASTCore(FileName, Type, ImportLoc,
+  /*ImportedBy=*/nullptr, Loaded, 0, 0, ASTFileSignature(),
+  ClientLoadCapabilities)) {
 ModuleMgr.removeModules(ModuleMgr.begin() + NumModules,
 PP.getLangOpts().Modules
 ? ().getModuleMap()
@@ -4252,22 +4255,6 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef 
FileName,
 GlobalIndex.reset();
 ModuleMgr.setGlobalIndex(nullptr);
 return ReadResult;
-  };
-
-  SmallVector Loaded;
-  switch (ASTReadResult ReadResult =
-  ReadASTCore(FileName, Type, ImportLoc,
-  /*ImportedBy=*/nullptr, Loaded, 0, 0,
-  ASTFileSignature(), ClientLoadCapabilities)) {
-  case Failure:
-  case Missing:
-  case OutOfDate:
-  case VersionMismatch:
-  case ConfigurationMismatch:
-  case HadErrors:
-return removeModulesAndReturn(ReadResult);
-  case Success:
-break;
   }
 
   // Here comes stuff that we only do once the entire chain is loaded.
@@ -4279,18 +4266,18 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef 
FileName,
 
 // Read the AST block.
 if (ASTReadResult Result = ReadASTBlock(F, ClientLoadCapabilities))
-  return removeModulesAndReturn(Result);
+  return Failure;
 
 // The AST block should always have a definition for the main module.
 if (F.isModule() && !F.DidReadTopLevelSubmodule) {
   Error(diag::err_module_file_missing_top_level_submodule, F.FileName);
-  return removeModulesAndReturn(Failure);
+  return Failure;
 }
 
 // Read the extension blocks.
 while (!SkipCursorToBlock(F.Stream, EXTENSION_BLOCK_ID)) {
   if (ASTReadResult Result = ReadExtensionBlock(F))
-return removeModulesAndReturn(Result);
+return Failure;
 }
 
 // Once read, set the ModuleFile bit base offset and update the size in
@@ -5605,17 

[clang] 766a08d - [Frontend] Only compile modules if not already finalized

2021-07-15 Thread Volodymyr Sapsai via cfe-commits

Author: Ben Barham
Date: 2021-07-15T18:27:08-07:00
New Revision: 766a08df12c111b15ed51d0fcac06042d2f68cd6

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

LOG: [Frontend] Only compile modules if not already finalized

It was possible to re-add a module to a shared in-memory module cache
when search paths are changed. This can eventually cause a crash if the
original module is referenced after this occurs.
  1. Module A depends on B
  2. B exists in two paths C and D
  3. First run only has C on the search path, finds A and B and loads
 them
  4. Second run adds D to the front of the search path. A is loaded and
 contains a reference to the already compiled module from C. But
 searching finds the module from D instead, causing a mismatch
  5. B and the modules that depend on it are considered out of date and
 thus rebuilt
  6. The recompiled module A is added to the in-memory cache, freeing
 the previously inserted one

This can never occur from a regular clang process, but is very easy to
do through the API - whether through the use of a shared case or just
running multiple compilations from a single `CompilerInstance`. Update
the compilation to return early if a module is already finalized so that
the pre-condition in the in-memory module cache holds.

Resolves rdar://78180255

Differential Revision: https://reviews.llvm.org/D105328

Added: 
clang/unittests/Serialization/ModuleCacheTest.cpp

Modified: 
clang/include/clang/Basic/DiagnosticCommonKinds.td
clang/include/clang/Basic/DiagnosticSerializationKinds.td
clang/include/clang/Serialization/ASTReader.h
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Serialization/ASTReader.cpp
clang/unittests/Serialization/CMakeLists.txt

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td 
b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index eea5d8eaa10a1..4dff3379ed35b 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -111,6 +111,8 @@ def err_module_cycle : Error<"cyclic dependency in module 
'%0': %1">,
   DefaultFatal;
 def err_module_prebuilt : Error<
   "error in loading module '%0' from prebuilt module path">, DefaultFatal;
+def err_module_rebuild_finalized : Error<
+  "cannot rebuild module '%0' as it is already finalized">, DefaultFatal;
 def note_pragma_entered_here : Note<"#pragma entered here">;
 def note_decl_hiding_tag_type : Note<
   "%1 %0 is hidden by a non-type declaration of %0 here">;

diff  --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td 
b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index ce48833a87030..bf3221be004de 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -69,6 +69,9 @@ def err_module_file_not_module : Error<
   "AST file '%0' was not built as a module">, DefaultFatal;
 def err_module_file_missing_top_level_submodule : Error<
   "module file '%0' is missing its top-level submodule">, DefaultFatal;
+def note_module_file_conflict : Note<
+  "this is generally caused by modules with the same name found in multiple "
+  "paths">;
 
 def remark_module_import : Remark<
   "importing module '%0'%select{| into '%3'}2 from '%1'">,

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index 6932d9c86d0cc..4819a5aecefaf 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1401,6 +1401,9 @@ class ASTReader
   llvm::iterator_range
   getModulePreprocessedEntities(ModuleFile ) const;
 
+  bool canRecoverFromOutOfDate(StringRef ModuleFileName,
+   unsigned ClientLoadCapabilities);
+
 public:
   class ModuleDeclIterator
   : public llvm::iterator_adaptor_base<

diff  --git a/clang/lib/Frontend/CompilerInstance.cpp 
b/clang/lib/Frontend/CompilerInstance.cpp
index a6e2329c8864a..c642af1849bc4 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1054,6 +1054,15 @@ compileModuleImpl(CompilerInstance , 
SourceLocation ImportLoc,
   [](CompilerInstance &) {}) {
   llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
 
+  // Never compile a module that's already finalized - this would cause the
+  // existing module to be freed, causing crashes if it is later referenced
+  if (ImportingInstance.getModuleCache().isPCMFinal(ModuleFileName)) {
+ImportingInstance.getDiagnostics().Report(
+ImportLoc, diag::err_module_rebuild_finalized)
+<< ModuleName;
+return false;
+  }
+
   // Construct a compiler invocation for creating 

[clang] 722c514 - [clang][AST] Make `getLocalOrImportedSubmoduleID` work with const `Module*`. NFC.

2021-06-17 Thread Volodymyr Sapsai via cfe-commits

Author: Volodymyr Sapsai
Date: 2021-06-17T17:29:12-07:00
New Revision: 722c51473c7a3bfe13d929734615a3b46d44c09a

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

LOG: [clang][AST] Make `getLocalOrImportedSubmoduleID` work with const 
`Module*`. NFC.

Differential Revision: https://reviews.llvm.org/D104350

Added: 


Modified: 
clang/include/clang/Serialization/ASTWriter.h
clang/lib/Serialization/ASTWriter.cpp

Removed: 




diff  --git a/clang/include/clang/Serialization/ASTWriter.h 
b/clang/include/clang/Serialization/ASTWriter.h
index a7a659637902e..e4d92f0b0515c 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -450,7 +450,7 @@ class ASTWriter : public ASTDeserializationListener,
 
   /// A mapping from each known submodule to its ID number, which will
   /// be a positive integer.
-  llvm::DenseMap SubmoduleIDs;
+  llvm::DenseMap SubmoduleIDs;
 
   /// A list of the module file extension writers.
   std::vector>
@@ -671,7 +671,7 @@ class ASTWriter : public ASTDeserializationListener,
   /// Retrieve or create a submodule ID for this module, or return 0 if
   /// the submodule is neither local (a submodle of the currently-written 
module)
   /// nor from an imported module.
-  unsigned getLocalOrImportedSubmoduleID(Module *Mod);
+  unsigned getLocalOrImportedSubmoduleID(const Module *Mod);
 
   /// Note that the identifier II occurs at the given offset
   /// within the identifier table.

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 4cdcf53775de1..ca169c010555c 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -2476,11 +2476,11 @@ void 
ASTWriter::WritePreprocessorDetail(PreprocessingRecord ,
   }
 }
 
-unsigned ASTWriter::getLocalOrImportedSubmoduleID(Module *Mod) {
+unsigned ASTWriter::getLocalOrImportedSubmoduleID(const Module *Mod) {
   if (!Mod)
 return 0;
 
-  llvm::DenseMap::iterator Known = SubmoduleIDs.find(Mod);
+  auto Known = SubmoduleIDs.find(Mod);
   if (Known != SubmoduleIDs.end())
 return Known->second;
 



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


  1   2   3   >