diff options
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 2 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 18 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 1 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 57 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.h | 9 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 6 |
6 files changed, 91 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 2912344e06..81afac9a60 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -264,6 +264,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_extra_tokens_at_eol : Warning< + "extra tokens at end of '#pragma %0' - ignored">; // - #pragma pack def warn_pragma_pack_invalid_action : Warning< "unknown action for '#pragma pack' - ignored">; diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 5c23f9ac61..eadff639a2 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -1756,7 +1756,23 @@ public: SourceLocation LParenLoc, SourceLocation RParenLoc) { return; - } + } + + /// ActOnPragmaPack - Called on well formed #pragma weak ident. + virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName, + SourceLocation PragmaLoc, + SourceLocation WeakNameLoc) { + return; + } + + /// ActOnPragmaPack - Called on well formed #pragma weak ident = ident. + virtual void ActOnPragmaWeakAlias(IdentifierInfo* WeakName, + IdentifierInfo* AliasName, + SourceLocation PragmaLoc, + SourceLocation WeakNameLoc, + SourceLocation AliasNameLoc) { + return; + } }; /// MinimalAction - Minimal actions are used by light-weight clients of the diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 26e37e2806..6218ade323 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -81,6 +81,7 @@ class Parser { llvm::OwningPtr<PragmaHandler> PackHandler; llvm::OwningPtr<PragmaHandler> UnusedHandler; + llvm::OwningPtr<PragmaHandler> WeakHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 94695e4d56..58c729aef2 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -100,6 +100,12 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { return; } + PP.Lex(Tok); + if (Tok.isNot(tok::eom)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack"; + return; + } + SourceLocation RParenLoc = Tok.getLocation(); Actions.ActOnPragmaPack(Kind, Name, Alignment.release(), PackLoc, LParenLoc, RParenLoc); @@ -172,7 +178,14 @@ void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) { PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc); return; } - + + PP.Lex(Tok); + if (Tok.isNot(tok::eom)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << + "unused"; + return; + } + // Verify that we have a location for the right parenthesis. assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'"); assert(!Ex.empty() && "Valid '#pragma unused' must have arguments"); @@ -180,3 +193,45 @@ void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, Token &UnusedTok) { // Perform the action to handle the pragma. Actions.ActOnPragmaUnused(&Ex[0], Ex.size(), UnusedLoc, LParenLoc, RParenLoc); } + +// #pragma weak identifier +// #pragma weak identifier '=' identifier +void PragmaWeakHandler::HandlePragma(Preprocessor &PP, Token &WeakTok) { + // FIXME: Should we be expanding macros here? My guess is no. + SourceLocation WeakLoc = WeakTok.getLocation(); + + Token Tok; + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak"; + return; + } + + IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0; + SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc; + + PP.Lex(Tok); + if (Tok.is(tok::equal)) { + PP.Lex(Tok); + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << "weak"; + return; + } + AliasName = Tok.getIdentifierInfo(); + AliasNameLoc = Tok.getLocation(); + PP.Lex(Tok); + } + + if (Tok.isNot(tok::eom)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak"; + return; + } + + if (AliasName) { + Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc, + AliasNameLoc); + } else { + Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc); + } +} diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h index 31b2a5f685..39c86eea43 100644 --- a/lib/Parse/ParsePragma.h +++ b/lib/Parse/ParsePragma.h @@ -39,6 +39,15 @@ public: virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); }; +class PragmaWeakHandler : public PragmaHandler { + Action &Actions; +public: + PragmaWeakHandler(const IdentifierInfo *N, Action &A) + : PragmaHandler(N), Actions(A) {} + + virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); +}; + } // end namespace clang #endif diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 1c2e8a62e1..a2a66f9255 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -39,6 +39,10 @@ Parser::Parser(Preprocessor &pp, Action &actions) PragmaUnusedHandler(&PP.getIdentifierTable().get("unused"), actions, *this)); PP.AddPragmaHandler(0, UnusedHandler.get()); + + WeakHandler.reset(new + PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions)); + PP.AddPragmaHandler(0, WeakHandler.get()); } /// If a crash happens while the parser is active, print out a line indicating @@ -288,6 +292,8 @@ Parser::~Parser() { PackHandler.reset(); PP.RemovePragmaHandler(0, UnusedHandler.get()); UnusedHandler.reset(); + PP.RemovePragmaHandler(0, WeakHandler.get()); + WeakHandler.reset(); } /// Initialize - Warm up the parser. |