Add parser support for #pragma weak.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72907 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 2912344..81afac9 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -264,6 +264,8 @@
"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 5c23f9a..eadff63 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -1756,7 +1756,23 @@
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 26e37e2..6218ade 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -81,6 +81,7 @@
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 94695e4..58c729a 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -100,6 +100,12 @@
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 @@
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 @@
// 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 31b2a5f..39c86ee 100644
--- a/lib/Parse/ParsePragma.h
+++ b/lib/Parse/ParsePragma.h
@@ -39,6 +39,15 @@
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 1c2e8a6..a2a66f9 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -39,6 +39,10 @@
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 @@
PackHandler.reset();
PP.RemovePragmaHandler(0, UnusedHandler.get());
UnusedHandler.reset();
+ PP.RemovePragmaHandler(0, WeakHandler.get());
+ WeakHandler.reset();
}
/// Initialize - Warm up the parser.