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 <bakal...@google.com> Date: Thu, 9 Jan 2025 09:36:35 +0100 Subject: [PATCH 1/8] [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@foo.h:8 {{attribute declaration must precede definition}} -#include "foo.h" // expected-note@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 <bakal...@google.com> Date: Thu, 9 Jan 2025 15:13:14 +0100 Subject: [PATCH 2/8] [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 <bakal...@google.com> Date: Thu, 9 Jan 2025 17:48:18 +0100 Subject: [PATCH 3/8] [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 <bakal...@google.com> Date: Thu, 9 Jan 2025 17:58:54 +0100 Subject: [PATCH 4/8] [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 <bakal...@google.com> Date: Thu, 9 Jan 2025 18:12:52 +0100 Subject: [PATCH 5/8] [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 <bakal...@google.com> Date: Fri, 10 Jan 2025 11:21:05 +0100 Subject: [PATCH 6/8] [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 <bakal...@google.com> Date: Fri, 10 Jan 2025 11:30:57 +0100 Subject: [PATCH 7/8] [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'}} >From 97220d3c12b84aaddafb89223e0505e39820d36e Mon Sep 17 00:00:00 2001 From: Viktoriia Bakalova <bakal...@google.com> Date: Fri, 10 Jan 2025 11:57:50 +0100 Subject: [PATCH 8/8] [WIP] Formatting. --- clang/lib/Serialization/ASTReaderDecl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index e840a4ac191e28..b9b73d1646bb7e 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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits