Skip to content

Commit 40be91d

Browse files
committed
[Modules][PCH] Serialize #pragma pack
This patch serializes the state of #pragma pack. It preserves the state of the pragma from a PCH/from modules in a file that uses that PCH/those modules. rdar://21359084 Differential Revision: https://reviews.llvm.org/D31241 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299226 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ef8a2a5 commit 40be91d

File tree

12 files changed

+235
-0
lines changed

12 files changed

+235
-0
lines changed

include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,9 @@ namespace clang {
604604
OPENCL_EXTENSION_DECLS = 59,
605605

606606
MODULAR_CODEGEN_DECLS = 60,
607+
608+
/// \brief Record code for \#pragma pack options.
609+
PACK_PRAGMA_OPTIONS = 61,
607610
};
608611

609612
/// \brief Record types used within a source manager block.

include/clang/Serialization/ASTReader.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,17 @@ class ASTReader
811811
int PragmaMSPointersToMembersState = -1;
812812
SourceLocation PointersToMembersPragmaLocation;
813813

814+
/// \brief The pragma pack state.
815+
Optional<unsigned> PragmaPackCurrentValue;
816+
SourceLocation PragmaPackCurrentLocation;
817+
struct PragmaPackStackEntry {
818+
unsigned Value;
819+
SourceLocation Location;
820+
StringRef SlotLabel;
821+
};
822+
llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack;
823+
llvm::SmallVector<std::string, 2> PragmaPackStrings;
824+
814825
/// \brief The OpenCL extension settings.
815826
OpenCLOptions OpenCLExtensions;
816827

include/clang/Serialization/ASTWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ class ASTWriter : public ASTDeserializationListener,
485485
void WriteOptimizePragmaOptions(Sema &SemaRef);
486486
void WriteMSStructPragmaOptions(Sema &SemaRef);
487487
void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef);
488+
void WritePackPragmaOptions(Sema &SemaRef);
488489
void WriteModuleFileExtension(Sema &SemaRef,
489490
ModuleFileExtensionWriter &Writer);
490491

lib/Sema/SemaAttr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
215215
ValueType Value) {
216216
if (Action == PSK_Reset) {
217217
CurrentValue = DefaultValue;
218+
CurrentPragmaLocation = PragmaLocation;
218219
return;
219220
}
220221
if (Action & PSK_Push)

lib/Serialization/ASTReader.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,6 +3298,28 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
32983298
}
32993299
ForceCUDAHostDeviceDepth = Record[0];
33003300
break;
3301+
3302+
case PACK_PRAGMA_OPTIONS: {
3303+
if (Record.size() < 3) {
3304+
Error("invalid pragma pack record");
3305+
return Failure;
3306+
}
3307+
PragmaPackCurrentValue = Record[0];
3308+
PragmaPackCurrentLocation = ReadSourceLocation(F, Record[1]);
3309+
unsigned NumStackEntries = Record[2];
3310+
unsigned Idx = 3;
3311+
// Reset the stack when importing a new module.
3312+
PragmaPackStack.clear();
3313+
for (unsigned I = 0; I < NumStackEntries; ++I) {
3314+
PragmaPackStackEntry Entry;
3315+
Entry.Value = Record[Idx++];
3316+
Entry.Location = ReadSourceLocation(F, Record[Idx++]);
3317+
PragmaPackStrings.push_back(ReadString(Record, Idx));
3318+
Entry.SlotLabel = PragmaPackStrings.back();
3319+
PragmaPackStack.push_back(Entry);
3320+
}
3321+
break;
3322+
}
33013323
}
33023324
}
33033325
}
@@ -7419,6 +7441,34 @@ void ASTReader::UpdateSema() {
74197441
PointersToMembersPragmaLocation);
74207442
}
74217443
SemaObj->ForceCUDAHostDeviceDepth = ForceCUDAHostDeviceDepth;
7444+
7445+
if (PragmaPackCurrentValue) {
7446+
// The bottom of the stack might have a default value. It must be adjusted
7447+
// to the current value to ensure that the packing state is preserved after
7448+
// popping entries that were included/imported from a PCH/module.
7449+
bool DropFirst = false;
7450+
if (!PragmaPackStack.empty() &&
7451+
PragmaPackStack.front().Location.isInvalid()) {
7452+
assert(PragmaPackStack.front().Value == SemaObj->PackStack.DefaultValue &&
7453+
"Expected a default alignment value");
7454+
SemaObj->PackStack.Stack.emplace_back(
7455+
PragmaPackStack.front().SlotLabel, SemaObj->PackStack.CurrentValue,
7456+
SemaObj->PackStack.CurrentPragmaLocation);
7457+
DropFirst = true;
7458+
}
7459+
for (const auto &Entry :
7460+
llvm::makeArrayRef(PragmaPackStack).drop_front(DropFirst ? 1 : 0))
7461+
SemaObj->PackStack.Stack.emplace_back(Entry.SlotLabel, Entry.Value,
7462+
Entry.Location);
7463+
if (PragmaPackCurrentLocation.isInvalid()) {
7464+
assert(*PragmaPackCurrentValue == SemaObj->PackStack.DefaultValue &&
7465+
"Expected a default alignment value");
7466+
// Keep the current values.
7467+
} else {
7468+
SemaObj->PackStack.CurrentValue = *PragmaPackCurrentValue;
7469+
SemaObj->PackStack.CurrentPragmaLocation = PragmaPackCurrentLocation;
7470+
}
7471+
}
74227472
}
74237473

