diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/JSONNodeDumper.cpp | 15 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 24 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 62 | ||||
-rw-r--r-- | clang/lib/AST/TextNodeDumper.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Analysis/BodyFarm.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Basic/LangOptions.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCoroutine.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 3 |
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; |