Move support for "#pragma STDC FP_CONTRACT" to Parser; add Sema actions
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125474 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 74ae70b..6267e65 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -118,6 +118,7 @@
// 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 @@
SpellChecking = 1;
SinglePrecisionConstants = 0;
FastRelaxedMath = 0;
+ DefaultFPContract = 0;
NoBitFieldTypeAlign = 0;
}
@@ -236,6 +238,17 @@
}
};
+/// 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
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index f1cee27..fe65d06 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -122,6 +122,7 @@
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++
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index cfd21df..f35fef8 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -210,6 +210,8 @@
typedef TemplateParameterList TemplateParamsTy;
typedef NestedNameSpecifier CXXScopeTy;
+ FPOptions FPFeatures;
+
const LangOptions &LangOpts;
Preprocessor &PP;
ASTContext &Context;
@@ -544,6 +546,8 @@
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 @@
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);
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index acea2cc..f0475bc 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -962,20 +962,6 @@
// 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 @@
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());
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 90c7d76..41f32fb 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -371,3 +371,14 @@
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);
+}
diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h
index 9dfacea..80894b2 100644
--- a/lib/Parse/ParsePragma.h
+++ b/lib/Parse/ParsePragma.h
@@ -80,6 +80,17 @@
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
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index bb09661..8273d5e 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -50,6 +50,9 @@
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 @@
UnusedHandler.reset();
PP.RemovePragmaHandler(WeakHandler.get());
WeakHandler.reset();
+ PP.RemovePragmaHandler("STDC", FPContractHandler.get());
+ FPContractHandler.reset();
PP.clearCodeCompletionHandler();
}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index eda8888..a1ad784 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -131,7 +131,7 @@
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),
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index c983199..794b0b1 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -350,6 +350,20 @@
}
}
+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