aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin P. Neal <kevin.neal@sas.com>2018-08-14 17:06:56 +0000
committerKevin P. Neal <kevin.neal@sas.com>2018-08-14 17:06:56 +0000
commit26dbd400930e046ea1730e14fd70a9e3c16cb14a (patch)
treee673171dee3bf6f0f06fe09e57dfd500d2792f43
parent7964dc77eed2dd83115b7672dbd57ea7d468cd33 (diff)
We have in place support for parsing #pragma FENV_ACCESS, but that
information is then discarded with a warning to the user that we don't support it. This patch gets us one step closer by getting the info down into the AST in most cases. Reviewed by: rsmith Differential Revision: https://reviews.llvm.org/D49865 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339693 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Expr.h8
-rw-r--r--include/clang/Basic/LangOptions.h35
-rw-r--r--include/clang/Basic/TokenKinds.def5
-rw-r--r--include/clang/Parse/Parser.h4
-rw-r--r--include/clang/Sema/Sema.h4
-rw-r--r--lib/Parse/ParsePragma.cpp37
-rw-r--r--lib/Parse/ParseStmt.cpp8
-rw-r--r--lib/Parse/Parser.cpp3
-rw-r--r--lib/Sema/SemaAttr.cpp12
9 files changed, 109 insertions, 7 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 0a457d6b97..474b796ea6 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -3269,7 +3269,7 @@ private:
// This is only meaningful for operations on floating point types and 0
// otherwise.
- unsigned FPFeatures : 2;
+ unsigned FPFeatures : 3;
SourceLocation OpLoc;
enum { LHS, RHS, END_EXPR };
@@ -3448,6 +3448,12 @@ public:
return FPOptions(FPFeatures).allowFPContractWithinStatement();
}
+ // Get the FENV_ACCESS status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFEnvAccessOn() const {
+ return FPOptions(FPFeatures).allowFEnvAccess();
+ }
+
protected:
BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index a1396f8435..a7a5105fdf 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -137,6 +137,14 @@ public:
FPC_Fast
};
+ // TODO: merge FEnvAccessModeKind and FPContractModeKind
+ enum FEnvAccessModeKind {
+ FEA_Off,
+
+ FEA_On
+ };
+
+
public:
/// Set of enabled sanitizers.
SanitizerSet Sanitize;
@@ -262,14 +270,19 @@ public:
/// Floating point control options
class FPOptions {
public:
- FPOptions() : fp_contract(LangOptions::FPC_Off) {}
+ FPOptions() : fp_contract(LangOptions::FPC_Off),
+ fenv_access(LangOptions::FEA_Off) {}
// Used for serializing.
explicit FPOptions(unsigned I)
- : fp_contract(static_cast<LangOptions::FPContractModeKind>(I)) {}
+ : fp_contract(static_cast<LangOptions::FPContractModeKind>(I & 3)),
+ fenv_access(static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1))
+ {}
explicit FPOptions(const LangOptions &LangOpts)
- : fp_contract(LangOpts.getDefaultFPContractMode()) {}
+ : fp_contract(LangOpts.getDefaultFPContractMode()),
+ fenv_access(LangOptions::FEA_Off) {}
+ // FIXME: Use getDefaultFEnvAccessMode() when available.
bool allowFPContractWithinStatement() const {
return fp_contract == LangOptions::FPC_On;
@@ -289,12 +302,24 @@ public:
void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
+ bool allowFEnvAccess() const {
+ return fenv_access == LangOptions::FEA_On;
+ }
+
+ void setAllowFEnvAccess() {
+ fenv_access = LangOptions::FEA_On;
+ }
+
+ void setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; }
+
/// Used to serialize this.
- unsigned getInt() const { return fp_contract; }
+ unsigned getInt() const { return fp_contract | (fenv_access << 2); }
private:
- /// Adjust BinaryOperator::FPFeatures to match the bit-field size of this.
+ /// Adjust BinaryOperator::FPFeatures to match the total bit-field size
+ /// of these two.
unsigned fp_contract : 2;
+ unsigned fenv_access : 1;
};
/// Describes the kind of translation unit being processed.
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 30cb022f1c..caea67adba 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -780,6 +780,11 @@ ANNOTATION(pragma_redefine_extname)
// handles them.
ANNOTATION(pragma_fp_contract)
+// Annotation for #pragma STDC FENV_ACCESS
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_fenv_access)
+
// Annotation for #pragma pointers_to_members...
// The lexer produces these so that they only take effect when the parser
// handles them.
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 1d6849cd5b..32874ee44f 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -670,6 +670,10 @@ private:
void HandlePragmaFPContract();
/// Handle the annotation token produced for
+ /// #pragma STDC FENV_ACCESS...
+ void HandlePragmaFEnvAccess();
+
+ /// \brief Handle the annotation token produced for
/// #pragma clang fp ...
void HandlePragmaFP();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index b3d1c96bdf..aa6e4b7cfe 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -8434,6 +8434,10 @@ public:
/// \#pragma clang fp contract
void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC);
+ /// ActOnPragmaFenvAccess - Called on well formed
+ /// \#pragma STDC FENV_ACCESS
+ void ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC);
+
/// 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/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index fb862c706f..26b363f280 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -106,8 +106,19 @@ struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
tok::OnOffSwitch OOS;
if (PP.LexOnOffSwitch(OOS))
return;
- if (OOS == tok::OOS_ON)
+ if (OOS == tok::OOS_ON) {
PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
+ }
+
+ MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
+ 1);
+ Toks[0].startToken();
+ Toks[0].setKind(tok::annot_pragma_fenv_access);
+ Toks[0].setLocation(Tok.getLocation());
+ Toks[0].setAnnotationEndLoc(Tok.getLocation());
+ Toks[0].setAnnotationValue(reinterpret_cast<void*>(
+ static_cast<uintptr_t>(OOS)));
+ PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
}
};
@@ -604,6 +615,30 @@ void Parser::HandlePragmaFPContract() {
ConsumeAnnotationToken();
}
+void Parser::HandlePragmaFEnvAccess() {
+ assert(Tok.is(tok::annot_pragma_fenv_access));
+ tok::OnOffSwitch OOS =
+ static_cast<tok::OnOffSwitch>(
+ reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
+
+ LangOptions::FEnvAccessModeKind FPC;
+ switch (OOS) {
+ case tok::OOS_ON:
+ FPC = LangOptions::FEA_On;
+ break;
+ case tok::OOS_OFF:
+ FPC = LangOptions::FEA_Off;
+ break;
+ case tok::OOS_DEFAULT: // FIXME: Add this cli option when it makes sense.
+ FPC = LangOptions::FEA_Off;
+ break;
+ }
+
+ Actions.ActOnPragmaFEnvAccess(FPC);
+ ConsumeAnnotationToken();
+}
+
+
StmtResult Parser::HandlePragmaCaptured()
{
assert(Tok.is(tok::annot_pragma_captured));
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 338a8ab7e8..574293f518 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -348,6 +348,11 @@ Retry:
ConsumeAnnotationToken();
return StmtError();
+ case tok::annot_pragma_fenv_access:
+ ProhibitAttributes(Attrs);
+ HandlePragmaFEnvAccess();
+ return StmtEmpty();
+
case tok::annot_pragma_opencl_extension:
ProhibitAttributes(Attrs);
HandlePragmaOpenCLExtension();
@@ -902,6 +907,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() {
case tok::annot_pragma_fp:
HandlePragmaFP();
break;
+ case tok::annot_pragma_fenv_access:
+ HandlePragmaFEnvAccess();
+ break;
case tok::annot_pragma_ms_pointers_to_members:
HandlePragmaMSPointersToMembers();
break;
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index c3085654f5..1736629121 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -674,6 +674,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
case tok::annot_pragma_fp_contract:
HandlePragmaFPContract();
return nullptr;
+ case tok::annot_pragma_fenv_access:
+ HandlePragmaFEnvAccess();
+ return nullptr;
case tok::annot_pragma_fp:
HandlePragmaFP();
break;
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 056d031fd8..8024e1a051 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -773,6 +773,18 @@ void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) {
}
}
+void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) {
+ switch (FPC) {
+ case LangOptions::FEA_On:
+ FPFeatures.setAllowFEnvAccess();
+ break;
+ case LangOptions::FEA_Off:
+ FPFeatures.setDisallowFEnvAccess();
+ break;
+ }
+}
+
+
void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
SourceLocation Loc) {
// Visibility calculations will consider the namespace's visibility.