74247474
IdentifierInfo *ASTReader::get(StringRef Name) {

lib/Serialization/ASTWriter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4170,6 +4170,20 @@ void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) {
41704170
Stream.EmitRecord(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Record);
41714171
}
41724172

4173+
/// \brief Write the state of 'pragma pack' at the end of the module.
4174+
void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
4175+
RecordData Record;
4176+
Record.push_back(SemaRef.PackStack.CurrentValue);
4177+
AddSourceLocation(SemaRef.PackStack.CurrentPragmaLocation, Record);
4178+
Record.push_back(SemaRef.PackStack.Stack.size());
4179+
for (const auto &StackEntry : SemaRef.PackStack.Stack) {
4180+
Record.push_back(StackEntry.Value);
4181+
AddSourceLocation(StackEntry.PragmaLocation, Record);
4182+
AddString(StackEntry.StackSlotLabel, Record);
4183+
}
4184+
Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record);
4185+
}
4186+
41734187
void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
41744188
ModuleFileExtensionWriter &Writer) {
41754189
// Enter the extension block.
@@ -4860,6 +4874,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
48604874
WriteMSStructPragmaOptions(SemaRef);
48614875
WriteMSPointersToMembersPragmaOptions(SemaRef);
48624876
}
4877+
WritePackPragmaOptions(SemaRef);
48634878

48644879
// Some simple statistics
48654880
RecordData::value_type Record[] = {

test/Modules/Inputs/module.map

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,22 @@ module diag_pragma {
265265
header "diag_pragma.h"
266266
}
267267

268+
module pragma_pack_set {
269+
header "pragma_pack_set.h"
270+
}
271+
272+
module pragma_pack_push {
273+
header "pragma_pack_push.h"
274+
}
275+
276+
module pragma_pack_empty {
277+
header "empty.h"
278+
}
279+
280+
module pragma_pack_reset_push {
281+
header "pragma_pack_reset_push.h"
282+
}
283+
268284
module dummy {
269285
header "dummy.h"
270286
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
#pragma pack (push, 4)
3+
#pragma pack (push, 2)
4+
#pragma pack (push, 1)
5+
#pragma pack (pop)
6+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
#pragma pack ()
3+
#pragma pack (push, 4)
4+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
#pragma pack (1)
3+

0 commit comments

Comments
 (0)