Skip to content

Commit

Permalink
Serialize pragma ms_struct state.
Browse files Browse the repository at this point in the history
pragma ms_struct has an effect on struct decls, and the effect is serialized
correctly already.  But the "is ms_struct currently on" state wasn't before
this change.

This uses the same approach as `pragma clang optimize`: When writing a module,
the state isn't serialized, only when writing a pch file.

llvm-svn: 262539
  • Loading branch information
nico committed Mar 2, 2016
1 parent 8226fc4 commit 779355f
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 15 deletions.
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/PragmaKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ enum PragmaMSCommentKind {
PCK_User // #pragma comment(user, ...)
};

enum PragmaMSStructKind {
PMSST_OFF, // #pragms ms_struct off
PMSST_ON // #pragms ms_struct on
};

}

#endif
5 changes: 0 additions & 5 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -7611,11 +7611,6 @@ class Sema {
PPK_Pop // #pragma pack(pop, [identifier], [n])
};

enum PragmaMSStructKind {
PMSST_OFF, // #pragms ms_struct off
PMSST_ON // #pragms ms_struct on
};

/// ActOnPragmaPack - Called on well formed \#pragma pack(...).
void ActOnPragmaPack(PragmaPackKind Kind,
IdentifierInfo *Name,
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,10 @@ namespace clang {
CXX_CTOR_INITIALIZERS_OFFSETS = 53,

/// \brief Delete expressions that will be analyzed later.
DELETE_EXPRS_TO_ANALYZE = 54
DELETE_EXPRS_TO_ANALYZE = 54,

/// \brief Record code for \#pragma ms_struct options.
MSSTRUCT_PRAGMA_OPTIONS = 55
};

/// \brief Record types used within a source manager block.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,9 @@ class ASTReader
/// \brief The pragma clang optimize location (if the pragma state is "off").
SourceLocation OptimizeOffPragmaLocation;

/// \brief The PragmaMSStructKind pragma ms_struct state if set, or -1.
int PragmaMSStructState;

/// \brief The OpenCL extension settings.
SmallVector<uint64_t, 1> OpenCLExtensions;

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ class ASTWriter : public ASTDeserializationListener,
void WriteObjCCategories();
void WriteLateParsedTemplates(Sema &SemaRef);
void WriteOptimizePragmaOptions(Sema &SemaRef);
void WriteMSStructPragmaOptions(Sema &SemaRef);
void WriteModuleFileExtension(Sema &SemaRef,
ModuleFileExtensionWriter &Writer);

Expand Down
11 changes: 5 additions & 6 deletions clang/lib/Parse/ParsePragma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,8 @@ void Parser::HandlePragmaPack() {

void Parser::HandlePragmaMSStruct() {
assert(Tok.is(tok::annot_pragma_msstruct));
Sema::PragmaMSStructKind Kind =
static_cast<Sema::PragmaMSStructKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
Actions.ActOnPragmaMSStruct(Kind);
ConsumeToken(); // The annotation token.
}
Expand Down Expand Up @@ -1063,8 +1062,8 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP,
void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
PragmaIntroducerKind Introducer,
Token &MSStructTok) {
Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF;
PragmaMSStructKind Kind = PMSST_OFF;

Token Tok;
PP.Lex(Tok);
if (Tok.isNot(tok::identifier)) {
Expand All @@ -1074,7 +1073,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
SourceLocation EndLoc = Tok.getLocation();
const IdentifierInfo *II = Tok.getIdentifierInfo();
if (II->isStr("on")) {
Kind = Sema::PMSST_ON;
Kind = PMSST_ON;
PP.Lex(Tok);
}
else if (II->isStr("off") || II->isStr("reset"))
Expand Down
15 changes: 13 additions & 2 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3217,6 +3217,14 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
break;

case MSSTRUCT_PRAGMA_OPTIONS:
if (Record.size() != 1) {
Error("invalid pragma ms_struct record");
return Failure;
}
PragmaMSStructState = Record[0];
break;

case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES:
for (unsigned I = 0, N = Record.size(); I != N; ++I)
UnusedLocalTypedefNameCandidates.push_back(
Expand Down Expand Up @@ -6998,10 +7006,12 @@ void ASTReader::UpdateSema() {
SemaDeclRefs.clear();
}

// Update the state of 'pragma clang optimize'. Use the same API as if we had
// encountered the pragma in the source.
// Update the state of pragmas. Use the same API as if we had encountered the
// pragma in the source.
if(OptimizeOffPragmaLocation.isValid())
SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation);
if (PragmaMSStructState != -1)
SemaObj->ActOnPragmaMSStruct((PragmaMSStructKind)PragmaMSStructState);
}

IdentifierInfo *ASTReader::get(StringRef Name) {
Expand Down Expand Up @@ -8696,6 +8706,7 @@ ASTReader::ASTReader(
Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context),
Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerRdr),
ReadTimer(std::move(ReadTimer)),
PragmaMSStructState(-1),
isysroot(isysroot), DisableValidation(DisableValidation),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
AllowConfigurationMismatch(AllowConfigurationMismatch),
Expand Down
12 changes: 11 additions & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(UNDEFINED_BUT_USED);
RECORD(LATE_PARSED_TEMPLATE);
RECORD(OPTIMIZE_PRAGMA_OPTIONS);
RECORD(MSSTRUCT_PRAGMA_OPTIONS);
RECORD(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES);
RECORD(CXX_CTOR_INITIALIZERS_OFFSETS);
RECORD(DELETE_EXPRS_TO_ANALYZE);
Expand Down Expand Up @@ -3928,6 +3929,13 @@ void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record);
}

