[clang] [WIP] [Modules] Delay reading type source info of the preferred_name attribute. (PR #122250)
Viktoriia Bakalova via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 10 02:31:13 PST 2025
https://github.com/VitaNuo updated https://github.com/llvm/llvm-project/pull/122250
>From 0a615576181a538bc0d8eff6499ad87cbdeb89c3 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Thu, 9 Jan 2025 09:36:35 +0100
Subject: [PATCH 1/7] [WIP] Delay reading type source info of the
preferred_name attribute.
---
clang/include/clang/Serialization/ASTReader.h | 18 ++++-
.../clang/Serialization/ASTRecordReader.h | 7 ++
clang/lib/Serialization/ASTReader.cpp | 25 +++++++
clang/lib/Serialization/ASTReaderDecl.cpp | 72 ++++++++++++++++---
clang/lib/Serialization/ASTWriter.cpp | 5 +-
clang/test/Modules/preferred_name.cppm | 13 ----
clang/test/Modules/preferred_name_2.cppm | 47 ++++++++++++
7 files changed, 163 insertions(+), 24 deletions(-)
create mode 100644 clang/test/Modules/preferred_name_2.cppm
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index f739fe688c110d..3c79a4c86a5617 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -13,7 +13,10 @@
#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
+#include "clang/AST/DeclID.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/IdentifierTable.h"
@@ -1156,6 +1159,19 @@ class ASTReader
SmallVector<std::pair<VarDecl *, serialization::TypeID>, 16>
PendingDeducedVarTypes;
+ struct PendingPreferredNameAttribute {
+ Decl* D;
+ AttributeCommonInfo Info;
+ serialization::TypeID TypeID;
+ bool isInherited;
+ bool isImplicit;
+ bool isPackExpansion;
+ SourceLocation ElaboratedTypedefSourceLocation;
+ NestedNameSpecifierLoc NNS;
+ SourceLocation TypedefSourceLocation;
+ };
+ std::deque<PendingPreferredNameAttribute> PendingPreferredNameAttributes;
+
/// The list of redeclaration chains that still need to be
/// reconstructed, and the local offset to the corresponding list
/// of redeclarations.
@@ -1419,7 +1435,7 @@ class ASTReader
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;
-private:
+ private:
struct ImportedModule {
ModuleFile *Mod;
ModuleFile *ImportedBy;
diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h
index 2561418b78ca7f..f476d72fcf9e71 100644
--- a/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/clang/include/clang/Serialization/ASTRecordReader.h
@@ -337,6 +337,13 @@ class ASTRecordReader
/// Reads attributes from the current stream position, advancing Idx.
void readAttributes(AttrVec &Attrs);
+ /// Reads one attribute from the current stream position, advancing Idx.
+ Attr *readAttr(Decl *D);
+
+ /// Reads attributes from the current stream position, advancing Idx.
+ void readAttributes(AttrVec &Attrs, Decl *D);
+
+
/// Read an BTFTypeTagAttr object.
BTFTypeTagAttr *readBTFTypeTagAttr() {
return cast<BTFTypeTagAttr>(readAttr());
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index ec85fad3389a1c..4ee04552f13a96 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -23,6 +23,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclID.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
@@ -41,6 +42,7 @@
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/ASTSourceDescriptor.h"
+#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticError.h"
@@ -9860,6 +9862,29 @@ void ASTReader::finishPendingActions() {
}
PendingDeducedVarTypes.clear();
+ ASTContext &Context = getContext();
+ for (unsigned I = 0; I != PendingPreferredNameAttributes.size(); ++I) {
+ auto *D = PendingPreferredNameAttributes[I].D;
+ QualType InfoTy = GetType(PendingPreferredNameAttributes[I].TypeID);
+ TypeSourceInfo *TInfo = nullptr;
+ if (!InfoTy.isNull()) {
+ TInfo = getContext().CreateTypeSourceInfo(InfoTy);
+ // TODO - this piece doesn't work yet
+ ElaboratedTypeLoc &Loc = (ElaboratedTypeLoc)TInfo->getTypeLoc();
+ Loc.setElaboratedKeywordLoc(PendingPreferredNameAttributes[I].ElaboratedTypedefSourceLocation);
+ Loc.setQualifierLoc(PendingPreferredNameAttributes[I].NNS);
+ Loc.setNameLoc(PendingPreferredNameAttributes[I].TypedefSourceLocation);
+ }
+
+ AttrVec &Attrs = getContext().getDeclAttrs(D);
+ PreferredNameAttr *New = new (Context) PreferredNameAttr(Context, PendingPreferredNameAttributes[I].Info, TInfo);
+ cast<InheritableAttr>(New)->setInherited(PendingPreferredNameAttributes[I].isInherited);
+ New->setImplicit(PendingPreferredNameAttributes[I].isImplicit);
+ New->setPackExpansion(PendingPreferredNameAttributes[I].isPackExpansion);
+ Attrs.push_back(New);
+ }
+ PendingPreferredNameAttributes.clear();
+
// For each decl chain that we wanted to complete while deserializing, mark
// it as "still needs to be completed".
for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) {
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 6ece3ba7af9f4b..5e67f4fa8bf107 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -22,6 +22,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclID.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
@@ -638,7 +639,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
if (HasAttrs) {
AttrVec Attrs;
- Record.readAttributes(Attrs);
+ Record.readAttributes(Attrs, D);
// Avoid calling setAttrs() directly because it uses Decl::getASTContext()
// internally which is unsafe during derialization.
D->setAttrsImpl(Attrs, Reader.getContext());
@@ -725,12 +726,12 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
RedeclarableResult ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
RedeclarableResult Redecl = VisitRedeclarable(TD);
VisitTypeDecl(TD);
- TypeSourceInfo *TInfo = readTypeSourceInfo();
- if (Record.readInt()) { // isModed
- QualType modedT = Record.readType();
- TD->setModedTypeSourceInfo(TInfo, modedT);
- } else
- TD->setTypeSourceInfo(TInfo);
+ TypeSourceInfo *TInfo = readTypeSourceInfo();
+ if (Record.readInt()) { // isModed
+ QualType modedT = Record.readType();
+ TD->setModedTypeSourceInfo(TInfo, modedT);
+ } else
+ TD->setTypeSourceInfo(TInfo);
// Read and discard the declaration for which this is a typedef name for
// linkage, if it exists. We cannot rely on our type to pull in this decl,
// because it might have been merged with a type from another module and
@@ -3167,6 +3168,54 @@ Attr *ASTRecordReader::readAttr() {
return New;
}
+Attr *ASTRecordReader::readAttr(Decl *D) {
+ AttrReader Record(*this);
+ auto V = Record.readInt();
+ if (!V)
+ return nullptr;
+
+ Attr *New = nullptr;
+ // Kind is stored as a 1-based integer because 0 is used to indicate a null
+ // Attr pointer.
+ auto Kind = static_cast<attr::Kind>(V - 1);
+ ASTContext &Context = getContext();
+
+ IdentifierInfo *AttrName = Record.readIdentifier();
+ IdentifierInfo *ScopeName = Record.readIdentifier();
+ SourceRange AttrRange = Record.readSourceRange();
+ SourceLocation ScopeLoc = Record.readSourceLocation();
+ unsigned ParsedKind = Record.readInt();
+ unsigned Syntax = Record.readInt();
+ unsigned SpellingIndex = Record.readInt();
+ bool IsAlignas = (ParsedKind == AttributeCommonInfo::AT_Aligned &&
+ Syntax == AttributeCommonInfo::AS_Keyword &&
+ SpellingIndex == AlignedAttr::Keyword_alignas);
+ bool IsRegularKeywordAttribute = Record.readBool();
+
+ AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
+ AttributeCommonInfo::Kind(ParsedKind),
+ {AttributeCommonInfo::Syntax(Syntax), SpellingIndex,
+ IsAlignas, IsRegularKeywordAttribute});
+ if (Kind == attr::PreferredName) {
+ bool isInherited = Record.readInt();
+ bool isImplicit = Record.readInt();
+ bool isPackExpansion = Record.readInt();
+
+
+ serialization::TypeID TypeID = getGlobalTypeID(Record.readInt());
+ SourceLocation SL = Record.readSourceLocation();
+ NestedNameSpecifierLoc NNL = readNestedNameSpecifierLoc();
+ SourceLocation TSL = Record.readSourceLocation();
+ Reader->PendingPreferredNameAttributes.push_back({D, Info, TypeID, isInherited, isImplicit, isPackExpansion, SL, NNL, TSL});
+ return nullptr;
+ }
+
+#include "clang/Serialization/AttrPCHRead.inc"
+
+ assert(New && "Unable to decode attribute?");
+ return New;
+}
+
/// Reads attributes from the current stream position.
void ASTRecordReader::readAttributes(AttrVec &Attrs) {
for (unsigned I = 0, E = readInt(); I != E; ++I)
@@ -3174,6 +3223,12 @@ void ASTRecordReader::readAttributes(AttrVec &Attrs) {
Attrs.push_back(A);
}
+void ASTRecordReader::readAttributes(AttrVec &Attrs, Decl* D) {
+ for (unsigned I = 0, E = readInt(); I != E; ++I)
+ if (auto *A = readAttr(D))
+ Attrs.push_back(A);
+}
+
//===----------------------------------------------------------------------===//
// ASTReader Implementation
//===----------------------------------------------------------------------===//
@@ -3572,7 +3627,7 @@ void mergeInheritableAttributes(ASTReader &Reader, Decl *D, Decl *Previous) {
template<typename DeclT>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
Redeclarable<DeclT> *D,
- Decl *Previous, Decl *Canon) {
+ Decl *Previous, Decl *Canon) {
D->RedeclLink.setPrevious(cast<DeclT>(Previous));
D->First = cast<DeclT>(Previous)->First;
}
@@ -4199,6 +4254,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID))
return nullptr;
}
+ // This is the crashing line.
assert(Record.getIdx() == Record.size());
// Load any relevant update records.
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a52d59c61c4ce6..a259a55cd397a6 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4720,8 +4720,9 @@ void ASTRecordWriter::AddAttr(const Attr *A) {
// FIXME: Clang can't handle the serialization/deserialization of
// preferred_name properly now. See
// https://github.com/llvm/llvm-project/issues/56490 for example.
- if (!A || (isa<PreferredNameAttr>(A) &&
- Writer->isWritingStdCXXNamedModules()))
+ if (!A)
+ // if (!A || (isa<PreferredNameAttr>(A) &&
+ // Writer->isWritingStdCXXNamedModules()))
return Record.push_back(0);
Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs
diff --git a/clang/test/Modules/preferred_name.cppm b/clang/test/Modules/preferred_name.cppm
index 806781a81c5ca7..255e915f824c8d 100644
--- a/clang/test/Modules/preferred_name.cppm
+++ b/clang/test/Modules/preferred_name.cppm
@@ -16,8 +16,6 @@
//
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o %t/A.pcm
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use1.cpp -verify -fsyntax-only
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use2.cpp -verify -fsyntax-only
//
//--- foo.h
template<class _CharT>
@@ -42,7 +40,6 @@ inline foo_templ<char> bar()
module;
#include "foo.h"
export module A;
-export using ::foo_templ;
//--- Use.cppm
// expected-no-diagnostics
@@ -50,13 +47,3 @@ module;
#include "foo.h"
export module Use;
import A;
-export using ::foo_templ;
-
-//--- Use1.cpp
-import A; // expected-warning at foo.h:8 {{attribute declaration must precede definition}}
-#include "foo.h" // expected-note at foo.h:9 {{previous definition is here}}
-
-//--- Use2.cpp
-// expected-no-diagnostics
-#include "foo.h"
-import A;
diff --git a/clang/test/Modules/preferred_name_2.cppm b/clang/test/Modules/preferred_name_2.cppm
new file mode 100644
index 00000000000000..b1d1c5a49b39ce
--- /dev/null
+++ b/clang/test/Modules/preferred_name_2.cppm
@@ -0,0 +1,47 @@
+// Tests that the ODR check wouldn't produce false-positive result for preferred_name attribute.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use1.cpp -verify -fsyntax-only
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use2.cpp -verify -fsyntax-only
+
+// Test again with reduced BMI.
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o %t/A.pcm
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
+//
+//--- foo.h
+template<class _CharT>
+class foo_templ;
+
+typedef foo_templ<char> foo;
+
+template<class _CharT>
+class foo_templ {
+public:
+ foo_templ() {}
+};
+
+inline foo_templ<char> bar()
+{
+ return foo_templ<char>();
+}
+
+//--- A.cppm
+module;
+#include "foo.h"
+export module A;
+
+//--- Use.cppm
+// expected-no-diagnostics
+module;
+#include "foo.h"
+export module Use;
+import A;
>From b9670533a4dca0150bd854a207792bdaab0bd096 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Thu, 9 Jan 2025 15:13:14 +0100
Subject: [PATCH 2/7] [WIP] Set type on the attribute in finish pending
actions.
---
clang/lib/Serialization/ASTReader.cpp | 11 +++++++----
clang/lib/Serialization/ASTReaderDecl.cpp | 2 --
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 4ee04552f13a96..c8a42471af819e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9870,10 +9870,13 @@ void ASTReader::finishPendingActions() {
if (!InfoTy.isNull()) {
TInfo = getContext().CreateTypeSourceInfo(InfoTy);
// TODO - this piece doesn't work yet
- ElaboratedTypeLoc &Loc = (ElaboratedTypeLoc)TInfo->getTypeLoc();
- Loc.setElaboratedKeywordLoc(PendingPreferredNameAttributes[I].ElaboratedTypedefSourceLocation);
- Loc.setQualifierLoc(PendingPreferredNameAttributes[I].NNS);
- Loc.setNameLoc(PendingPreferredNameAttributes[I].TypedefSourceLocation);
+ if (auto Loc = TInfo->getTypeLoc().getAs<ElaboratedTypeLoc>()) {
+ Loc.setElaboratedKeywordLoc(PendingPreferredNameAttributes[I].ElaboratedTypedefSourceLocation);
+ Loc.setQualifierLoc(PendingPreferredNameAttributes[I].NNS);
+ if (auto TypedefLoc = Loc.getNextTypeLoc().getAs<TypedefTypeLoc>()) {
+ TypedefLoc.setNameLoc(PendingPreferredNameAttributes[I].TypedefSourceLocation);
+ }
+ }
}
AttrVec &Attrs = getContext().getDeclAttrs(D);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 5e67f4fa8bf107..5874b062bcd894 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3200,8 +3200,6 @@ Attr *ASTRecordReader::readAttr(Decl *D) {
bool isInherited = Record.readInt();
bool isImplicit = Record.readInt();
bool isPackExpansion = Record.readInt();
-
-
serialization::TypeID TypeID = getGlobalTypeID(Record.readInt());
SourceLocation SL = Record.readSourceLocation();
NestedNameSpecifierLoc NNL = readNestedNameSpecifierLoc();
>From 183a54da325fd3175101b70b26066de520140cb2 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Thu, 9 Jan 2025 17:48:18 +0100
Subject: [PATCH 3/7] [WIP] Reduce code duplication.
---
clang/lib/Serialization/ASTReader.cpp | 1 -
clang/lib/Serialization/ASTReaderDecl.cpp | 114 +++++++++++-----------
clang/test/Modules/preferred_name.cppm | 14 +++
clang/test/Modules/preferred_name_2.cppm | 47 ---------
4 files changed, 70 insertions(+), 106 deletions(-)
delete mode 100644 clang/test/Modules/preferred_name_2.cppm
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c8a42471af819e..5f7eba874fc94b 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9869,7 +9869,6 @@ void ASTReader::finishPendingActions() {
TypeSourceInfo *TInfo = nullptr;
if (!InfoTy.isNull()) {
TInfo = getContext().CreateTypeSourceInfo(InfoTy);
- // TODO - this piece doesn't work yet
if (auto Loc = TInfo->getTypeLoc().getAs<ElaboratedTypeLoc>()) {
Loc.setElaboratedKeywordLoc(PendingPreferredNameAttributes[I].ElaboratedTypedefSourceLocation);
Loc.setQualifierLoc(PendingPreferredNameAttributes[I].NNS);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 5874b062bcd894..c775155fdbf0a3 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -39,6 +39,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/AttrKinds.h"
+#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
@@ -63,6 +64,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Bitstream/BitstreamReader.h"
+#include "llvm/CGData/CodeGenData.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -3130,72 +3132,71 @@ class AttrReader {
OMPTraitInfo *readOMPTraitInfo() { return Reader.readOMPTraitInfo(); }
template <typename T> T *readDeclAs() { return Reader.readDeclAs<T>(); }
+
+ AttributeCommonInfo readAttributeCommonInfo() {
+ IdentifierInfo *AttrName = readIdentifier();
+ IdentifierInfo *ScopeName = readIdentifier();
+ SourceRange AttrRange = readSourceRange();
+ SourceLocation ScopeLoc = readSourceLocation();
+ unsigned ParsedKind = readInt();
+ unsigned Syntax = readInt();
+ unsigned SpellingIndex = readInt();
+ bool IsAlignas = (ParsedKind == AttributeCommonInfo::AT_Aligned &&
+ Syntax == AttributeCommonInfo::AS_Keyword &&
+ SpellingIndex == AlignedAttr::Keyword_alignas);
+ bool IsRegularKeywordAttribute = readBool();
+
+ AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
+ AttributeCommonInfo::Kind(ParsedKind),
+ {AttributeCommonInfo::Syntax(Syntax), SpellingIndex,
+ IsAlignas, IsRegularKeywordAttribute});
+ return Info;
+ }
+
+ std::optional<attr::Kind> readAttrKind() {
+ auto V = readInt();
+ if (!V)
+ return {};
+
+ // Kind is stored as a 1-based integer because 0 is used to indicate a null
+ // Attr pointer.
+ return static_cast<attr::Kind>(V - 1);
+ }
+
+ Attr *createAttribute(attr::Kind Kind, AttributeCommonInfo Info) {
+ ASTContext &Context = Reader.getContext();
+ Attr *New = nullptr;
+ auto Record = *this;
+ #include "clang/Serialization/AttrPCHRead.inc"
+
+ assert(New && "Unable to decode attribute?");
+ return New;
+ }
};
}
+
Attr *ASTRecordReader::readAttr() {
AttrReader Record(*this);
- auto V = Record.readInt();
- if (!V)
+ attr::Kind Kind;
+ if (auto KindOpt = Record.readAttrKind(); !KindOpt)
return nullptr;
+ else
+ Kind = *KindOpt;
- Attr *New = nullptr;
- // Kind is stored as a 1-based integer because 0 is used to indicate a null
- // Attr pointer.
- auto Kind = static_cast<attr::Kind>(V - 1);
- ASTContext &Context = getContext();
-
- IdentifierInfo *AttrName = Record.readIdentifier();
- IdentifierInfo *ScopeName = Record.readIdentifier();
- SourceRange AttrRange = Record.readSourceRange();
- SourceLocation ScopeLoc = Record.readSourceLocation();
- unsigned ParsedKind = Record.readInt();
- unsigned Syntax = Record.readInt();
- unsigned SpellingIndex = Record.readInt();
- bool IsAlignas = (ParsedKind == AttributeCommonInfo::AT_Aligned &&
- Syntax == AttributeCommonInfo::AS_Keyword &&
- SpellingIndex == AlignedAttr::Keyword_alignas);
- bool IsRegularKeywordAttribute = Record.readBool();
-
- AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
- AttributeCommonInfo::Kind(ParsedKind),
- {AttributeCommonInfo::Syntax(Syntax), SpellingIndex,
- IsAlignas, IsRegularKeywordAttribute});
-
-#include "clang/Serialization/AttrPCHRead.inc"
-
- assert(New && "Unable to decode attribute?");
- return New;
+ AttributeCommonInfo Info = Record.readAttributeCommonInfo();
+ return Record.createAttribute(Kind, Info);
}
Attr *ASTRecordReader::readAttr(Decl *D) {
AttrReader Record(*this);
- auto V = Record.readInt();
- if (!V)
+ attr::Kind Kind;
+ if (auto KindOpt = Record.readAttrKind(); !KindOpt)
return nullptr;
+ else
+ Kind = *KindOpt;
- Attr *New = nullptr;
- // Kind is stored as a 1-based integer because 0 is used to indicate a null
- // Attr pointer.
- auto Kind = static_cast<attr::Kind>(V - 1);
- ASTContext &Context = getContext();
-
- IdentifierInfo *AttrName = Record.readIdentifier();
- IdentifierInfo *ScopeName = Record.readIdentifier();
- SourceRange AttrRange = Record.readSourceRange();
- SourceLocation ScopeLoc = Record.readSourceLocation();
- unsigned ParsedKind = Record.readInt();
- unsigned Syntax = Record.readInt();
- unsigned SpellingIndex = Record.readInt();
- bool IsAlignas = (ParsedKind == AttributeCommonInfo::AT_Aligned &&
- Syntax == AttributeCommonInfo::AS_Keyword &&
- SpellingIndex == AlignedAttr::Keyword_alignas);
- bool IsRegularKeywordAttribute = Record.readBool();
-
- AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
- AttributeCommonInfo::Kind(ParsedKind),
- {AttributeCommonInfo::Syntax(Syntax), SpellingIndex,
- IsAlignas, IsRegularKeywordAttribute});
+ AttributeCommonInfo Info = Record.readAttributeCommonInfo();
if (Kind == attr::PreferredName) {
bool isInherited = Record.readInt();
bool isImplicit = Record.readInt();
@@ -3208,15 +3209,12 @@ Attr *ASTRecordReader::readAttr(Decl *D) {
return nullptr;
}
-#include "clang/Serialization/AttrPCHRead.inc"
-
- assert(New && "Unable to decode attribute?");
- return New;
+ return Record.createAttribute(Kind, Info);
}
/// Reads attributes from the current stream position.
void ASTRecordReader::readAttributes(AttrVec &Attrs) {
- for (unsigned I = 0, E = readInt(); I != E; ++I)
+ for (unsigned I = 0, E = readInt(); I != E; ++I)
if (auto *A = readAttr())
Attrs.push_back(A);
}
diff --git a/clang/test/Modules/preferred_name.cppm b/clang/test/Modules/preferred_name.cppm
index 255e915f824c8d..316eb6bd52c9bf 100644
--- a/clang/test/Modules/preferred_name.cppm
+++ b/clang/test/Modules/preferred_name.cppm
@@ -16,6 +16,8 @@
//
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o %t/A.pcm
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use1.cpp -verify -fsyntax-only
+// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use2.cpp -verify -fsyntax-only
//
//--- foo.h
template<class _CharT>
@@ -40,6 +42,7 @@ inline foo_templ<char> bar()
module;
#include "foo.h"
export module A;
+export using ::foo_templ;
//--- Use.cppm
// expected-no-diagnostics
@@ -47,3 +50,14 @@ module;
#include "foo.h"
export module Use;
import A;
+export using ::foo_templ;
+
+//--- Use1.cpp
+// expected-no-diagnostics
+import A;
+#include "foo.h"
+
+//--- Use2.cpp
+// expected-no-diagnostics
+#include "foo.h"
+import A;
diff --git a/clang/test/Modules/preferred_name_2.cppm b/clang/test/Modules/preferred_name_2.cppm
deleted file mode 100644
index b1d1c5a49b39ce..00000000000000
--- a/clang/test/Modules/preferred_name_2.cppm
+++ /dev/null
@@ -1,47 +0,0 @@
-// Tests that the ODR check wouldn't produce false-positive result for preferred_name attribute.
-//
-// RUN: rm -rf %t
-// RUN: mkdir -p %t
-// RUN: split-file %s %t
-//
-// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use1.cpp -verify -fsyntax-only
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use2.cpp -verify -fsyntax-only
-
-// Test again with reduced BMI.
-// RUN: rm -rf %t
-// RUN: mkdir -p %t
-// RUN: split-file %s %t
-//
-// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o %t/A.pcm
-// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/Use.cppm -verify -fsyntax-only
-//
-//--- foo.h
-template<class _CharT>
-class foo_templ;
-
-typedef foo_templ<char> foo;
-
-template<class _CharT>
-class foo_templ {
-public:
- foo_templ() {}
-};
-
-inline foo_templ<char> bar()
-{
- return foo_templ<char>();
-}
-
-//--- A.cppm
-module;
-#include "foo.h"
-export module A;
-
-//--- Use.cppm
-// expected-no-diagnostics
-module;
-#include "foo.h"
-export module Use;
-import A;
>From bffc6127f2779c9720fb4953c88550e6cfefcbc4 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Thu, 9 Jan 2025 17:58:54 +0100
Subject: [PATCH 4/7] [WIP] Cleanup.
---
clang/include/clang/Serialization/ASTReader.h | 2 +-
clang/lib/Serialization/ASTReader.cpp | 2 --
clang/lib/Serialization/ASTReaderDecl.cpp | 18 +++++++-----------
clang/lib/Serialization/ASTWriter.cpp | 2 --
4 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 3c79a4c86a5617..ba91bb9ab6cee0 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -1435,7 +1435,7 @@ class ASTReader
const serialization::reader::DeclContextLookupTable *
getLoadedLookupTables(DeclContext *Primary) const;
- private:
+private:
struct ImportedModule {
ModuleFile *Mod;
ModuleFile *ImportedBy;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 5f7eba874fc94b..e9d6b87b38d2ab 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -23,7 +23,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclGroup.h"
-#include "clang/AST/DeclID.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
@@ -42,7 +41,6 @@
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/ASTSourceDescriptor.h"
-#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticError.h"
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index c775155fdbf0a3..ebe2f24cc270c6 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -22,7 +22,6 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclID.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
@@ -39,7 +38,6 @@
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/AttrKinds.h"
-#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
@@ -64,7 +62,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Bitstream/BitstreamReader.h"
-#include "llvm/CGData/CodeGenData.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -728,12 +725,12 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
RedeclarableResult ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
RedeclarableResult Redecl = VisitRedeclarable(TD);
VisitTypeDecl(TD);
- TypeSourceInfo *TInfo = readTypeSourceInfo();
- if (Record.readInt()) { // isModed
- QualType modedT = Record.readType();
- TD->setModedTypeSourceInfo(TInfo, modedT);
- } else
- TD->setTypeSourceInfo(TInfo);
+ TypeSourceInfo *TInfo = readTypeSourceInfo();
+ if (Record.readInt()) { // isModed
+ QualType modedT = Record.readType();
+ TD->setModedTypeSourceInfo(TInfo, modedT);
+ } else
+ TD->setTypeSourceInfo(TInfo);
// Read and discard the declaration for which this is a typedef name for
// linkage, if it exists. We cannot rely on our type to pull in this decl,
// because it might have been merged with a type from another module and
@@ -3623,7 +3620,7 @@ void mergeInheritableAttributes(ASTReader &Reader, Decl *D, Decl *Previous) {
template<typename DeclT>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
Redeclarable<DeclT> *D,
- Decl *Previous, Decl *Canon) {
+ Decl *Previous, Decl *Canon) {
D->RedeclLink.setPrevious(cast<DeclT>(Previous));
D->First = cast<DeclT>(Previous)->First;
}
@@ -4250,7 +4247,6 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID))
return nullptr;
}
- // This is the crashing line.
assert(Record.getIdx() == Record.size());
// Load any relevant update records.
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index a259a55cd397a6..370b05eb1bc16b 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4721,8 +4721,6 @@ void ASTRecordWriter::AddAttr(const Attr *A) {
// preferred_name properly now. See
// https://github.com/llvm/llvm-project/issues/56490 for example.
if (!A)
- // if (!A || (isa<PreferredNameAttr>(A) &&
- // Writer->isWritingStdCXXNamedModules()))
return Record.push_back(0);
Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs
>From 487f6d01b9d5b57fa0b56d6816db4cf7f29fae7c Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Thu, 9 Jan 2025 18:12:52 +0100
Subject: [PATCH 5/7] [WIP] Cleanup.
---
clang/include/clang/Serialization/ASTReader.h | 9 +++---
.../clang/Serialization/ASTRecordReader.h | 1 -
clang/lib/Serialization/ASTReader.cpp | 16 +++++-----
clang/lib/Serialization/ASTReaderDecl.cpp | 30 ++++++++++---------
4 files changed, 29 insertions(+), 27 deletions(-)
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index ba91bb9ab6cee0..d1491e1f9e426f 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -13,7 +13,6 @@
#ifndef LLVM_CLANG_SERIALIZATION_ASTREADER_H
#define LLVM_CLANG_SERIALIZATION_ASTREADER_H
-#include "clang/AST/DeclID.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttributeCommonInfo.h"
@@ -1160,15 +1159,15 @@ class ASTReader
PendingDeducedVarTypes;
struct PendingPreferredNameAttribute {
- Decl* D;
+ Decl *D;
AttributeCommonInfo Info;
serialization::TypeID TypeID;
bool isInherited;
bool isImplicit;
bool isPackExpansion;
- SourceLocation ElaboratedTypedefSourceLocation;
- NestedNameSpecifierLoc NNS;
- SourceLocation TypedefSourceLocation;
+ SourceLocation ElaboratedTypedefSL;
+ NestedNameSpecifierLoc NestedNameSL;
+ SourceLocation TypedefSL;
};
std::deque<PendingPreferredNameAttribute> PendingPreferredNameAttributes;
diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h
index f476d72fcf9e71..3d1e25161a4d73 100644
--- a/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/clang/include/clang/Serialization/ASTRecordReader.h
@@ -343,7 +343,6 @@ class ASTRecordReader
/// Reads attributes from the current stream position, advancing Idx.
void readAttributes(AttrVec &Attrs, Decl *D);
-
/// Read an BTFTypeTagAttr object.
BTFTypeTagAttr *readBTFTypeTagAttr() {
return cast<BTFTypeTagAttr>(readAttr());
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e9d6b87b38d2ab..fae9440d274495 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9868,17 +9868,19 @@ void ASTReader::finishPendingActions() {
if (!InfoTy.isNull()) {
TInfo = getContext().CreateTypeSourceInfo(InfoTy);
if (auto Loc = TInfo->getTypeLoc().getAs<ElaboratedTypeLoc>()) {
- Loc.setElaboratedKeywordLoc(PendingPreferredNameAttributes[I].ElaboratedTypedefSourceLocation);
- Loc.setQualifierLoc(PendingPreferredNameAttributes[I].NNS);
- if (auto TypedefLoc = Loc.getNextTypeLoc().getAs<TypedefTypeLoc>()) {
- TypedefLoc.setNameLoc(PendingPreferredNameAttributes[I].TypedefSourceLocation);
- }
+ Loc.setElaboratedKeywordLoc(
+ PendingPreferredNameAttributes[I].ElaboratedTypedefSL);
+ Loc.setQualifierLoc(PendingPreferredNameAttributes[I].NestedNameSL);
+ if (auto TypedefLoc = Loc.getNextTypeLoc().getAs<TypedefTypeLoc>())
+ TypedefLoc.setNameLoc(PendingPreferredNameAttributes[I].TypedefSL);
}
}
AttrVec &Attrs = getContext().getDeclAttrs(D);
- PreferredNameAttr *New = new (Context) PreferredNameAttr(Context, PendingPreferredNameAttributes[I].Info, TInfo);
- cast<InheritableAttr>(New)->setInherited(PendingPreferredNameAttributes[I].isInherited);
+ PreferredNameAttr *New = new (Context) PreferredNameAttr(
+ Context, PendingPreferredNameAttributes[I].Info, TInfo);
+ cast<InheritableAttr>(New)->setInherited(
+ PendingPreferredNameAttributes[I].isInherited);
New->setImplicit(PendingPreferredNameAttributes[I].isImplicit);
New->setPackExpansion(PendingPreferredNameAttributes[I].isPackExpansion);
Attrs.push_back(New);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index ebe2f24cc270c6..b9b73d1646bb7e 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3144,9 +3144,10 @@ class AttrReader {
bool IsRegularKeywordAttribute = readBool();
AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc,
- AttributeCommonInfo::Kind(ParsedKind),
- {AttributeCommonInfo::Syntax(Syntax), SpellingIndex,
- IsAlignas, IsRegularKeywordAttribute});
+ AttributeCommonInfo::Kind(ParsedKind),
+ {AttributeCommonInfo::Syntax(Syntax),
+ SpellingIndex, IsAlignas,
+ IsRegularKeywordAttribute});
return Info;
}
@@ -3164,21 +3165,20 @@ class AttrReader {
ASTContext &Context = Reader.getContext();
Attr *New = nullptr;
auto Record = *this;
- #include "clang/Serialization/AttrPCHRead.inc"
+#include "clang/Serialization/AttrPCHRead.inc"
assert(New && "Unable to decode attribute?");
return New;
}
};
-}
-
+} // namespace
Attr *ASTRecordReader::readAttr() {
AttrReader Record(*this);
attr::Kind Kind;
if (auto KindOpt = Record.readAttrKind(); !KindOpt)
return nullptr;
- else
+ else
Kind = *KindOpt;
AttributeCommonInfo Info = Record.readAttributeCommonInfo();
@@ -3190,7 +3190,7 @@ Attr *ASTRecordReader::readAttr(Decl *D) {
attr::Kind Kind;
if (auto KindOpt = Record.readAttrKind(); !KindOpt)
return nullptr;
- else
+ else
Kind = *KindOpt;
AttributeCommonInfo Info = Record.readAttributeCommonInfo();
@@ -3199,10 +3199,12 @@ Attr *ASTRecordReader::readAttr(Decl *D) {
bool isImplicit = Record.readInt();
bool isPackExpansion = Record.readInt();
serialization::TypeID TypeID = getGlobalTypeID(Record.readInt());
- SourceLocation SL = Record.readSourceLocation();
- NestedNameSpecifierLoc NNL = readNestedNameSpecifierLoc();
- SourceLocation TSL = Record.readSourceLocation();
- Reader->PendingPreferredNameAttributes.push_back({D, Info, TypeID, isInherited, isImplicit, isPackExpansion, SL, NNL, TSL});
+ SourceLocation ElaboratedTypedefSL = Record.readSourceLocation();
+ NestedNameSpecifierLoc NestedNameSL = readNestedNameSpecifierLoc();
+ SourceLocation TypedefSL = Record.readSourceLocation();
+ Reader->PendingPreferredNameAttributes.push_back(
+ {D, Info, TypeID, isInherited, isImplicit, isPackExpansion,
+ ElaboratedTypedefSL, NestedNameSL, TypedefSL});
return nullptr;
}
@@ -3211,12 +3213,12 @@ Attr *ASTRecordReader::readAttr(Decl *D) {
/// Reads attributes from the current stream position.
void ASTRecordReader::readAttributes(AttrVec &Attrs) {
- for (unsigned I = 0, E = readInt(); I != E; ++I)
+ for (unsigned I = 0, E = readInt(); I != E; ++I)
if (auto *A = readAttr())
Attrs.push_back(A);
}
-void ASTRecordReader::readAttributes(AttrVec &Attrs, Decl* D) {
+void ASTRecordReader::readAttributes(AttrVec &Attrs, Decl *D) {
for (unsigned I = 0, E = readInt(); I != E; ++I)
if (auto *A = readAttr(D))
Attrs.push_back(A);
>From 50f4ea774cb35dbbf51d2fb267b3f938a6b920a6 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Fri, 10 Jan 2025 11:21:05 +0100
Subject: [PATCH 6/7] [WIP] Add test case.
---
clang/lib/Serialization/ASTReaderDecl.cpp | 2 +-
clang/test/Modules/preferred_name.cppm | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index b9b73d1646bb7e..e840a4ac191e28 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -3165,7 +3165,7 @@ class AttrReader {
ASTContext &Context = Reader.getContext();
Attr *New = nullptr;
auto Record = *this;
-#include "clang/Serialization/AttrPCHRead.inc"
+ #include "clang/Serialization/AttrPCHRead.inc"
assert(New && "Unable to decode attribute?");
return New;
diff --git a/clang/test/Modules/preferred_name.cppm b/clang/test/Modules/preferred_name.cppm
index 316eb6bd52c9bf..e66119deb820b6 100644
--- a/clang/test/Modules/preferred_name.cppm
+++ b/clang/test/Modules/preferred_name.cppm
@@ -61,3 +61,9 @@ import A;
// expected-no-diagnostics
#include "foo.h"
import A;
+
+//--- Use3.cpp
+#include "foo.h"
+import A;
+foo test;
+int size = test.size(); // expected-error {{no member named 'size' in 'foo'}}
\ No newline at end of file
>From 7d92fb265a9f0d23e06fad9d20b0815e7feceb05 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Fri, 10 Jan 2025 11:30:57 +0100
Subject: [PATCH 7/7] [WIP] Cleanup and comments.
---
clang/include/clang/Serialization/ASTRecordReader.h | 2 ++
clang/test/Modules/preferred_name.cppm | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h
index 3d1e25161a4d73..10ea3e497d6c37 100644
--- a/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/clang/include/clang/Serialization/ASTRecordReader.h
@@ -338,9 +338,11 @@ class ASTRecordReader
void readAttributes(AttrVec &Attrs);
/// Reads one attribute from the current stream position, advancing Idx.
+ /// Parent Decl is provided to delay attribute deserialization.
Attr *readAttr(Decl *D);
/// Reads attributes from the current stream position, advancing Idx.
+ /// Parent Decl is provided to delay attribute deserialization.
void readAttributes(AttrVec &Attrs, Decl *D);
/// Read an BTFTypeTagAttr object.
diff --git a/clang/test/Modules/preferred_name.cppm b/clang/test/Modules/preferred_name.cppm
index e66119deb820b6..7f280ca74bb31d 100644
--- a/clang/test/Modules/preferred_name.cppm
+++ b/clang/test/Modules/preferred_name.cppm
@@ -66,4 +66,4 @@ import A;
#include "foo.h"
import A;
foo test;
-int size = test.size(); // expected-error {{no member named 'size' in 'foo'}}
\ No newline at end of file
+int size = test.size(); // expected-error {{no member named 'size' in 'foo'}}
More information about the cfe-commits
mailing list