aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-03-18 18:20:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-03-18 18:20:05 +0000
commit2fc9bb9ce23aec06620745773d24e59944b87ffc (patch)
tree0726fa11e6594591f34578ba035ea82a69fc0393
parentd652fd2996ce31dfd35dd2a9c58bf051ca7fff44 (diff)
downloadsrc-2fc9bb9ce23aec06620745773d24e59944b87ffc.tar.gz
src-2fc9bb9ce23aec06620745773d24e59944b87ffc.zip
Vendor import of llvm-project branch release/10.xvendor/llvm-project/llvmorg-10.0.0-rc4-5-g52c365aa9ca
llvmorg-10.0.0-rc4-5-g52c365aa9ca.
Notes
Notes: svn path=/vendor/llvm-project/release-10.x/; revision=359079 svn path=/vendor/llvm-project/llvmorg-10.0.0-rc4-5-g52c365aa9ca/; revision=359080; tag=vendor/llvm-project/llvmorg-10.0.0-rc4-5-g52c365aa9ca
-rw-r--r--clang/include/clang/AST/Expr.h22
-rw-r--r--clang/include/clang/AST/Stmt.h15
-rw-r--r--clang/include/clang/Sema/Sema.h41
-rw-r--r--clang/include/clang/Sema/Template.h10
-rw-r--r--clang/lib/AST/ASTImporter.cpp2
-rw-r--r--clang/lib/Lex/Pragma.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp17
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp54
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp6
-rw-r--r--clang/lib/Sema/TreeTransform.h23
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp67
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp2
-rw-r--r--clang/tools/driver/driver.cpp22
-rw-r--r--llvm/include/llvm/Support/ManagedStatic.h6
-rw-r--r--llvm/include/llvm/Support/Timer.h5
-rw-r--r--llvm/lib/Support/Timer.cpp4
18 files changed, 258 insertions, 45 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index bcb960540001..7ff53ef7c653 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -3955,14 +3955,18 @@ class StmtExpr : public Expr {
Stmt *SubStmt;
SourceLocation LParenLoc, RParenLoc;
public:
- StmtExpr(CompoundStmt *substmt, QualType T,
- SourceLocation lp, SourceLocation rp, bool InDependentContext) :
- // Note: we treat a statement-expression in a dependent context as always
- // being value- and instantiation-dependent. This matches the behavior of
- // lambda-expressions and GCC.
- Expr(StmtExprClass, T, VK_RValue, OK_Ordinary,
- T->isDependentType(), InDependentContext, InDependentContext, false),
- SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) {}
+ StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParenLoc,
+ SourceLocation RParenLoc, unsigned TemplateDepth)
+ : // We treat a statement-expression in a dependent context as
+ // always being value- and instantiation-dependent. This matches the
+ // behavior of lambda-expressions and GCC.
+ Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, T->isDependentType(),
+ TemplateDepth != 0, TemplateDepth != 0, false),
+ SubStmt(SubStmt), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+ // FIXME: A templated statement expression should have an associated
+ // DeclContext so that nested declarations always have a dependent context.
+ StmtExprBits.TemplateDepth = TemplateDepth;
+ }
/// Build an empty statement expression.
explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { }
@@ -3979,6 +3983,8 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+ unsigned getTemplateDepth() const { return StmtExprBits.TemplateDepth; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == StmtExprClass;
}
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 253b76941991..3aa2745937b1 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -588,6 +588,18 @@ protected:
unsigned Kind : 2;
};
+ class StmtExprBitfields {
+ friend class ASTStmtReader;
+ friend class StmtExpr;
+
+ unsigned : NumExprBits;
+
+ /// The number of levels of template parameters enclosing this statement
+ /// expression. Used to determine if a statement expression remains
+ /// dependent after instantiation.
+ unsigned TemplateDepth;
+ };
+
//===--- C++ Expression bitfields classes ---===//
class CXXOperatorCallExprBitfields {
@@ -996,6 +1008,9 @@ protected:
PseudoObjectExprBitfields PseudoObjectExprBits;
SourceLocExprBitfields SourceLocExprBits;
+ // GNU Extensions.
+ StmtExprBitfields StmtExprBits;
+
// C++ Expressions
CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 2b5f7c1a7203..033f7af6f2f3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -620,6 +620,15 @@ public:
/// function, block, and method scopes that are currently active.
SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes;
+ /// The index of the first FunctionScope that corresponds to the current
+ /// context.
+ unsigned FunctionScopesStart = 0;
+
+ ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const {
+ return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart,
+ FunctionScopes.end());
+ }
+
/// Stack containing information needed when in C++2a an 'auto' is encountered
/// in a function declaration parameter type specifier in order to invent a
/// corresponding template parameter in the enclosing abbreviated function
@@ -627,6 +636,16 @@ public:
/// the FunctionScopes stack.
SmallVector<InventedTemplateParameterInfo, 4> InventedParameterInfos;
+ /// The index of the first InventedParameterInfo that refers to the current
+ /// context.
+ unsigned InventedParameterInfosStart = 0;
+
+ ArrayRef<InventedTemplateParameterInfo> getInventedParameterInfos() const {
+ return llvm::makeArrayRef(InventedParameterInfos.begin() +
+ InventedParameterInfosStart,
+ InventedParameterInfos.end());
+ }
+
typedef LazyVector<TypedefNameDecl *, ExternalSemaSource,
&ExternalSemaSource::ReadExtVectorDecls, 2, 2>
ExtVectorDeclsType;
@@ -800,17 +819,24 @@ public:
DeclContext *SavedContext;
ProcessingContextState SavedContextState;
QualType SavedCXXThisTypeOverride;
+ unsigned SavedFunctionScopesStart;
+ unsigned SavedInventedParameterInfosStart;
public:
ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true)
: S(S), SavedContext(S.CurContext),
SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
- SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
+ SavedCXXThisTypeOverride(S.CXXThisTypeOverride),
+ SavedFunctionScopesStart(S.FunctionScopesStart),
+ SavedInventedParameterInfosStart(S.InventedParameterInfosStart)
{
assert(ContextToPush && "pushing null context");
S.CurContext = ContextToPush;
if (NewThisContext)
S.CXXThisTypeOverride = QualType();
+ // Any saved FunctionScopes do not refer to this context.
+ S.FunctionScopesStart = S.FunctionScopes.size();
+ S.InventedParameterInfosStart = S.InventedParameterInfos.size();
}
void pop() {
@@ -818,6 +844,8 @@ public:
S.CurContext = SavedContext;
S.DelayedDiagnostics.popUndelayed(SavedContextState);
S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
+ S.FunctionScopesStart = SavedFunctionScopesStart;
+ S.InventedParameterInfosStart = SavedInventedParameterInfosStart;
SavedContext = nullptr;
}
@@ -4924,7 +4952,9 @@ public:
void ActOnStartStmtExpr();
ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt,
- SourceLocation RPLoc); // "({..})"
+ SourceLocation RPLoc);
+ ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
+ SourceLocation RPLoc, unsigned TemplateDepth);
// Handle the final expression in a statement expression.
ExprResult ActOnStmtExprResult(ExprResult E);
void ActOnStmtExprError();
@@ -11924,6 +11954,13 @@ public:
return DC;
}
+ /// Determine the number of levels of enclosing template parameters. This is
+ /// only usable while parsing. Note that this does not include dependent
+ /// contexts in which no template parameters have yet been declared, such as
+ /// in a terse function template or generic lambda before the first 'auto' is
+ /// encountered.
+ unsigned getTemplateDepth(Scope *S) const;
+
/// To be used for checking whether the arguments being passed to
/// function exceeds the number of parameters expected for it.
static bool TooManyArguments(size_t NumParams, size_t NumArgs,
diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 4c1cfecd4de6..47d6143bdc9a 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -95,6 +95,16 @@ class VarDecl;
return TemplateArgumentLists.size();
}
+ /// Determine how many of the \p OldDepth outermost template parameter
+ /// lists would be removed by substituting these arguments.
+ unsigned getNewDepth(unsigned OldDepth) const {
+ if (OldDepth < NumRetainedOuterLevels)
+ return OldDepth;
+ if (OldDepth < getNumLevels())
+ return NumRetainedOuterLevels;
+ return OldDepth - TemplateArgumentLists.size();
+ }
+
/// Retrieve the template argument at a given depth and index.
const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index f42361500a91..ab4e961dcd4c 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -6726,7 +6726,7 @@ ExpectedStmt ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
return new (Importer.getToContext())
StmtExpr(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc,
- E->isInstantiationDependent());
+ E->getTemplateDepth());
}
ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index a8cd18b123b0..57a95815488e 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -42,6 +42,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Timer.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -1038,6 +1039,8 @@ struct PragmaDebugHandler : public PragmaHandler {
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
llvm_unreachable("This is an assertion!");
} else if (II->isStr("crash")) {
+ llvm::Timer T("crash", "pragma crash");
+ llvm::TimeRegion R(&T);
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
LLVM_BUILTIN_TRAP;
} else if (II->isStr("parser_crash")) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 63d8d7506d03..04a7038d6754 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13909,7 +13909,12 @@ void Sema::ActOnStmtExprError() {
}
ExprResult Sema::ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt,
- SourceLocation RPLoc) { // "({..})"
+ SourceLocation RPLoc) {
+ return BuildStmtExpr(LPLoc, SubStmt, RPLoc, getTemplateDepth(S));
+}
+
+ExprResult Sema::BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
+ SourceLocation RPLoc, unsigned TemplateDepth) {
assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
@@ -13938,18 +13943,10 @@ ExprResult Sema::ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt,
}
}
- bool IsDependentContext = false;
- if (S)
- IsDependentContext = S->getTemplateParamParent() != nullptr;
- else
- // FIXME: This is not correct when substituting inside a templated
- // context that isn't a DeclContext (such as a variable template).
- IsDependentContext = CurContext->isDependentContext();
-
// FIXME: Check that expression type is complete/non-abstract; statement
// expressions are not lvalues.
Expr *ResStmtExpr =
- new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc, IsDependentContext);
+ new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc, TemplateDepth);
if (StmtExprMayBindToTemp)
return MaybeBindToTemporary(ResStmtExpr);
return ResStmtExpr;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 705abdb4ce72..e97171b6334e 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6802,7 +6802,7 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
Context, SubStmt, SourceLocation(), SourceLocation());
Expr *E = new (Context)
StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(),
- CurContext->isDependentContext());
+ /*FIXME TemplateDepth=*/0);
return MaybeCreateExprWithCleanups(E);
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ad4ea2d2593d..4f577a3cf748 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -46,6 +46,48 @@ clang::getTemplateParamsRange(TemplateParameterList const * const *Ps,
return SourceRange(Ps[0]->getTemplateLoc(), Ps[N-1]->getRAngleLoc());
}
+unsigned Sema::getTemplateDepth(Scope *S) const {
+ unsigned Depth = 0;
+
+ // Each template parameter scope represents one level of template parameter
+ // depth.
+ for (Scope *TempParamScope = S->getTemplateParamParent();
+ TempParamScope && !Depth;
+ TempParamScope = TempParamScope->getParent()->getTemplateParamParent()) {
+ ++Depth;
+ }
+
+ // Note that there are template parameters with the given depth.
+ auto ParamsAtDepth = [&](unsigned D) { Depth = std::max(Depth, D + 1); };
+
+ // Look for parameters of an enclosing generic lambda. We don't create a
+ // template parameter scope for these.
+ for (FunctionScopeInfo *FSI : getFunctionScopes()) {
+ if (auto *LSI = dyn_cast<LambdaScopeInfo>(FSI)) {
+ if (!LSI->TemplateParams.empty()) {
+ ParamsAtDepth(LSI->AutoTemplateParameterDepth);
+ break;
+ }
+ if (LSI->GLTemplateParameterList) {
+ ParamsAtDepth(LSI->GLTemplateParameterList->getDepth());
+ break;
+ }
+ }
+ }
+
+ // Look for parameters of an enclosing terse function template. We don't
+ // create a template parameter scope for these either.
+ for (const InventedTemplateParameterInfo &Info :
+ getInventedParameterInfos()) {
+ if (!Info.TemplateParams.empty()) {
+ ParamsAtDepth(Info.AutoTemplateParameterDepth);
+ break;
+ }
+ }
+
+ return Depth;
+}
+
/// \brief Determine whether the declaration found is acceptable as the name
/// of a template and, if so, return that template declaration. Otherwise,
/// returns null.
@@ -2173,9 +2215,15 @@ private:
// constructor.
ExprResult NewDefArg;
if (OldParam->hasDefaultArg()) {
- NewDefArg = SemaRef.SubstExpr(OldParam->getDefaultArg(), Args);
- if (NewDefArg.isInvalid())
- return nullptr;
+ // We don't care what the value is (we won't use it); just create a
+ // placeholder to indicate there is a default argument.
+ QualType ParamTy = NewDI->getType();
+ NewDefArg = new (SemaRef.Context)
+ OpaqueValueExpr(OldParam->getDefaultArg()->getBeginLoc(),
+ ParamTy.getNonLValueExprType(SemaRef.Context),
+ ParamTy->isLValueReferenceType() ? VK_LValue :
+ ParamTy->isRValueReferenceType() ? VK_XValue :
+ VK_RValue);
}
ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 568f5404dc0b..b5d2ab1f31f2 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -922,6 +922,10 @@ namespace {
this->Entity = Entity;
}
+ unsigned TransformTemplateDepth(unsigned Depth) {
+ return TemplateArgs.getNewDepth(Depth);
+ }
+
bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
SourceRange PatternRange,
ArrayRef<UnexpandedParameterPack> Unexpanded,
@@ -2162,7 +2166,7 @@ namespace {
// The deduced type itself.
TemplateTypeParmDecl *VisitTemplateTypeParmType(
const TemplateTypeParmType *T) {
- if (!T->getDecl()->isImplicit())
+ if (!T->getDecl() || !T->getDecl()->isImplicit())
return nullptr;
return T->getDecl();
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 0892f966ac2e..805fe6684205 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -212,6 +212,14 @@ public:
return T.isNull();
}
+ /// Transform a template parameter depth level.
+ ///
+ /// During a transformation that transforms template parameters, this maps
+ /// an old template parameter depth to a new depth.
+ unsigned TransformTemplateDepth(unsigned Depth) {
+ return Depth;
+ }
+
/// Determine whether the given call argument should be dropped, e.g.,
/// because it is a default argument.
///
@@ -2527,8 +2535,9 @@ public:
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
- SourceLocation RParenLoc) {
- return getSema().ActOnStmtExpr(nullptr, LParenLoc, SubStmt, RParenLoc);
+ SourceLocation RParenLoc, unsigned TemplateDepth) {
+ return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
+ TemplateDepth);
}
/// Build a new __builtin_choose_expr expression.
@@ -10345,16 +10354,18 @@ TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
return ExprError();
}
- if (!getDerived().AlwaysRebuild() &&
+ unsigned OldDepth = E->getTemplateDepth();
+ unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
+
+ if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
SubStmt.get() == E->getSubStmt()) {
// Calling this an 'error' is unintuitive, but it does the right thing.
SemaRef.ActOnStmtExprError();
return SemaRef.MaybeBindToTemporary(E);
}
- return getDerived().RebuildStmtExpr(E->getLParenLoc(),
- SubStmt.get(),
- E->getRParenLoc());
+ return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
+ E->getRParenLoc(), NewDepth);
}
template<typename Derived>
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index b7000a6956d9..e3eea3c6f860 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2867,7 +2867,8 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) {
return LocalOffset + M.GlobalBitOffset;
}
-static bool isSameTemplateParameterList(const TemplateParameterList *X,
+static bool isSameTemplateParameterList(const ASTContext &C,
+ const TemplateParameterList *X,
const TemplateParameterList *Y);
/// Determine whether two template parameters are similar enough
@@ -2879,7 +2880,32 @@ static bool isSameTemplateParameter(const NamedDecl *X,
if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) {
const auto *TY = cast<TemplateTypeParmDecl>(Y);
- return TX->isParameterPack() == TY->isParameterPack();
+ if (TX->isParameterPack() != TY->isParameterPack())
+ return false;
+ if (TX->hasTypeConstraint() != TY->hasTypeConstraint())
+ return false;
+ if (TX->hasTypeConstraint()) {
+ const TypeConstraint *TXTC = TX->getTypeConstraint();
+ const TypeConstraint *TYTC = TY->getTypeConstraint();
+ if (TXTC->getNamedConcept() != TYTC->getNamedConcept())
+ return false;
+ if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs())
+ return false;
+ if (TXTC->hasExplicitTemplateArgs()) {
+ const auto *TXTCArgs = TXTC->getTemplateArgsAsWritten();
+ const auto *TYTCArgs = TYTC->getTemplateArgsAsWritten();
+ if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs)
+ return false;
+ llvm::FoldingSetNodeID XID, YID;
+ for (const auto &ArgLoc : TXTCArgs->arguments())
+ ArgLoc.getArgument().Profile(XID, X->getASTContext());
+ for (const auto &ArgLoc : TYTCArgs->arguments())
+ ArgLoc.getArgument().Profile(YID, Y->getASTContext());
+ if (XID != YID)
+ return false;
+ }
+ }
+ return true;
}
if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) {
@@ -2891,7 +2917,8 @@ static bool isSameTemplateParameter(const NamedDecl *X,
const auto *TX = cast<TemplateTemplateParmDecl>(X);
const auto *TY = cast<TemplateTemplateParmDecl>(Y);
return TX->isParameterPack() == TY->isParameterPack() &&
- isSameTemplateParameterList(TX->getTemplateParameters(),
+ isSameTemplateParameterList(TX->getASTContext(),
+ TX->getTemplateParameters(),
TY->getTemplateParameters());
}
@@ -2944,7 +2971,8 @@ static bool isSameQualifier(const NestedNameSpecifier *X,
/// Determine whether two template parameter lists are similar enough
/// that they may be used in declarations of the same template.
-static bool isSameTemplateParameterList(const TemplateParameterList *X,
+static bool isSameTemplateParameterList(const ASTContext &C,
+ const TemplateParameterList *X,
const TemplateParameterList *Y) {
if (X->size() != Y->size())
return false;
@@ -2953,6 +2981,18 @@ static bool isSameTemplateParameterList(const TemplateParameterList *X,
if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I)))
return false;
+ const Expr *XRC = X->getRequiresClause();
+ const Expr *YRC = Y->getRequiresClause();
+ if (!XRC != !YRC)
+ return false;
+ if (XRC) {
+ llvm::FoldingSetNodeID XRCID, YRCID;
+ XRC->Profile(XRCID, C, /*Canonical=*/true);
+ YRC->Profile(YRCID, C, /*Canonical=*/true);
+ if (XRCID != YRCID)
+ return false;
+ }
+
return true;
}
@@ -2989,7 +3029,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A,
return true;
}
-/// Determine whether the two declarations refer to the same entity.
+/// Determine whether the two declarations refer to the same entity.pr
static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
@@ -3064,6 +3104,19 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
}
ASTContext &C = FuncX->getASTContext();
+
+ const Expr *XRC = FuncX->getTrailingRequiresClause();
+ const Expr *YRC = FuncY->getTrailingRequiresClause();
+ if (!XRC != !YRC)
+ return false;
+ if (XRC) {
+ llvm::FoldingSetNodeID XRCID, YRCID;
+ XRC->Profile(XRCID, C, /*Canonical=*/true);
+ YRC->Profile(YRCID, C, /*Canonical=*/true);
+ if (XRCID != YRCID)
+ return false;
+ }
+
auto GetTypeAsWritten = [](const FunctionDecl *FD) {
// Map to the first declaration that we've already merged into this one.
// The TSI of redeclarations might not match (due to calling conventions
@@ -3087,6 +3140,7 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
return true;
return false;
}
+
return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() &&
hasSameOverloadableAttrs(FuncX, FuncY);
}
@@ -3126,7 +3180,8 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
const auto *TemplateY = cast<TemplateDecl>(Y);
return isSameEntity(TemplateX->getTemplatedDecl(),
TemplateY->getTemplatedDecl()) &&
- isSameTemplateParameterList(TemplateX->getTemplateParameters(),
+ isSameTemplateParameterList(TemplateX->getASTContext(),
+ TemplateX->getTemplateParameters(),
TemplateY->getTemplateParameters());
}
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 5dd0ef9d43c3..c38b3ad18467 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -754,6 +754,7 @@ void ASTStmtReader::VisitConceptSpecializationExpr(
E->TemplateKWLoc = Record.readSourceLocation();
E->ConceptName = Record.readDeclarationNameInfo();
E->NamedConcept = readDeclAs<ConceptDecl>();
+ E->FoundDecl = Record.readDeclAs<NamedDecl>();
E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
llvm::SmallVector<TemplateArgument, 4> Args;
for (unsigned I = 0; I < NumTemplateArgs; ++I)
@@ -1190,6 +1191,7 @@ void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
E->setLParenLoc(readSourceLocation());
E->setRParenLoc(readSourceLocation());
E->setSubStmt(cast_or_null<CompoundStmt>(Record.readSubStmt()));
+ E->StmtExprBits.TemplateDepth = Record.readInt();
}
void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) {
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 1b118c257a4c..8519a4df019d 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -429,6 +429,7 @@ void ASTStmtWriter::VisitConceptSpecializationExpr(
Record.AddSourceLocation(E->getTemplateKWLoc());
Record.AddDeclarationNameInfo(E->getConceptNameInfo());
Record.AddDeclRef(E->getNamedConcept());
+ Record.AddDeclRef(E->getFoundDecl());
Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
for (const TemplateArgument &Arg : TemplateArgs)
Record.AddTemplateArgument(Arg);
@@ -1068,6 +1069,7 @@ void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
Record.AddStmt(E->getSubStmt());
Record.AddSourceLocation(E->getLParenLoc());
Record.AddSourceLocation(E->getRParenLoc());
+ Record.push_back(E->getTemplateDepth());
Code = serialization::EXPR_STMT;
}
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 4457e40ff04b..7b3968341cc7 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -30,6 +30,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/ErrorHandling.h"
@@ -491,6 +492,7 @@ int main(int argc_, const char **argv_) {
std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 1;
+ bool IsCrash = false;
if (C && !C->containsError()) {
SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
@@ -517,11 +519,11 @@ int main(int argc_, const char **argv_) {
// If result status is 70, then the driver command reported a fatal error.
// On Windows, abort will return an exit code of 3. In these cases,
// generate additional diagnostic information if possible.
- bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
+ IsCrash = CommandRes < 0 || CommandRes == 70;
#ifdef _WIN32
- DiagnoseCrash |= CommandRes == 3;
+ IsCrash |= CommandRes == 3;
#endif
- if (DiagnoseCrash) {
+ if (IsCrash) {
TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
break;
}
@@ -530,10 +532,16 @@ int main(int argc_, const char **argv_) {
Diags.getClient()->finish();
- // If any timers were active but haven't been destroyed yet, print their
- // results now. This happens in -disable-free mode.
- llvm::TimerGroup::printAll(llvm::errs());
- llvm::TimerGroup::clearAll();
+ if (!UseNewCC1Process && IsCrash) {
+ // When crashing in -fintegrated-cc1 mode, bury the timer pointers, because
+ // the internal linked list might point to already released stack frames.
+ llvm::BuryPointer(llvm::TimerGroup::aquireDefaultGroup());
+ } else {
+ // If any timers were active but haven't been destroyed yet, print their
+ // results now. This happens in -disable-free mode.
+ llvm::TimerGroup::printAll(llvm::errs());
+ llvm::TimerGroup::clearAll();
+ }
#ifdef _WIN32
// Exit status should not be negative on Win32, unless abnormal termination.
diff --git a/llvm/include/llvm/Support/ManagedStatic.h b/llvm/include/llvm/Support/ManagedStatic.h
index e65bb051f181..bbd0d04ed040 100644
--- a/llvm/include/llvm/Support/ManagedStatic.h
+++ b/llvm/include/llvm/Support/ManagedStatic.h
@@ -102,6 +102,12 @@ public:
}
const C *operator->() const { return &**this; }
+
+ // Extract the instance, leaving the ManagedStatic uninitialized. The
+ // user is then responsible for the lifetime of the returned instance.
+ C *claim() {
+ return static_cast<C *>(Ptr.exchange(nullptr));
+ }
};
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
diff --git a/llvm/include/llvm/Support/Timer.h b/llvm/include/llvm/Support/Timer.h
index a298ecd90404..045ac448bdb4 100644
--- a/llvm/include/llvm/Support/Timer.h
+++ b/llvm/include/llvm/Support/Timer.h
@@ -230,6 +230,11 @@ public:
/// used by the Statistic code to influence the construction and destruction
/// order of the global timer lists.
static void ConstructTimerLists();
+
+ /// This makes the default group unmanaged, and lets the user manage the
+ /// group's lifetime.
+ static std::unique_ptr<TimerGroup> aquireDefaultGroup();
+
private:
friend class Timer;
friend void PrintStatisticsJSON(raw_ostream &OS);
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index 613d2eaae6d3..2d3d00812826 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -441,3 +441,7 @@ const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
void TimerGroup::ConstructTimerLists() {
(void)*NamedGroupedTimers;
}
+
+std::unique_ptr<TimerGroup> TimerGroup::aquireDefaultGroup() {
+ return std::unique_ptr<TimerGroup>(DefaultTimerGroup.claim());
+}