]> granicus.if.org Git - clang/commitdiff
Move support for "#pragma STDC FP_CONTRACT" to Parser; add Sema actions
authorPeter Collingbourne <peter@pcc.me.uk>
Mon, 14 Feb 2011 01:42:35 +0000 (01:42 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Mon, 14 Feb 2011 01:42:35 +0000 (01:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125474 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.h
include/clang/Parse/Parser.h
include/clang/Sema/Sema.h
lib/Lex/Pragma.cpp
lib/Parse/ParsePragma.cpp
lib/Parse/ParsePragma.h
lib/Parse/Parser.cpp
lib/Sema/Sema.cpp
lib/Sema/SemaAttr.cpp

index 74ae70b52e68cc9ea1497895e896d4d0e52d3458..6267e65fbe28ea9dc424eb952e6354610df2df33 100644 (file)
@@ -118,6 +118,7 @@ public:
                                          // single precision constants.
   unsigned FastRelaxedMath : 1; // OpenCL fast relaxed math (on its own,
                                 // defines __FAST_RELAXED_MATH__).
+  unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT
   // FIXME: This is just a temporary option, for testing purposes.
   unsigned NoBitFieldTypeAlign : 1;
 
@@ -210,6 +211,7 @@ public:
     SpellChecking = 1;
     SinglePrecisionConstants = 0;
     FastRelaxedMath = 0;
+    DefaultFPContract = 0;
     NoBitFieldTypeAlign = 0;
   }
 
@@ -236,6 +238,17 @@ public:
   }
 };
 
+/// Floating point control options
+class FPOptions {
+public:
+  unsigned fp_contract : 1;
+
+  FPOptions() : fp_contract(0) {}
+
+  FPOptions(const LangOptions &LangOpts) :
+    fp_contract(LangOpts.DefaultFPContract) {}
+};
+
 }  // end namespace clang
 
 #endif
index f1cee277b906b07ca91fb983c6c0d65271196c3b..fe65d06e6c38ecbee21ec8a3a95817099f66f60d 100644 (file)
@@ -122,6 +122,7 @@ class Parser : public CodeCompletionHandler {
   llvm::OwningPtr<PragmaHandler> PackHandler;
   llvm::OwningPtr<PragmaHandler> UnusedHandler;
   llvm::OwningPtr<PragmaHandler> WeakHandler;
+  llvm::OwningPtr<PragmaHandler> FPContractHandler;
 
   /// Whether the '>' token acts as an operator or not. This will be
   /// true except when we are parsing an expression within a C++
index cfd21df753b81d11a9af8813e8e14fdec21ca427..f35fef89529264f61a618a142c79128ea941523e 100644 (file)
@@ -210,6 +210,8 @@ public:
   typedef TemplateParameterList TemplateParamsTy;
   typedef NestedNameSpecifier CXXScopeTy;
 
+  FPOptions FPFeatures;
+
   const LangOptions &LangOpts;
   Preprocessor &PP;
   ASTContext &Context;
@@ -544,6 +546,8 @@ public:
   void Initialize();
   
   const LangOptions &getLangOptions() const { return LangOpts; }
+  FPOptions     &getFPOptions() { return FPFeatures; }
+
   Diagnostic &getDiagnostics() const { return Diags; }
   SourceManager &getSourceManager() const { return SourceMgr; }
   const TargetAttributesSema &getTargetAttributesSema() const;
@@ -4407,6 +4411,10 @@ public:
                             SourceLocation WeakNameLoc,
                             SourceLocation AliasNameLoc);
 
+  /// ActOnPragmaFPContract - Called on well formed
+  /// #pragma STDC FP_CONTRACT
+  void ActOnPragmaFPContract(tok::OnOffSwitch OOS);
+
   /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
   /// a the record decl, to handle '#pragma pack' and '#pragma options align'.
   void AddAlignmentAttributesForRecord(RecordDecl *RD);
