diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-02-23 23:47:16 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-02-23 23:47:16 +0000 |
commit | aa5ab26ed93382b812147f532dcbf4afb5494040 (patch) | |
tree | 075b778942e1b8eec6108dd5d5dea37171a0afa3 /lib | |
parent | 8b9414e868853fc052251455674bf7512261e14a (diff) |
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.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151307 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 10 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 34 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 8 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 3 |
4 files changed, 53 insertions, 2 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index cc8c0c45d2..c2bf54db2c 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -2251,6 +2251,16 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 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. diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 433c76b83b..96a4f3af76 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -37,6 +37,24 @@ void Parser::HandlePragmaVisibility() { 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 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, 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 diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 3537768eed..0ce73cbeb2 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -280,6 +280,14 @@ Retry: 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. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 4c5df4d2ff..6927c50b8f 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -549,6 +549,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, 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) |