From: Peter Collingbourne Date: Mon, 14 Feb 2011 01:42:24 +0000 (+0000) Subject: Make LexOnOffSwitch a Preprocessor member function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9d3f5f7550a2fab4178ed01425758c349b73a609;p=clang Make LexOnOffSwitch a Preprocessor member function git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125473 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 8f61c69f9e..85573de02c 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -244,11 +244,11 @@ def warn_pragma_ignored : Warning<"unknown pragma ignored">, InGroup, DefaultIgnore; def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, InGroup; -def ext_stdc_pragma_syntax : +def ext_on_off_switch_syntax : ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">, InGroup; -def ext_stdc_pragma_syntax_eom : - ExtWarn<"expected end of macro in STDC pragma">, +def ext_pragma_syntax_eom : + ExtWarn<"expected end of macro in pragma">, InGroup; def warn_stdc_fenv_access_not_supported : Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">, diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h index 85dc0671de..515390a8ce 100644 --- a/include/clang/Basic/TokenKinds.h +++ b/include/clang/Basic/TokenKinds.h @@ -43,6 +43,12 @@ enum ObjCKeywordKind { NUM_OBJC_KEYWORDS }; +/// OnOffSwitch - This defines the possible values of an on-off-switch +/// (C99 6.10.6p2). +enum OnOffSwitch { + OOS_ON, OOS_OFF, OOS_DEFAULT +}; + /// \brief Determines the name of a token as used within the front end. /// /// The name of a token will be an internal name (such as "l_square") diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index df3a5b234b..018f7e9c8c 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -843,6 +843,10 @@ public: bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer, SourceLocation &End); + /// LexOnOffSwitch - Lex an on-off-switch (C99 6.10.6p2) and verify that it is + /// followed by EOM. Return true if the token is not a valid on-off-switch. + bool LexOnOffSwitch(tok::OnOffSwitch &OOS); + private: void PushIncludeMacroStack() { diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index da66b502b2..acea2cc886 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -723,6 +723,33 @@ void Preprocessor::RemovePragmaHandler(llvm::StringRef Namespace, PragmaHandlers->RemovePragmaHandler(NS); } +bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) { + Token Tok; + LexUnexpandedToken(Tok); + + if (Tok.isNot(tok::identifier)) { + Diag(Tok, diag::ext_on_off_switch_syntax); + return true; + } + IdentifierInfo *II = Tok.getIdentifierInfo(); + if (II->isStr("ON")) + Result = tok::OOS_ON; + else if (II->isStr("OFF")) + Result = tok::OOS_OFF; + else if (II->isStr("DEFAULT")) + Result = tok::OOS_DEFAULT; + else { + Diag(Tok, diag::ext_on_off_switch_syntax); + return true; + } + + // Verify that this is followed by EOM. + LexUnexpandedToken(Tok); + if (Tok.isNot(tok::eom)) + Diag(Tok, diag::ext_pragma_syntax_eom); + return false; +} + namespace { /// PragmaOnceHandler - "#pragma once" marks the file as atomically included. struct PragmaOnceHandler : public PragmaHandler { @@ -935,38 +962,6 @@ struct PragmaPopMacroHandler : public PragmaHandler { // Pragma STDC implementations. -enum STDCSetting { - STDC_ON, STDC_OFF, STDC_DEFAULT, STDC_INVALID -}; - -static STDCSetting LexOnOffSwitch(Preprocessor &PP) { - Token Tok; - PP.LexUnexpandedToken(Tok); - - if (Tok.isNot(tok::identifier)) { - PP.Diag(Tok, diag::ext_stdc_pragma_syntax); - return STDC_INVALID; - } - IdentifierInfo *II = Tok.getIdentifierInfo(); - STDCSetting Result; - if (II->isStr("ON")) - Result = STDC_ON; - else if (II->isStr("OFF")) - Result = STDC_OFF; - else if (II->isStr("DEFAULT")) - Result = STDC_DEFAULT; - else { - PP.Diag(Tok, diag::ext_stdc_pragma_syntax); - return STDC_INVALID; - } - - // Verify that this is followed by EOM. - PP.LexUnexpandedToken(Tok); - if (Tok.isNot(tok::eom)) - PP.Diag(Tok, diag::ext_stdc_pragma_syntax_eom); - return Result; -} - /// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...". struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler { PragmaSTDC_FP_CONTRACTHandler() : PragmaHandler("FP_CONTRACT") {} @@ -976,7 +971,8 @@ struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler { // at all, our default is OFF and setting it to ON is an optimization hint // we can safely ignore. When we support -ffma or something, we would need // to diagnose that we are ignoring FMA. - LexOnOffSwitch(PP); + tok::OnOffSwitch OOS; + PP.LexOnOffSwitch(OOS); } }; @@ -985,7 +981,10 @@ struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {} virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { - if (LexOnOffSwitch(PP) == STDC_ON) + tok::OnOffSwitch OOS; + if (PP.LexOnOffSwitch(OOS)) + return; + if (OOS == tok::OOS_ON) PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); } }; @@ -996,7 +995,8 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { : PragmaHandler("CX_LIMITED_RANGE") {} virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { - LexOnOffSwitch(PP); + tok::OnOffSwitch OOS; + PP.LexOnOffSwitch(OOS); } }; diff --git a/test/Preprocessor/pragma_unknown.c b/test/Preprocessor/pragma_unknown.c index c1851534cc..0672ade660 100644 --- a/test/Preprocessor/pragma_unknown.c +++ b/test/Preprocessor/pragma_unknown.c @@ -21,7 +21,7 @@ #pragma STDC CX_LIMITED_RANGE IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} #pragma STDC CX_LIMITED_RANGE // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} -#pragma STDC CX_LIMITED_RANGE ON FULL POWER // expected-warning {{expected end of macro in STDC pragma}} +#pragma STDC CX_LIMITED_RANGE ON FULL POWER // expected-warning {{expected end of macro in pragma}} #pragma STDC SO_GREAT // expected-warning {{unknown pragma in STDC namespace}} #pragma STDC // expected-warning {{unknown pragma in STDC namespace}}