index acea2cc886ce2f98f6cfd7e0f895f45acbaf8a5f..f0475bc0cb2016df369de237f450c8312a06dea7 100644 (file)
@@ -962,20 +962,6 @@ struct PragmaPopMacroHandler : public PragmaHandler {
 
 // Pragma STDC implementations.
 
-/// PragmaSTDC_FP_CONTRACTHandler - "#pragma STDC FP_CONTRACT ...".
-struct PragmaSTDC_FP_CONTRACTHandler : public PragmaHandler {
-  PragmaSTDC_FP_CONTRACTHandler() : PragmaHandler("FP_CONTRACT") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &Tok) {
-    // We just ignore the setting of FP_CONTRACT. Since we don't do contractions
-    // 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.
-    tok::OnOffSwitch OOS;
-    PP.LexOnOffSwitch(OOS);
-  }
-};
-
 /// PragmaSTDC_FENV_ACCESSHandler - "#pragma STDC FENV_ACCESS ...".
 struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
   PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
@@ -1034,7 +1020,6 @@ void Preprocessor::RegisterBuiltinPragmas() {
   AddPragmaHandler("clang", new PragmaDependencyHandler());
   AddPragmaHandler("clang", new PragmaDiagnosticHandler());
 
-  AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler());
   AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
   AddPragmaHandler("STDC", new PragmaSTDC_CX_LIMITED_RANGEHandler());
   AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
index 90c7d76cbcccd002b65aaa17748d55f56dcb9169..41f32fb945662d6e81fc24d4817acb710618a45c 100644 (file)
@@ -371,3 +371,14 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
     Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
   }
 }
+
+void
+PragmaFPContractHandler::HandlePragma(Preprocessor &PP, 
+                                      PragmaIntroducerKind Introducer,
+                                      Token &Tok) {
+  tok::OnOffSwitch OOS;
+  if (PP.LexOnOffSwitch(OOS))
+    return;
+
+  Actions.ActOnPragmaFPContract(OOS);
+}
index 9dfaceaeadd7f338648ad7cde7588bf61e25c2d7..80894b28d85dec1379267705561377dee05f76fe 100644 (file)
@@ -80,6 +80,17 @@ public:
                             Token &FirstToken);
 };
 
+class PragmaFPContractHandler : public PragmaHandler {
+  Sema &Actions;
+  Parser &parser;
+public:
+  PragmaFPContractHandler(Sema &S, Parser& p) : 
+    PragmaHandler("FP_CONTRACT"), Actions(S), parser(p) {}
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                            Token &FirstToken);
+};
+  
+
 }  // end namespace clang
 
 #endif
index bb0966111ebb68ef1b39c0ab087343b5e715e5ab..8273d5e2d15a8354829d7e5312956b780fef8c35 100644 (file)
@@ -50,6 +50,9 @@ Parser::Parser(Preprocessor &pp, Sema &actions)
 
   WeakHandler.reset(new PragmaWeakHandler(actions));
   PP.AddPragmaHandler(WeakHandler.get());
+
+  FPContractHandler.reset(new PragmaFPContractHandler(actions, *this));
+  PP.AddPragmaHandler("STDC", FPContractHandler.get());
       
   PP.setCodeCompletionHandler(*this);
 }
@@ -360,6 +363,8 @@ Parser::~Parser() {
   UnusedHandler.reset();
   PP.RemovePragmaHandler(WeakHandler.get());
   WeakHandler.reset();
+  PP.RemovePragmaHandler("STDC", FPContractHandler.get());
+  FPContractHandler.reset();
   PP.clearCodeCompletionHandler();
 }
 
index eda88881a408f8e649e52b5b82d59c6b8ce09665..a1ad78418f4da4202add2bbbcd4bf371f992c3c6 100644 (file)
@@ -131,7 +131,7 @@ void Sema::ActOnTranslationUnitScope(Scope *S) {
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
            bool CompleteTranslationUnit,
            CodeCompleteConsumer *CodeCompleter)
-  : TheTargetAttributesSema(0),
+  : TheTargetAttributesSema(0), FPFeatures(pp.getLangOptions()),
     LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
index c983199cf910d743702e340fefa5c94bf92ba0de..794b0b1f1cfa01dcd98220a491dab473a88f4dcf 100644 (file)
@@ -350,6 +350,20 @@ void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
   }
 }
 
+void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
+  switch (OOS) {
+  case tok::OOS_ON:
+    FPFeatures.fp_contract = 1;
+    break;
+  case tok::OOS_OFF:
+    FPFeatures.fp_contract = 0; 
+    break;
+  case tok::OOS_DEFAULT:
+    FPFeatures.fp_contract = getLangOptions().DefaultFPContract;
+    break;
+  }
+}
+
 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr) {
   // Visibility calculations will consider the namespace's visibility.
   // Here we just want to note that we're in a visibility context