forked from OSchip/llvm-project
Serialize `pragma ms_struct` state.
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
This commit is contained in:
parent
8226fc4829
commit
779355f96b
|
@ -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
|
||||
|
|
|
@ -7611,11 +7611,6 @@ public:
|
|||
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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -785,6 +785,9 @@ private:
|
|||
/// \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;
|
||||
|
||||
|
|
|
@ -551,6 +551,7 @@ private:
|
|||
void WriteObjCCategories();
|
||||
void WriteLateParsedTemplates(Sema &SemaRef);
|
||||
void WriteOptimizePragmaOptions(Sema &SemaRef);
|
||||
void WriteMSStructPragmaOptions(Sema &SemaRef);
|
||||
void WriteModuleFileExtension(Sema &SemaRef,
|
||||
ModuleFileExtensionWriter &Writer);
|
||||
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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"))
|
||||
|
|
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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[] = {
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue