forked from OSchip/llvm-project
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 llvm-svn: 339693
This commit is contained in:
parent
ba74d1c4ea
commit
2c0bc8b7a3
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue