diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 5 | ||||
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 37 | ||||
-rw-r--r-- | test/Parser/pragma-options.c | 12 | ||||
-rw-r--r-- | test/Sema/pragma-pack-and-options-align.c | 34 |
5 files changed, 91 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 2ce66903d2..51fea8ac90 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -236,6 +236,10 @@ def err_object_cannot_be_passed_returned_by_value : Error< "interface type %1 cannot be %select{returned|passed}0 by value" "; did you forget * in %1">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; +def warn_pragma_options_align_unsupported_option : Warning< + "unsupported alignment option in '#pragma options align'">; +def warn_pragma_options_align_reset_failed : Warning< + "#pragma options align=reset failed: %0">; def warn_pragma_pack_invalid_alignment : Warning< "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">; // Follow the MSVC implementation. diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 1b61800c2a..da3937ff83 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -4015,6 +4015,11 @@ public: MultiExprArg Args); + /// ActOnPragmaOptionsAlign - Called on well formed #pragma options align. + virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, + SourceLocation PragmaLoc, + SourceLocation KindLoc); + /// ActOnPragmaPack - Called on well formed #pragma pack(...). virtual void ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index dc7815fa64..770bd218d1 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -18,7 +18,7 @@ using namespace clang; //===----------------------------------------------------------------------===// -// Pragma Packed +// Pragma 'pack' and 'options align' //===----------------------------------------------------------------------===// namespace { @@ -94,6 +94,41 @@ unsigned Sema::getPragmaPackAlignment() const { return 0; } +void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, + SourceLocation PragmaLoc, + SourceLocation KindLoc) { + if (PackContext == 0) + PackContext = new PragmaPackStack(); + + PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); + + // Reset just pops the top of the stack. + if (Kind == Action::POAK_Reset) { + // Do the pop. + if (!Context->pop(0)) { + // If a name was specified then failure indicates the name + // wasn't found. Otherwise failure indicates the stack was + // empty. + Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) + << "stack empty"; + } + return; + } + + // We don't support #pragma options align=power. + switch (Kind) { + case POAK_Natural: + Context->push(0); + Context->setAlignment(0); + break; + + default: + Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option) + << KindLoc; + break; + } +} + void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, ExprTy *alignment, SourceLocation PragmaLoc, SourceLocation LParenLoc, SourceLocation RParenLoc) { diff --git a/test/Parser/pragma-options.c b/test/Parser/pragma-options.c new file mode 100644 index 0000000000..07b22fe5d3 --- /dev/null +++ b/test/Parser/pragma-options.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +/* expected-warning {{expected 'align' following '#pragma options'}} */ #pragma options +/* expected-warning {{expected '=' following '#pragma options align'}} */ #pragma options align +/* expected-warning {{expected identifier in '#pragma options'}} */ #pragma options align = +/* expected-warning {{invalid alignment option in '#pragma options align'}} */ #pragma options align = foo +/* expected-warning {{extra tokens at end of '#pragma options'}} */ #pragma options align = reset foo + +#pragma options align=natural +#pragma options align=reset +/* expected-warning {{unsupported alignment option}} */ #pragma options align=mac68k +/* expected-warning {{unsupported alignment option}} */ #pragma options align=power diff --git a/test/Sema/pragma-pack-and-options-align.c b/test/Sema/pragma-pack-and-options-align.c new file mode 100644 index 0000000000..c880ed6305 --- /dev/null +++ b/test/Sema/pragma-pack-and-options-align.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify + +// Check that #pragma pack and #pragma options share the same stack. + +#pragma pack(push, 1) +struct s0 { + char c; + int x; +}; +extern int a[sizeof(struct s0) == 5 ? 1 : -1]; + +#pragma options align=natural +struct s1 { + char c; + int x; +}; +extern int a[sizeof(struct s1) == 8 ? 1 : -1]; + +#pragma pack(pop) +struct s2 { + char c; + int x; +}; +extern int a[sizeof(struct s2) == 5 ? 1 : -1]; +#pragma pack(pop) + +struct s3 { + char c; + int x; +}; +extern int a[sizeof(struct s3) == 8 ? 1 : -1]; + +/* expected-warning {{#pragma options align=reset failed: stack empty}} */ #pragma options align=reset +/* expected-warning {{#pragma pack(pop, ...) failed: stack empty}} */ #pragma pack(pop) |