/// \brief Write the state of 'pragma ms_struct' at the end of the module.
void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) {
RecordData Record;
Record.push_back(SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF);
Stream.EmitRecord(MSSTRUCT_PRAGMA_OPTIONS, Record);
}

void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
ModuleFileExtensionWriter &Writer) {
// Enter the extension block.
Expand Down Expand Up @@ -4605,8 +4613,10 @@ uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,

WriteDeclReplacementsBlock();
WriteObjCCategories();
if(!WritingModule)
if(!WritingModule) {
WriteOptimizePragmaOptions(SemaRef);
WriteMSStructPragmaOptions(SemaRef);
}

// Some simple statistics
RecordData::value_type Record[] = {
Expand Down
41 changes: 41 additions & 0 deletions clang/test/PCH/pragma-ms_struct.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Test this without pch.
// RUN: %clang_cc1 %s -Wunknown-pragmas -Werror -triple i386-apple-darwin9 -fsyntax-only -include %s -verify -std=c++11

// Test with pch.
// RUN: %clang_cc1 %s -Wunknown-pragmas -Werror -triple i386-apple-darwin9 -emit-pch -o %t -std=c++11
// RUN: %clang_cc1 %s -Wunknown-pragmas -Werror -triple i386-apple-darwin9 -fsyntax-only -include-pch %t -verify -std=c++11

// The first run line creates a pch, and since at that point HEADER is not
// defined, the only thing contained in the pch is the pragma. The second line
// then includes that pch, so HEADER is defined and the actual code is compiled.
// The check then makes sure that the pragma is in effect in the file that
// includes the pch.

// expected-no-diagnostics

#ifndef HEADER
#define HEADER
struct SOffH {
short m : 9;
int q : 12;
};

#pragma ms_struct on

struct SOnH {
short m : 9;
int q : 12;
};

#else

struct SOnC {
short m : 9;
int q : 12;
};

static_assert(sizeof(SOffH) == 4, "");
static_assert(sizeof(SOnH) == 8, "");
static_assert(sizeof(SOnC) == 8, "");

#endif

0 comments on commit 779355f

Please sign in to comment.