llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: None (divVerent) <details> <summary>Changes</summary> Also deserialize them back again on reading. The implementation is based on the existing implementation of `#pragma weak` serialization. Fixes issue #<!-- -->186742. --- Full diff: https://github.com/llvm/llvm-project/pull/186755.diff 13 Files Affected: - (modified) clang/include/clang/Sema/ExternalSemaSource.h (+10) - (modified) clang/include/clang/Sema/MultiplexExternalSemaSource.h (+11) - (modified) clang/include/clang/Sema/Sema.h (+4) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+3) - (modified) clang/include/clang/Serialization/ASTReader.h (+11-1) - (modified) clang/lib/Sema/MultiplexExternalSemaSource.cpp (+6) - (modified) clang/lib/Sema/Sema.cpp (+9) - (modified) clang/lib/Sema/SemaDecl.cpp (+4) - (modified) clang/lib/Serialization/ASTReader.cpp (+44) - (modified) clang/lib/Serialization/ASTWriter.cpp (+26) - (added) clang/test/PCH/pragma-redefine-extname.c (+14) - (added) clang/test/PCH/pragma-redefine-extname.h (+5) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h (+7) ``````````diff diff --git a/clang/include/clang/Sema/ExternalSemaSource.h b/clang/include/clang/Sema/ExternalSemaSource.h index 11cd69df88d1c..e7e66bea8c6bd 100644 --- a/clang/include/clang/Sema/ExternalSemaSource.h +++ b/clang/include/clang/Sema/ExternalSemaSource.h @@ -163,6 +163,16 @@ class ExternalSemaSource : public ExternalASTSource { virtual void ReadWeakUndeclaredIdentifiers( SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {} + /// Read the set of #pragma redefine_extname'd, undeclared identifiers known + /// to the external Sema source. + /// + /// The external source should append its own #pragma redefine_extname'd, + /// undeclared identifiers to the given vector. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same identifiers repeatedly. + virtual void ReadExtnameUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, AsmLabelAttr *>> &EI) {} + /// Read the set of used vtables known to the external Sema source. /// /// The external source should append its own used vtables to the given diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 8bcaa121b3039..12015724b39f4 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -310,6 +310,17 @@ class MultiplexExternalSemaSource : public ExternalSemaSource { void ReadWeakUndeclaredIdentifiers( SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override; + /// Read the set of #pragma redefine_extname'd, undeclared identifiers known + /// to the external Sema source. + /// + /// The external source should append its own #pragma redefine_extname'd, + /// undeclared identifiers to the given vector. Note that this routine may be + /// invoked multiple times; the external source should take care not to + /// introduce the same identifiers repeatedly. + void ReadExtnameUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, AsmLabelAttr *>> &EI) + override; + /// Read the set of used vtables known to the external Sema source. /// /// The external source should append its own used vtables to the given diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 832e46286194a..638c1be16f835 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -968,6 +968,10 @@ class Sema final : public SemaBase { /// Load weak undeclared identifiers from the external source. void LoadExternalWeakUndeclaredIdentifiers(); + /// Load #pragma redefine_extname'd undeclared identifiers from the external + /// source. + void LoadExternalExtnameUndeclaredIdentifiers(); + /// Determine if VD, which must be a variable or function, is an external /// symbol that nonetheless can't be referenced from outside this translation /// unit because its type has no linkage and it's not extern "C". diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 5db0b08f877ce..e44c2b55df1f9 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -748,6 +748,9 @@ enum ASTRecordTypes { /// Record code for #pragma clang riscv intrinsic vector. RISCV_VECTOR_INTRINSICS_PRAGMA = 78, + + /// Record code for extname-redefined undeclared identifiers. + EXTNAME_UNDECLARED_IDENTIFIERS = 79, }; /// Record types used within a source manager block. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 14f7d8a69a1b3..9bcf6459c7e56 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -965,9 +965,15 @@ class ASTReader SmallVector<serialization::SelectorID, 64> ReferencedSelectorsData; /// A snapshot of Sema's weak undeclared identifier tracking, for - /// generating warnings. + /// generating warnings. Note that this vector has 3n entries, being triplets + /// of the form C name, alias if any, and source location. SmallVector<serialization::IdentifierID, 64> WeakUndeclaredIdentifiers; + /// A snapshot of Sema's #redefine_extname'd undeclared identifier tracking, + /// for generating warnings. Note that this vector has 3n entries, being + /// triplets in the order of C name, asm name, and source location. + SmallVector<serialization::IdentifierID, 64> ExtnameUndeclaredIdentifiers; + /// The IDs of type aliases for ext_vectors that exist in the chain. /// /// Used by Sema for finding sugared names for ext_vectors in diagnostics. @@ -2356,6 +2362,10 @@ class ASTReader void ReadWeakUndeclaredIdentifiers( SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WeakIDs) override; + void ReadExtnameUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, AsmLabelAttr *>> &ExtnameIDs) + override; + void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override; void ReadPendingInstantiations( diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 1f040c879d724..be9582ce501fe 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -317,6 +317,12 @@ void MultiplexExternalSemaSource::ReadWeakUndeclaredIdentifiers( Sources[i]->ReadWeakUndeclaredIdentifiers(WI); } +void MultiplexExternalSemaSource::ReadExtnameUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, AsmLabelAttr *>> &EI) { + for (size_t i = 0; i < Sources.size(); ++i) + Sources[i]->ReadExtnameUndeclaredIdentifiers(EI); +} + void MultiplexExternalSemaSource::ReadUsedVTables( SmallVectorImpl<ExternalVTableUse> &VTables) { for(size_t i = 0; i < Sources.size(); ++i) diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 8b1d0398cf65d..7eeffc0c73ce4 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1083,6 +1083,15 @@ void Sema::LoadExternalWeakUndeclaredIdentifiers() { (void)WeakUndeclaredIdentifiers[WeakID.first].insert(WeakID.second); } +void Sema::LoadExternalExtnameUndeclaredIdentifiers() { + if (!ExternalSource) + return; + + SmallVector<std::pair<IdentifierInfo *, AsmLabelAttr *>, 4> ExtnameIDs; + ExternalSource->ReadExtnameUndeclaredIdentifiers(ExtnameIDs); + for (auto &ExtnameID : ExtnameIDs) + ExtnameUndeclaredIdentifiers[ExtnameID.first] = ExtnameID.second; +} typedef llvm::DenseMap<const CXXRecordDecl*, bool> RecordCompleteMap; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 054b664ca0a8b..96175dc1acc34 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8232,6 +8232,8 @@ NamedDecl *Sema::ActOnVariableDeclarator( } } + LoadExternalExtnameUndeclaredIdentifiers(); + if (Expr *E = D.getAsmLabel()) { // The parser guarantees this is a string. StringLiteral *SE = cast<StringLiteral>(E); @@ -10536,6 +10538,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, isMemberSpecialization || isFunctionTemplateSpecialization); + LoadExternalExtnameUndeclaredIdentifiers(); + // Handle GNU asm-label extension (encoded as an attribute). if (Expr *E = D.getAsmLabel()) { // The parser guarantees this is a string. diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 515eaf8d1caed..1c395c2f5dd92 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -19,6 +19,7 @@ #include "clang/AST/ASTStructuralEquivalence.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/AbstractTypeReader.h" +#include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -4028,6 +4029,27 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, } break; + case EXTNAME_UNDECLARED_IDENTIFIERS: + if (Record.size() % 3 != 0) + return llvm::createStringError(std::errc::illegal_byte_sequence, + "invalid extname identifiers record"); + + // FIXME: Ignore #pragma redefine_extname'd, undeclared identifiers from + // non-original PCH files. This isn't the way to do it :) + ExtnameUndeclaredIdentifiers.clear(); + + // Translate the #pragma redefine_extname'd, undeclared identifiers into + // global IDs. + for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) { + ExtnameUndeclaredIdentifiers.push_back( + getGlobalIdentifierID(F, Record[I++])); + ExtnameUndeclaredIdentifiers.push_back( + getGlobalIdentifierID(F, Record[I++])); + ExtnameUndeclaredIdentifiers.push_back( + ReadSourceLocation(F, Record, I).getRawEncoding()); + } + break; + case SELECTOR_OFFSETS: { F.SelectorOffsets = (const uint32_t *)Blob.data(); F.LocalNumSelectors = Record[0]; @@ -9687,6 +9709,28 @@ void ASTReader::ReadWeakUndeclaredIdentifiers( WeakUndeclaredIdentifiers.clear(); } +void ASTReader::ReadExtnameUndeclaredIdentifiers( + SmallVectorImpl<std::pair<IdentifierInfo *, AsmLabelAttr *>> &ExtnameIDs) { + if (ExtnameUndeclaredIdentifiers.empty()) + return; + + for (unsigned I = 0, N = ExtnameUndeclaredIdentifiers.size(); I < N; + /*none*/) { + IdentifierInfo *NameId = + DecodeIdentifierInfo(ExtnameUndeclaredIdentifiers[I++]); + IdentifierInfo *ExtnameId = + DecodeIdentifierInfo(ExtnameUndeclaredIdentifiers[I++]); + SourceLocation Loc = + SourceLocation::getFromRawEncoding(ExtnameUndeclaredIdentifiers[I++]); + AsmLabelAttr *Attr = AsmLabelAttr::CreateImplicit( + getContext(), ExtnameId->getName(), + AttributeCommonInfo(ExtnameId, SourceRange(Loc), + AttributeCommonInfo::Form::Pragma())); + ExtnameIDs.push_back(std::make_pair(NameId, Attr)); + } + ExtnameUndeclaredIdentifiers.clear(); +} + void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) { for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) { ExternalVTableUse VT; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e21a86b688dbf..bdbf6676c83a0 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -941,6 +941,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(TU_UPDATE_LEXICAL); RECORD(SEMA_DECL_REFS); RECORD(WEAK_UNDECLARED_IDENTIFIERS); + RECORD(EXTNAME_UNDECLARED_IDENTIFIERS); RECORD(PENDING_IMPLICIT_INSTANTIATIONS); RECORD(UPDATE_VISIBLE); RECORD(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD); @@ -6058,6 +6059,25 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot, } } + // Write the set of #pragma redefine_extname'd, undeclared identifiers. We + // always write the entire table, since later PCH files in a PCH chain are + // only interested in the results at the end of the chain. + RecordData ExtnameUndeclaredIdentifiers; + if (SemaPtr) { + ASTContext &Context = SemaPtr->Context; + ASTRecordWriter ExtnameUndeclaredIdentifiersWriter( + Context, *this, ExtnameUndeclaredIdentifiers); + for (const auto &ExtnameUndeclaredIdentifierList : + SemaPtr->ExtnameUndeclaredIdentifiers) { + const IdentifierInfo *const II = ExtnameUndeclaredIdentifierList.first; + const AsmLabelAttr *const AL = ExtnameUndeclaredIdentifierList.second; + ExtnameUndeclaredIdentifiersWriter.AddIdentifierRef(II); + ExtnameUndeclaredIdentifiersWriter.AddIdentifierRef( + &Context.Idents.get(AL->getLabel())); + ExtnameUndeclaredIdentifiersWriter.AddSourceLocation(AL->getLocation()); + } + } + // Form the record of special types. RecordData SpecialTypes; if (SemaPtr) { @@ -6205,6 +6225,12 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot, Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS, WeakUndeclaredIdentifiers); + // Write the record containing #pragma redefine_extname'd undeclared + // identifiers. + if (!ExtnameUndeclaredIdentifiers.empty()) + Stream.EmitRecord(EXTNAME_UNDECLARED_IDENTIFIERS, + ExtnameUndeclaredIdentifiers); + if (!WritingModule) { // Write the submodules that were imported, if any. struct ModuleInfo { diff --git a/clang/test/PCH/pragma-redefine-extname.c b/clang/test/PCH/pragma-redefine-extname.c new file mode 100644 index 0000000000000..79542f07a435c --- /dev/null +++ b/clang/test/PCH/pragma-redefine-extname.c @@ -0,0 +1,14 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %S/pragma-redefine-extname.h %s -verify -emit-llvm -o - | FileCheck %s + +// Test with pch. +// RUN: %clang_cc1 -x c-header -emit-pch -o %t %S/pragma-redefine-extname.h +// RUN: %clang_cc1 -include-pch %t %s -verify -emit-llvm -o - | FileCheck %s + +// CHECK-DAG: define void @"\01redeffunc2_ext" +// CHECK-DAG: call void @"\01redeffunc1_ext" + +///////////// Issue #186742: check that #pragma redefine_extname exports into PCHs even if the header contains no declaration of the symbol +void undecfunc1(void); +void undecfunc2(void) { undecfunc1(); } +static void undecfunc3(void) {} // expected-warning {{#pragma redefine_extname is applicable to external C declarations only; not applied to function 'undecfunc3'}} diff --git a/clang/test/PCH/pragma-redefine-extname.h b/clang/test/PCH/pragma-redefine-extname.h new file mode 100644 index 0000000000000..426baad7f363e --- /dev/null +++ b/clang/test/PCH/pragma-redefine-extname.h @@ -0,0 +1,5 @@ +// Header for PCH test pragma-redefine-extname.c + +#pragma redefine_extname undecfunc1 redeffunc1_ext +#pragma redefine_extname undecfunc2 redeffunc2_ext +#pragma redefine_extname undecfunc3 redeffunc3_ext diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index 61ca63c81d2d8..cbb7380c56fa8 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -582,6 +582,13 @@ class SemaSourceWithPriorities : public clang::ExternalSemaSource { Source->ReadWeakUndeclaredIdentifiers(WI); } + void ReadExtnameUndeclaredIdentifiers( + llvm::SmallVectorImpl<std::pair<clang::IdentifierInfo *, + clang::AsmLabelAttr *>> &EI) override { + for (auto &Source : Sources) + Source->ReadExtnameUndeclaredIdentifiers(EI); + } + void ReadUsedVTables( llvm::SmallVectorImpl<clang::ExternalVTableUse> &VTables) override { for (auto &Source : Sources) `````````` </details> https://github.com/llvm/llvm-project/pull/186755 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
