Index: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td @@ -505,17 +505,12 @@ def err_pragma_message : Error<"%0">; def warn_pragma_ignored : Warning<"unknown pragma ignored">, InGroup, DefaultIgnore; -def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, - InGroup; def ext_on_off_switch_syntax : ExtWarn<"expected 'ON' or 'OFF' or 'DEFAULT' in pragma">, InGroup; def ext_pragma_syntax_eod : ExtWarn<"expected end of directive in pragma">, InGroup; -def warn_stdc_fenv_access_not_supported : - Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">, - InGroup; def warn_pragma_diagnostic_invalid : ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal'," " 'push', or 'pop'">, Index: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td @@ -973,6 +973,12 @@ def err_pragma_fp_contract_scope : Error< "'#pragma fp_contract' can only appear at file scope or at the start of a " "compound statement">; +// - #pragma stdc unknown +def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, + InGroup; +def warn_stdc_fenv_access_not_supported : + Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">, + InGroup; // - #pragma comment def err_pragma_comment_malformed : Error< "pragma comment requires parenthesized identifier and optional string">; Index: cfe/trunk/include/clang/Parse/Parser.h =================================================================== --- cfe/trunk/include/clang/Parse/Parser.h +++ cfe/trunk/include/clang/Parse/Parser.h @@ -185,6 +185,9 @@ std::unique_ptr UnrollHintHandler; std::unique_ptr NoUnrollHintHandler; std::unique_ptr FPHandler; + std::unique_ptr STDCFENVHandler; + std::unique_ptr STDCCXLIMITHandler; + std::unique_ptr STDCUnknownHandler; std::unique_ptr AttributePragmaHandler; std::unique_ptr CommentSemaHandler; Index: cfe/trunk/lib/Lex/Pragma.cpp =================================================================== --- cfe/trunk/lib/Lex/Pragma.cpp +++ cfe/trunk/lib/Lex/Pragma.cpp @@ -1601,44 +1601,6 @@ } }; -// Pragma STDC implementations. - -/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...". -struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { - PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {} - - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &Tok) override { - tok::OnOffSwitch OOS; - if (PP.LexOnOffSwitch(OOS)) - return; - if (OOS == tok::OOS_ON) - PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); - } -}; - -/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...". -struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { - PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {} - - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &Tok) override { - tok::OnOffSwitch OOS; - PP.LexOnOffSwitch(OOS); - } -}; - -/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...". -struct PragmaSTDC_UnknownHandler : public PragmaHandler { - PragmaSTDC_UnknownHandler() = default; - - void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, - Token &UnknownTok) override { - // C99 6.10.6p2, unknown forms are not allowed. - PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored); - } -}; - /// PragmaARCCFCodeAuditedHandler - /// \#pragma clang arc_cf_code_audited begin/end struct PragmaARCCFCodeAuditedHandler : public PragmaHandler { @@ -1815,10 +1777,6 @@ ModuleHandler->AddPragma(new PragmaModuleBuildHandler()); ModuleHandler->AddPragma(new PragmaModuleLoadHandler()); - AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler()); - AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler()); - AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler()); - // MS extensions. if (LangOpts.MicrosoftExt) { AddPragmaHandler(new PragmaWarningHandler()); @@ -1843,17 +1801,4 @@ // in Preprocessor::RegisterBuiltinPragmas(). AddPragmaHandler("GCC", new EmptyPragmaHandler()); AddPragmaHandler("clang", new EmptyPragmaHandler()); - if (PragmaHandler *NS = PragmaHandlers->FindHandler("STDC")) { - // Preprocessor::RegisterBuiltinPragmas() already registers - // PragmaSTDC_UnknownHandler as the empty handler, so remove it first, - // otherwise there will be an assert about a duplicate handler. - PragmaNamespace *STDCNamespace = NS->getIfNamespace(); - assert(STDCNamespace && - "Invalid namespace, registered as a regular pragma handler!"); - if (PragmaHandler *Existing = STDCNamespace->FindHandler("", false)) { - RemovePragmaHandler("STDC", Existing); - delete Existing; - } - } - AddPragmaHandler("STDC", new EmptyPragmaHandler()); } Index: cfe/trunk/lib/Parse/ParsePragma.cpp =================================================================== --- cfe/trunk/lib/Parse/ParsePragma.cpp +++ cfe/trunk/lib/Parse/ParsePragma.cpp @@ -95,6 +95,44 @@ Token &FirstToken) override; }; +// Pragma STDC implementations. + +/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...". +struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler { + PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + tok::OnOffSwitch OOS; + if (PP.LexOnOffSwitch(OOS)) + return; + if (OOS == tok::OOS_ON) + PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported); + } +}; + +/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...". +struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler { + PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {} + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &Tok) override { + tok::OnOffSwitch OOS; + PP.LexOnOffSwitch(OOS); + } +}; + +/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...". +struct PragmaSTDC_UnknownHandler : public PragmaHandler { + PragmaSTDC_UnknownHandler() = default; + + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &UnknownTok) override { + // C99 6.10.6p2, unknown forms are not allowed. + PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored); + } +}; + struct PragmaFPHandler : public PragmaHandler { PragmaFPHandler() : PragmaHandler("fp") {} void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, @@ -233,6 +271,15 @@ FPContractHandler.reset(new PragmaFPContractHandler()); PP.AddPragmaHandler("STDC", FPContractHandler.get()); + STDCFENVHandler.reset(new PragmaSTDC_FENV_ACCESSHandler()); + PP.AddPragmaHandler("STDC", STDCFENVHandler.get()); + + STDCCXLIMITHandler.reset(new PragmaSTDC_CX_LIMITED_RANGEHandler()); + PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get()); + + STDCUnknownHandler.reset(new PragmaSTDC_UnknownHandler()); + PP.AddPragmaHandler("STDC", STDCUnknownHandler.get()); + PCSectionHandler.reset(new PragmaClangSectionHandler(Actions)); PP.AddPragmaHandler("clang", PCSectionHandler.get()); @@ -371,6 +418,15 @@ PP.RemovePragmaHandler("STDC", FPContractHandler.get()); FPContractHandler.reset(); + PP.RemovePragmaHandler("STDC", STDCFENVHandler.get()); + STDCFENVHandler.reset(); + + PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get()); + STDCCXLIMITHandler.reset(); + + PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get()); + STDCUnknownHandler.reset(); + PP.RemovePragmaHandler("clang", OptimizeHandler.get()); OptimizeHandler.reset(); Index: cfe/trunk/test/Preprocessor/pragma_unknown.c =================================================================== --- cfe/trunk/test/Preprocessor/pragma_unknown.c +++ cfe/trunk/test/Preprocessor/pragma_unknown.c @@ -1,29 +1,45 @@ // RUN: %clang_cc1 -fsyntax-only -Wunknown-pragmas -verify %s -// RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s +// RUN: %clang_cc1 -E %s 2>&1 | FileCheck --strict-whitespace %s // GCC doesn't expand macro args for unrecognized pragmas. #define bar xX #pragma foo bar // expected-warning {{unknown pragma ignored}} +// CHECK-NOT: unknown pragma in STDC namespace // CHECK: {{^}}#pragma foo bar{{$}} #pragma STDC FP_CONTRACT ON #pragma STDC FP_CONTRACT OFF #pragma STDC FP_CONTRACT DEFAULT #pragma STDC FP_CONTRACT IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} +// CHECK: {{^}}#pragma STDC FP_CONTRACT ON{{$}} +// CHECK: {{^}}#pragma STDC FP_CONTRACT OFF{{$}} +// CHECK: {{^}}#pragma STDC FP_CONTRACT DEFAULT{{$}} +// CHECK: {{^}}#pragma STDC FP_CONTRACT IN_BETWEEN{{$}} #pragma STDC FENV_ACCESS ON // expected-warning {{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}} #pragma STDC FENV_ACCESS OFF #pragma STDC FENV_ACCESS DEFAULT #pragma STDC FENV_ACCESS IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} +// CHECK: {{^}}#pragma STDC FENV_ACCESS ON{{$}} +// CHECK: {{^}}#pragma STDC FENV_ACCESS OFF{{$}} +// CHECK: {{^}}#pragma STDC FENV_ACCESS DEFAULT{{$}} +// CHECK: {{^}}#pragma STDC FENV_ACCESS IN_BETWEEN{{$}} #pragma STDC CX_LIMITED_RANGE ON #pragma STDC CX_LIMITED_RANGE OFF #pragma STDC CX_LIMITED_RANGE DEFAULT #pragma STDC CX_LIMITED_RANGE IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} +// CHECK: {{^}}#pragma STDC CX_LIMITED_RANGE ON{{$}} +// CHECK: {{^}}#pragma STDC CX_LIMITED_RANGE OFF{{$}} +// CHECK: {{^}}#pragma STDC CX_LIMITED_RANGE DEFAULT{{$}} +// CHECK: {{^}}#pragma STDC CX_LIMITED_RANGE IN_BETWEEN{{$}} #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 directive in pragma}} +// CHECK: {{^}}#pragma STDC CX_LIMITED_RANGE{{$}} +// CHECK: {{^}}#pragma STDC CX_LIMITED_RANGE ON FULL POWER{{$}} #pragma STDC SO_GREAT // expected-warning {{unknown pragma in STDC namespace}} #pragma STDC // expected-warning {{unknown pragma in STDC namespace}} - +// CHECK: {{^}}#pragma STDC SO_GREAT{{$}} +// CHECK: {{^}}#pragma STDC{{$}}