[cfe-commits] r151307 - in /cfe/trunk: include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h lib/Parse/ParseDeclCXX.cpp lib/Parse/ParsePragma.cpp lib/Parse/ParseStmt.cpp lib/Parse/Parser.cpp test/Sema/pragma-pack-2.c test/SemaCXX/pragma-visibility.cpp test/SemaObjC/pragma-pack.m
Eli Friedman
eli.friedman at gmail.com
Thu Feb 23 15:47:17 PST 2012
Author: efriedma
Date: Thu Feb 23 17:47:16 2012
New Revision: 151307
URL: http://llvm.org/viewvc/llvm-project?rev=151307&view=rev
Log:
Handle "#pragma GCC visibility" in a few more places. Switch over "#pragma pack" to use the same handling that gcc does. Fixes <rdar://problem/10871094> and <rdar://problem/10893316>.
(Hopefully, common usage of these pragmas isn't irregular enough to break our current handling. Doug has ideas for a more crazy approach if necessary.)
Added:
cfe/trunk/test/SemaObjC/pragma-pack.m
Modified:
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParsePragma.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/test/Sema/pragma-pack-2.c
cfe/trunk/test/SemaCXX/pragma-visibility.cpp
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu Feb 23 17:47:16 2012
@@ -574,6 +574,11 @@
// handles them.
ANNOTATION(pragma_vis)
+// Annotation for #pragma pack...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_pack)
+
#undef ANNOTATION
#undef TESTING_KEYWORD
#undef OBJC2_AT_KEYWORD
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Feb 23 17:47:16 2012
@@ -410,6 +410,10 @@
/// #pragma GCC visibility...
void HandlePragmaVisibility();
+ /// \brief Handle the annotation token produced for
+ /// #pragma pack...
+ void HandlePragmaPack();
+
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
/// returns the token after Tok, etc.
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Feb 23 17:47:16 2012
@@ -2251,6 +2251,16 @@
continue;
}
+ if (Tok.is(tok::annot_pragma_vis)) {
+ HandlePragmaVisibility();
+ continue;
+ }
+
+ if (Tok.is(tok::annot_pragma_pack)) {
+ HandlePragmaPack();
+ continue;
+ }
+
AccessSpecifier AS = getAccessSpecifierIfPresent();
if (AS != AS_none) {
// Current token is a C++ access specifier.
Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Thu Feb 23 17:47:16 2012
@@ -37,6 +37,24 @@
Actions.ActOnPragmaVisibility(VisType, VisLoc);
}
+struct PragmaPackInfo {
+ Sema::PragmaPackKind Kind;
+ IdentifierInfo *Name;
+ Expr *Alignment;
+ SourceLocation LParenLoc;
+ SourceLocation RParenLoc;
+};
+
+void Parser::HandlePragmaPack() {
+ assert(Tok.is(tok::annot_pragma_pack));
+ PragmaPackInfo *Info =
+ static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
+ SourceLocation PragmaLoc = ConsumeToken();
+ Actions.ActOnPragmaPack(Info->Kind, Info->Name, Info->Alignment, PragmaLoc,
+ Info->LParenLoc, Info->RParenLoc);
+ delete Info;
+}
+
// #pragma GCC visibility comes in two variants:
// 'push' '(' [visibility] ')'
// 'pop'
@@ -196,8 +214,20 @@
return;
}
- Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc,
- LParenLoc, RParenLoc);
+ PragmaPackInfo *Info = new PragmaPackInfo;
+ Info->Kind = Kind;
+ Info->Name = Name;
+ Info->Alignment = Alignment.release();
+ Info->LParenLoc = LParenLoc;
+ Info->RParenLoc = RParenLoc;
+
+ Token *Toks = new Token[1];
+ Toks[0].startToken();
+ Toks[0].setKind(tok::annot_pragma_pack);
+ Toks[0].setLocation(PackLoc);
+ Toks[0].setAnnotationValue(static_cast<void*>(Info));
+ PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+ /*OwnsTokens=*/true);
}
// #pragma ms_struct on
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Feb 23 17:47:16 2012
@@ -280,6 +280,14 @@
case tok::kw___try:
return ParseSEHTryBlock(attrs);
+
+ case tok::annot_pragma_vis:
+ HandlePragmaVisibility();
+ return StmtEmpty();
+
+ case tok::annot_pragma_pack:
+ HandlePragmaPack();
+ return StmtEmpty();
}
// If we reached this code, the statement must end in a semicolon.
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Feb 23 17:47:16 2012
@@ -549,6 +549,9 @@
case tok::annot_pragma_vis:
HandlePragmaVisibility();
return DeclGroupPtrTy();
+ case tok::annot_pragma_pack:
+ HandlePragmaPack();
+ return DeclGroupPtrTy();
case tok::semi:
Diag(Tok, getLang().CPlusPlus0x ?
diag::warn_cxx98_compat_top_level_semi : diag::ext_top_level_semi)
Modified: cfe/trunk/test/Sema/pragma-pack-2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/pragma-pack-2.c?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/test/Sema/pragma-pack-2.c (original)
+++ cfe/trunk/test/Sema/pragma-pack-2.c Thu Feb 23 17:47:16 2012
@@ -22,32 +22,32 @@
// Test scope of definition
#pragma pack(push, 2)
-struct s2_0 {
-#pragma pack(pop)
+struct s2_0 { // expected-error {{expected ';'}}
+#pragma pack(pop) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
char f0;
int f1;
};
extern int a2_0[offsetof(struct s2_0, f1) == 2 ? 1 : -1];
struct s2_1 {
- char f0;
-#pragma pack(push, 2)
- int f1;
-#pragma pack(pop)
+ char f0; // expected-error {{expected ';'}}
+#pragma pack(push, 2) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
+ int f1; // expected-error {{expected ';'}}
+#pragma pack(pop) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
};
extern int a2_1[offsetof(struct s2_1, f1) == 4 ? 1 : -1];
struct s2_2 {
char f0;
- int f1;
-#pragma pack(push, 2)
+ int f1; // expected-error {{expected ';'}}
+#pragma pack(push, 2) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
};
#pragma pack(pop)
extern int a2_2[offsetof(struct s2_2, f1) == 4 ? 1 : -1];
struct s2_3 {
- char f0;
-#pragma pack(push, 2)
+ char f0; // expected-error {{expected ';'}}
+#pragma pack(push, 2) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
struct s2_3_0 {
#pragma pack(pop)
int f0;
@@ -58,10 +58,10 @@
struct s2_4 {
char f0;
struct s2_4_0 {
- int f0;
-#pragma pack(push, 2)
- } f1;
-#pragma pack(pop)
+ int f0; // expected-error {{expected ';'}}
+#pragma pack(push, 2) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
+ } f1; // expected-error {{expected ';'}}
+#pragma pack(pop) // expected-error {{type name}} expected-error {{member name}} expected-warning {{type specifier}}
};
extern int a2_4[offsetof(struct s2_4, f1) == 4 ? 1 : -1];
@@ -91,3 +91,15 @@
};
extern int a4_0[offsetof(struct s4_0, f1) == 1 ? 1 : -1];
extern int a4_1[offsetof(struct s4_1, f1) == 4 ? 1 : -1];
+
+void f() {
+ #pragma pack(push, 2)
+ struct s5_0 {
+ char f0;
+ struct s2_4_0 {
+ int f0;
+ } f1;
+ };
+ #pragma pack(pop)
+ extern int s5_0[offsetof(struct s5_0, f1) == 2 ? 1 : -1];
+}
Modified: cfe/trunk/test/SemaCXX/pragma-visibility.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pragma-visibility.cpp?rev=151307&r1=151306&r2=151307&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/pragma-visibility.cpp (original)
+++ cfe/trunk/test/SemaCXX/pragma-visibility.cpp Thu Feb 23 17:47:16 2012
@@ -10,3 +10,14 @@
} // expected-note{{surrounding namespace with visibility attribute ends here}}
#pragma GCC visibility pop // expected-error{{#pragma visibility pop with no matching #pragma visibility push}}
+
+// <rdar://problem/10871094>
+struct A {
+ #pragma GCC visibility push(protected)
+ #pragma GCC visibility pop
+};
+
+void f() {
+ #pragma GCC visibility push(protected)
+ #pragma GCC visibility pop
+}
Added: cfe/trunk/test/SemaObjC/pragma-pack.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/pragma-pack.m?rev=151307&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/pragma-pack.m (added)
+++ cfe/trunk/test/SemaObjC/pragma-pack.m Thu Feb 23 17:47:16 2012
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -verify %s
+
+// Make sure pragma pack works inside ObjC methods. <rdar://problem/10893316>
+ at interface X
+ at end
+ at implementation X
+- (void)Y {
+#pragma pack(push, 1)
+ struct x {
+ char a;
+ int b;
+ };
+#pragma pack(pop)
+ typedef char check_[sizeof (struct x) == 5 ? 1 : -1];
+}
+ at end
More information about the cfe-commits
mailing list