aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTImporter.cpp7
-rw-r--r--clang/lib/AST/JSONNodeDumper.cpp15
-rw-r--r--clang/lib/AST/Stmt.cpp24
-rw-r--r--clang/lib/AST/StmtPrinter.cpp62
-rw-r--r--clang/lib/AST/TextNodeDumper.cpp6
-rw-r--r--clang/lib/Analysis/BodyFarm.cpp3
-rw-r--r--clang/lib/Basic/LangOptions.cpp9
-rw-r--r--clang/lib/CodeGen/CGCoroutine.cpp4
-rw-r--r--clang/lib/Sema/Sema.cpp3
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp8
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp5
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp9
-rw-r--r--clang/lib/Sema/SemaStmt.cpp11
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp8
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp3
15 files changed, 150 insertions, 27 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 8d930ea..e973011 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -6339,9 +6339,10 @@ ExpectedStmt ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
if (!ToRBracLocOrErr)
return ToRBracLocOrErr.takeError();
- return CompoundStmt::Create(
- Importer.getToContext(), ToStmts,
- *ToLBracLocOrErr, *ToRBracLocOrErr);
+ FPOptionsOverride FPO =
+ S->hasStoredFPFeatures() ? S->getStoredFPFeatures() : FPOptionsOverride();
+ return CompoundStmt::Create(Importer.getToContext(), ToStmts, FPO,
+ *ToLBracLocOrErr, *ToRBracLocOrErr);
}
ExpectedStmt ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index ae585de..87e4255 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -1692,3 +1692,18 @@ void JSONNodeDumper::visitVerbatimLineComment(
const comments::VerbatimLineComment *C, const comments::FullComment *) {
JOS.attribute("text", C->getText());
}
+
+llvm::json::Object JSONNodeDumper::createFPOptions(FPOptionsOverride FPO) {
+ llvm::json::Object Ret;
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
+ if (FPO.has##NAME##Override()) \
+ Ret.try_emplace(#NAME, static_cast<unsigned>(FPO.get##NAME##Override()));
+#include "clang/Basic/FPOptions.def"
+ return Ret;
+}
+
+void JSONNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
+ VisitStmt(S);
+ if (S->hasStoredFPFeatures())
+ JOS.attribute("fpoptions", createFPOptions(S->getStoredFPFeatures()));
+}
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index d562717..8eae04d 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -361,11 +361,14 @@ int64_t Stmt::getID(const ASTContext &Context) const {
return Context.getAllocator().identifyKnownAlignedObject<Stmt>(this);
}
-CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB,
- SourceLocation RB)
+CompoundStmt::CompoundStmt(ArrayRef<Stmt *> Stmts, FPOptionsOverride FPFeatures,
+ SourceLocation LB, SourceLocation RB)
: Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
CompoundStmtBits.NumStmts = Stmts.size();
+ CompoundStmtBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
setStmts(Stmts);
+ if (hasStoredFPFeatures())
+ setStoredFPFeatures(FPFeatures);
}
void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
@@ -376,18 +379,23 @@ void CompoundStmt::setStmts(ArrayRef<Stmt *> Stmts) {
}
CompoundStmt *CompoundStmt::Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
+ FPOptionsOverride FPFeatures,
SourceLocation LB, SourceLocation RB) {
void *Mem =
- C.Allocate(totalSizeToAlloc<Stmt *>(Stmts.size()), alignof(CompoundStmt));
- return new (Mem) CompoundStmt(Stmts, LB, RB);
+ C.Allocate(totalSizeToAlloc<Stmt *, FPOptionsOverride>(
+ Stmts.size(), FPFeatures.requiresTrailingStorage()),
+ alignof(CompoundStmt));
+ return new (Mem) CompoundStmt(Stmts, FPFeatures, LB, RB);
}
-CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C,
- unsigned NumStmts) {
- void *Mem =
- C.Allocate(totalSizeToAlloc<Stmt *>(NumStmts), alignof(CompoundStmt));
+CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C, unsigned NumStmts,
+ bool HasFPFeatures) {
+ void *Mem = C.Allocate(
+ totalSizeToAlloc<Stmt *, FPOptionsOverride>(NumStmts, HasFPFeatures),
+ alignof(CompoundStmt));
CompoundStmt *New = new (Mem) CompoundStmt(EmptyShell());
New->CompoundStmtBits.NumStmts = NumStmts;
+ New->CompoundStmtBits.HasFPFeatures = HasFPFeatures;
return New;
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 0a959fa..8d77850 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -128,6 +128,7 @@ namespace {
void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
void PrintOMPExecutableDirective(OMPExecutableDirective *S,
bool ForceNoStmt = false);
+ void PrintFPPragmas(CompoundStmt *S);
void PrintExpr(Expr *E) {
if (E)
@@ -174,12 +175,73 @@ namespace {
/// with no newline after the }.
void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
OS << "{" << NL;
+ PrintFPPragmas(Node);
for (auto *I : Node->body())
PrintStmt(I);
Indent() << "}";
}
+void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {
+ if (!S->hasStoredFPFeatures())
+ return;
+ FPOptionsOverride FPO = S->getStoredFPFeatures();
+ bool FEnvAccess = false;
+ if (FPO.hasAllowFEnvAccessOverride()) {
+ FEnvAccess = FPO.getAllowFEnvAccessOverride();
+ Indent() << "#pragma STDC FENV_ACCESS " << (FEnvAccess ? "ON" : "OFF")
+ << NL;
+ }
+ if (FPO.hasSpecifiedExceptionModeOverride()) {
+ LangOptions::FPExceptionModeKind EM =
+ FPO.getSpecifiedExceptionModeOverride();
+ if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
+ Indent() << "#pragma clang fp exceptions(";
+ switch (FPO.getSpecifiedExceptionModeOverride()) {
+ default:
+ break;
+ case LangOptions::FPE_Ignore:
+ OS << "ignore";
+ break;
+ case LangOptions::FPE_MayTrap:
+ OS << "maytrap";
+ break;
+ case LangOptions::FPE_Strict:
+ OS << "strict";
+ break;
+ }
+ OS << ")\n";
+ }
+ }
+ if (FPO.hasConstRoundingModeOverride()) {
+ LangOptions::RoundingMode RM = FPO.getConstRoundingModeOverride();
+ Indent() << "#pragma STDC FENV_ROUND ";
+ switch (RM) {
+ case llvm::RoundingMode::TowardZero:
+ OS << "FE_TOWARDZERO";
+ break;
+ case llvm::RoundingMode::NearestTiesToEven:
+ OS << "FE_TONEAREST";
+ break;
+ case llvm::RoundingMode::TowardPositive:
+ OS << "FE_UPWARD";
+ break;
+ case llvm::RoundingMode::TowardNegative:
+ OS << "FE_DOWNWARD";
+ break;
+ case llvm::RoundingMode::NearestTiesToAway:
+ OS << "FE_TONEARESTFROMZERO";
+ break;
+ case llvm::RoundingMode::Dynamic:
+ OS << "FE_DYNAMIC";
+ break;
+ default:
+ llvm_unreachable("Invalid rounding mode");
+ }
+ OS << NL;
+ }
+}
+
void StmtPrinter::PrintRawDecl(Decl *D) {
D->print(OS, Policy, IndentLevel);
}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 7c48fd2..79e9fa6 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -2371,3 +2371,9 @@ void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
dumpName(D);
}
+
+void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
+ VisitStmt(S);
+ if (S->hasStoredFPFeatures())
+ printFPOptions(S->getStoredFPFeatures());
+}
diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp
index 8de6927..23d37b8 100644
--- a/clang/lib/Analysis/BodyFarm.cpp
+++ b/clang/lib/Analysis/BodyFarm.cpp
@@ -134,7 +134,8 @@ BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
}
CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
- return CompoundStmt::Create(C, Stmts, SourceLocation(), SourceLocation());
+ return CompoundStmt::Create(C, Stmts, FPOptionsOverride(), SourceLocation(),
+ SourceLocation());
}
DeclRefExpr *ASTMaker::makeDeclRefExpr(
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index 0bf410c..753b6bf 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -204,6 +204,15 @@ FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
return result;
}
+FPOptionsOverride FPOptions::getChangesSlow(const FPOptions &Base) const {
+ FPOptions::storage_type OverrideMask = 0;
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
+ if (get##NAME() != Base.get##NAME()) \
+ OverrideMask |= NAME##Mask;
+#include "clang/Basic/FPOptions.def"
+ return FPOptionsOverride(*this, OverrideMask);
+}
+
LLVM_DUMP_METHOD void FPOptions::dump() {
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
llvm::errs() << "\n " #NAME " " << get##NAME();
diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp
index 4216ca1..594c7d4 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -238,8 +238,8 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co
auto Loc = S.getResumeExpr()->getExprLoc();
auto *Catch = new (CGF.getContext())
CXXCatchStmt(Loc, /*exDecl=*/nullptr, Coro.ExceptionHandler);
- auto *TryBody =
- CompoundStmt::Create(CGF.getContext(), S.getResumeExpr(), Loc, Loc);
+ auto *TryBody = CompoundStmt::Create(CGF.getContext(), S.getResumeExpr(),
+ FPOptionsOverride(), Loc, Loc);
TryStmt = CXXTryStmt::Create(CGF.getContext(), Loc, TryBody, Catch);
CGF.EnterCXXTryStmt(*TryStmt);
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index e2ec8ee..326010d 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2219,7 +2219,8 @@ operator()(sema::FunctionScopeInfo *Scope) const {
}
void Sema::PushCompoundScope(bool IsStmtExpr) {
- getCurFunction()->CompoundScopes.push_back(CompoundScopeInfo(IsStmtExpr));
+ getCurFunction()->CompoundScopes.push_back(
+ CompoundScopeInfo(IsStmtExpr, getCurFPFeatures()));
}
void Sema::PopCompoundScope() {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index a70c857..221cbd1 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -15353,8 +15353,8 @@ void Sema::DefineImplicitLambdaToFunctionPointerConversion(
VK_LValue, Conv->getLocation());
assert(FunctionRef && "Can't refer to __invoke function?");
Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
- Conv->setBody(CompoundStmt::Create(Context, Return, Conv->getLocation(),
- Conv->getLocation()));
+ Conv->setBody(CompoundStmt::Create(Context, Return, FPOptionsOverride(),
+ Conv->getLocation(), Conv->getLocation()));
Conv->markUsed(Context);
Conv->setReferenced();
@@ -15408,8 +15408,8 @@ void Sema::DefineImplicitLambdaToBlockPointerConversion(
// Set the body of the conversion function.
Stmt *ReturnS = Return.get();
- Conv->setBody(CompoundStmt::Create(Context, ReturnS, Conv->getLocation(),
- Conv->getLocation()));
+ Conv->setBody(CompoundStmt::Create(Context, ReturnS, FPOptionsOverride(),
+ Conv->getLocation(), Conv->getLocation()));
Conv->markUsed(Context);
// We're done; notify the mutation listener, if any.
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index fadcdc4..0d73fcf 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7295,8 +7295,9 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
// a StmtExpr; currently this is only used for asm statements.
// This is hacky, either create a new CXXStmtWithTemporaries statement or
// a new AsmStmtWithTemporaries.
- CompoundStmt *CompStmt = CompoundStmt::Create(
- Context, SubStmt, SourceLocation(), SourceLocation());
+ CompoundStmt *CompStmt =
+ CompoundStmt::Create(Context, SubStmt, FPOptionsOverride(),
+ SourceLocation(), SourceLocation());
Expr *E = new (Context)
StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(),
/*FIXME TemplateDepth=*/0);
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 117fec4..6f50196 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -14681,8 +14681,8 @@ StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
SmallVector<Stmt *, 4> BodyParts;
BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
BodyParts.push_back(Inner);
- Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
- Inner->getEndLoc());
+ Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
+ Inner->getBeginLoc(), Inner->getEndLoc());
Inner = new (Context)
ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
@@ -14956,8 +14956,9 @@ StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
SmallVector<Stmt *> InnerBodyStmts;
InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
InnerBodyStmts.push_back(Body);
- CompoundStmt *InnerBody = CompoundStmt::Create(
- Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
+ CompoundStmt *InnerBody =
+ CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
+ Body->getBeginLoc(), Body->getEndLoc());
ForStmt *InnerFor = new (Context)
ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 82831a4..f25694c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -442,7 +442,16 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
}
- return CompoundStmt::Create(Context, Elts, L, R);
+ // Calculate difference between FP options in this compound statement and in
+ // the enclosing one. If this is a function body, take the difference against
+ // default options. In this case the difference will indicate options that are
+ // changed upon entry to the statement.
+ FPOptions FPO = (getCurFunction()->CompoundScopes.size() == 1)
+ ? FPOptions(getLangOpts())
+ : getCurCompoundScope().InitialFPFeatures;
+ FPOptionsOverride FPDiff = getCurFPFeatures().getChangesFrom(FPO);
+
+ return CompoundStmt::Create(Context, Elts, FPDiff, L, R);
}
ExprResult
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 0b715bc1..e0ae019 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -152,9 +152,14 @@ void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
VisitStmt(S);
SmallVector<Stmt *, 16> Stmts;
unsigned NumStmts = Record.readInt();
+ unsigned HasFPFeatures = Record.readInt();
+ assert(S->hasStoredFPFeatures() == HasFPFeatures);
while (NumStmts--)
Stmts.push_back(Record.readSubStmt());
S->setStmts(Stmts);
+ if (HasFPFeatures)
+ S->setStoredFPFeatures(
+ FPOptionsOverride::getFromOpaqueInt(Record.readInt()));
S->LBraceLoc = readSourceLocation();
S->RBraceLoc = readSourceLocation();
}
@@ -2768,7 +2773,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
case STMT_COMPOUND:
S = CompoundStmt::CreateEmpty(
- Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields]);
+ Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields],
+ /*HasFPFeatures=*/Record[ASTStmtReader::NumStmtFields + 1]);
break;
case STMT_CASE:
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index f3e0868..5e5a86e 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -81,8 +81,11 @@ void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
VisitStmt(S);
Record.push_back(S->size());
+ Record.push_back(S->hasStoredFPFeatures());
for (auto *CS : S->body())
Record.AddStmt(CS);
+ if (S->hasStoredFPFeatures())
+ Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
Record.AddSourceLocation(S->getLBracLoc());
Record.AddSourceLocation(S->getRBracLoc());
Code = serialization::STMT_COMPOUND;