diff options
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 2 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 1 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 10 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 32 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.h | 10 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 4 | ||||
-rw-r--r-- | test/Sema/pragma-ms_struct.c | 19 |
9 files changed, 85 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 6e1e1e4684..ccd48daca6 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -485,6 +485,8 @@ def warn_pragma_expected_rparen : Warning< "missing ')' after '#pragma %0' - ignoring">; def warn_pragma_expected_identifier : Warning< "expected identifier in '#pragma %0' - ignored">; +def warn_pragma_ms_struct : Warning< + "incorrect use of '#pragma ms_struct on|off' - ignored">; def warn_pragma_extra_tokens_at_eol : Warning< "extra tokens at end of '#pragma %0' - ignored">; // - #pragma options diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index de4904a9a9..0311c06ece 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -131,6 +131,7 @@ class Parser : public CodeCompletionHandler { llvm::OwningPtr<PragmaHandler> GCCVisibilityHandler; llvm::OwningPtr<PragmaHandler> OptionsHandler; llvm::OwningPtr<PragmaHandler> PackHandler; + llvm::OwningPtr<PragmaHandler> MSStructHandler; llvm::OwningPtr<PragmaHandler> UnusedHandler; llvm::OwningPtr<PragmaHandler> WeakHandler; llvm::OwningPtr<PragmaHandler> FPContractHandler; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 6c08712fe7..e635526ebd 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -240,6 +240,8 @@ public: /// PackContext - Manages the stack for #pragma pack. An alignment /// of 0 indicates default alignment. void *PackContext; // Really a "PragmaPackStack*" + + bool MSStructPragmaOn; // True when #pragma ms_struct on /// VisContext - Manages the stack for #pragma GCC visibility. void *VisContext; // Really a "PragmaVisStack*" @@ -4855,6 +4857,11 @@ 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, @@ -4862,6 +4869,9 @@ public: SourceLocation PragmaLoc, SourceLocation LParenLoc, SourceLocation RParenLoc); + + /// ActOnPragmaMSStruct - Called on well formed #pragms ms_struct [on|off]. + void ActOnPragmaMSStruct(PragmaMSStructKind Kind); /// ActOnPragmaUnused - Called on well-formed '#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index beb1af67ac..46225c8e79 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -177,6 +177,38 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, LParenLoc, RParenLoc); } +// #pragma ms_struct on +// #pragma ms_struct off +void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &MSStructTok) { + Sema::PragmaMSStructKind Kind = Sema::PMSST_OFF; + + Token Tok; + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); + return; + } + const IdentifierInfo *II = Tok.getIdentifierInfo(); + if (II->isStr("on")) { + Kind = Sema::PMSST_ON; + PP.Lex(Tok); + } + else if (II->isStr("off") || II->isStr("reset")) + PP.Lex(Tok); + else { + PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); + return; + } + + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "ms_struct"; + return; + } + Actions.ActOnPragmaMSStruct(Kind); +} + // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok, diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h index bee6af3f4c..1d3138fa70 100644 --- a/lib/Parse/ParsePragma.h +++ b/lib/Parse/ParsePragma.h @@ -58,6 +58,16 @@ public: virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken); }; + +class PragmaMSStructHandler : public PragmaHandler { + Sema &Actions; +public: + explicit PragmaMSStructHandler(Sema &A) : PragmaHandler("ms_struct"), + Actions(A) {} + + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); +}; class PragmaUnusedHandler : public PragmaHandler { Sema &Actions; diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 9244b99492..debc7404b9 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -45,6 +45,9 @@ Parser::Parser(Preprocessor &pp, Sema &actions) PackHandler.reset(new PragmaPackHandler(actions)); PP.AddPragmaHandler(PackHandler.get()); + + MSStructHandler.reset(new PragmaMSStructHandler(actions)); + PP.AddPragmaHandler(MSStructHandler.get()); UnusedHandler.reset(new PragmaUnusedHandler(actions, *this)); PP.AddPragmaHandler(UnusedHandler.get()); @@ -377,6 +380,8 @@ Parser::~Parser() { OptionsHandler.reset(); PP.RemovePragmaHandler(PackHandler.get()); PackHandler.reset(); + PP.RemovePragmaHandler(MSStructHandler.get()); + MSStructHandler.reset(); PP.RemovePragmaHandler(UnusedHandler.get()); UnusedHandler.reset(); PP.RemovePragmaHandler(WeakHandler.get()); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 3ce1d82c88..7707fb1104 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -141,7 +141,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), - PackContext(0), VisContext(0), + PackContext(0), MSStructPragmaOn(false), VisContext(0), LateTemplateParser(0), OpaqueParser(0), IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0), GlobalNewDeleteDeclared(false), @@ -184,7 +184,7 @@ Sema::~Sema() { if (PackContext) FreePackedContext(); if (VisContext) FreeVisContext(); delete TheTargetAttributesSema; - + MSStructPragmaOn = false; // Kill all the active scopes. for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I) delete FunctionScopes[I]; diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index 4fad173048..7a50356fed 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -263,6 +263,10 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, } } +void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { + MSStructPragmaOn = (Kind == PMSST_ON); +} + void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, SourceLocation PragmaLoc) { diff --git a/test/Sema/pragma-ms_struct.c b/test/Sema/pragma-ms_struct.c new file mode 100644 index 0000000000..61047c0309 --- /dev/null +++ b/test/Sema/pragma-ms_struct.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-apple-darwin9 %s + +#pragma ms_struct on + +#pragma ms_struct off + +#pragma ms_struct reset + +#pragma ms_struct // expected-warning {{incorrect use of '#pragma ms_struct on|off' - ignored}} + +#pragma ms_struct on top of spaghetti // expected-warning {{extra tokens at end of '#pragma ms_struct' - ignored}} + +struct foo +{ + int a; + int b; + char c; +}; + |