Skip to content

Commit

Permalink
Revert "Re-apply "Deferred Concept Instantiation Implementation"""
Browse files Browse the repository at this point in the history
This reverts commit befa8cf.

Apparently this breaks some libc++ builds with an apparent assertion,
 so I'm looking into that .
  • Loading branch information
Erich Keane committed Jul 1, 2022
1 parent 188582b commit 258c3ae
Show file tree
Hide file tree
Showing 26 changed files with 217 additions and 1,574 deletions.
9 changes: 4 additions & 5 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,10 @@ C++20 Feature Support
- No longer attempt to evaluate a consteval UDL function call at runtime when
it is called through a template instantiation. This fixes
`Issue 54578 <https://github.com/llvm/llvm-project/issues/54578>`_.
- Implemented `__builtin_source_location()` which enables library support for std::source_location.
- Clang now correctly delays the instantiation of function constraints until
the time of checking, which should now allow the libstdc++ ranges implementation
to work for at least trivial examples. This fixes
`Issue 44178 <https://github.com/llvm/llvm-project/issues/44178>`_.

- Implemented ``__builtin_source_location()``, which enables library support
for ``std::source_location``.

- The mangling scheme for C++20 modules has incompatibly changed. The
initial mangling was discovered not to be reversible, and the weak
ownership design decision did not give the backwards compatibility
Expand Down
36 changes: 13 additions & 23 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1890,9 +1890,7 @@ class FunctionDecl : public DeclaratorDecl,
TK_FunctionTemplateSpecialization,
// A function template specialization that hasn't yet been resolved to a
// particular specialized function template.
TK_DependentFunctionTemplateSpecialization,
// A non templated function which is in a dependent scope.
TK_DependentNonTemplate
TK_DependentFunctionTemplateSpecialization
};

/// Stashed information about a defaulted function definition whose body has
Expand Down Expand Up @@ -1941,21 +1939,20 @@ class FunctionDecl : public DeclaratorDecl,
/// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
/// For non-templates this value will be NULL, unless this non-template
/// function declaration was declared directly inside of a function template,
/// in which case this will have a pointer to a FunctionDecl, stored in the
/// NamedDecl. For function declarations that describe a function template,
/// this will be a pointer to a FunctionTemplateDecl, stored in the NamedDecl.
/// For member functions of class template specializations, this will be a
/// MemberSpecializationInfo pointer containing information about the
/// specialization. For function template specializations, this will be a
/// FunctionTemplateSpecializationInfo, which contains information about the
/// template being specialized and the template arguments involved in that
/// specialization.
llvm::PointerUnion<NamedDecl *, MemberSpecializationInfo *,
/// For non-templates, this value will be NULL. For function
/// declarations that describe a function template, this will be a
/// pointer to a FunctionTemplateDecl. For member functions
/// of class template specializations, this will be a MemberSpecializationInfo
/// pointer containing information about the specialization.
/// For function template specializations, this will be a
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
llvm::PointerUnion<FunctionTemplateDecl *,
MemberSpecializationInfo *,
FunctionTemplateSpecializationInfo *,
DependentFunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
TemplateOrSpecialization;

/// Provides source/type location info for the declaration name embedded in
/// the DeclaratorDecl base class.
Expand Down Expand Up @@ -2698,11 +2695,6 @@ class FunctionDecl : public DeclaratorDecl,
setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
}

/// Specify that this function declaration was instantiated from FunctionDecl
/// FD. This is only used if this is a function declaration declared locally
/// inside of a function template.
void setInstantiatedFromDecl(FunctionDecl *FD);

/// Retrieves the function template that is described by this
/// function declaration.
///
Expand All @@ -2717,8 +2709,6 @@ class FunctionDecl : public DeclaratorDecl,
/// FunctionTemplateDecl from a FunctionDecl.
FunctionTemplateDecl *getDescribedFunctionTemplate() const;

FunctionDecl *getInstantiatedFromDecl() const;

void setDescribedFunctionTemplate(FunctionTemplateDecl *Template);

/// Determine whether this function is a function template
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,10 +920,10 @@ class alignas(8) Decl {

/// If this decl is defined inside a function/method/block it returns
/// the corresponding DeclContext, otherwise it returns null.
const DeclContext *getParentFunctionOrMethod(bool Lexical = false) const;
DeclContext *getParentFunctionOrMethod(bool Lexical = false) {
return const_cast<DeclContext *>(
const_cast<const Decl *>(this)->getParentFunctionOrMethod(Lexical));
const DeclContext *getParentFunctionOrMethod() const;
DeclContext *getParentFunctionOrMethod() {
return const_cast<DeclContext*>(
const_cast<const Decl*>(this)->getParentFunctionOrMethod());
}

/// Retrieves the "canonical" declaration of the given declaration.
Expand Down
85 changes: 11 additions & 74 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -3622,11 +3622,6 @@ class Sema final {
bool ConsiderCudaAttrs = true,
bool ConsiderRequiresClauses = true);

// Calculates whether the expression Constraint depends on an enclosing
// template, for the purposes of [temp.friend] p9.
bool ConstraintExpressionDependsOnEnclosingTemplate(unsigned TemplateDepth,
const Expr *Constraint);

enum class AllowedExplicit {
/// Allow no explicit functions to be used.
None,
Expand Down Expand Up @@ -7096,21 +7091,6 @@ class Sema final {
LocalInstantiationScope &Scope,
const MultiLevelTemplateArgumentList &TemplateArgs);

/// used by SetupConstraintCheckingTemplateArgumentsAndScope to recursively(in
/// the case of lambdas) set up the LocalInstantiationScope of the current
/// function.
bool SetupConstraintScope(
FunctionDecl *FD, llvm::Optional<ArrayRef<TemplateArgument>> TemplateArgs,
MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope);

/// Used during constraint checking, sets up the constraint template arguemnt
/// lists, and calls SetupConstraintScope to set up the
/// LocalInstantiationScope to have the proper set of ParVarDecls configured.
llvm::Optional<MultiLevelTemplateArgumentList>
SetupConstraintCheckingTemplateArgumentsAndScope(
FunctionDecl *FD, llvm::Optional<ArrayRef<TemplateArgument>> TemplateArgs,
LocalInstantiationScope &Scope);

public:
const NormalizedConstraint *
getNormalizedAssociatedConstraints(
Expand Down Expand Up @@ -7141,10 +7121,8 @@ class Sema final {
/// check (either a concept or a constrained entity).
/// \param ConstraintExprs a list of constraint expressions, treated as if
/// they were 'AND'ed together.
/// \param TemplateArgList the multi-level list of template arguments to
/// substitute into the constraint expression. This should be relative to the
/// top-level (hence multi-level), since we need to instantiate fully at the
/// time of checking.
/// \param TemplateArgs the list of template arguments to substitute into the
/// constraint expression.
/// \param TemplateIDRange The source range of the template id that
/// caused the constraints check.
/// \param Satisfaction if true is returned, will contain details of the
Expand All @@ -7154,40 +7132,7 @@ class Sema final {
/// false otherwise.
bool CheckConstraintSatisfaction(
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
const MultiLevelTemplateArgumentList &TemplateArgList,
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
llvm::SmallVector<Expr *, 4> Converted;
return CheckConstraintSatisfaction(Template, ConstraintExprs, Converted,
TemplateArgList, TemplateIDRange,
Satisfaction);
}

/// \brief Check whether the given list of constraint expressions are
/// satisfied (as if in a 'conjunction') given template arguments.
/// Additionally, takes an empty list of Expressions which is populated with
/// the instantiated versions of the ConstraintExprs.
/// \param Template the template-like entity that triggered the constraints
/// check (either a concept or a constrained entity).
/// \param ConstraintExprs a list of constraint expressions, treated as if
/// they were 'AND'ed together.
/// \param ConvertedConstraints a out parameter that will get populated with
/// the instantiated version of the ConstraintExprs if we successfully checked
/// satisfaction.
/// \param TemplateArgList the multi-level list of template arguments to
/// substitute into the constraint expression. This should be relative to the
/// top-level (hence multi-level), since we need to instantiate fully at the
/// time of checking.
/// \param TemplateIDRange The source range of the template id that
/// caused the constraints check.
/// \param Satisfaction if true is returned, will contain details of the
/// satisfaction, with enough information to diagnose an unsatisfied
/// expression.
/// \returns true if an error occurred and satisfaction could not be checked,
/// false otherwise.
bool CheckConstraintSatisfaction(
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
const MultiLevelTemplateArgumentList &TemplateArgList,
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);

/// \brief Check whether the given non-dependent constraint expression is
Expand Down Expand Up @@ -7223,9 +7168,9 @@ class Sema final {
///
/// \returns true if the constrains are not satisfied or could not be checked
/// for satisfaction, false if the constraints are satisfied.
bool EnsureTemplateArgumentListConstraints(
TemplateDecl *Template, MultiLevelTemplateArgumentList TemplateArgs,
SourceRange TemplateIDRange);
bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template,
ArrayRef<TemplateArgument> TemplateArgs,
SourceRange TemplateIDRange);

/// \brief Emit diagnostics explaining why a constraint expression was deemed
/// unsatisfied.
Expand Down Expand Up @@ -8959,8 +8904,7 @@ class Sema final {

MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
const NamedDecl *D, const TemplateArgumentList *Innermost = nullptr,
bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
bool LookBeyondLambda = false, bool IncludeContainingStruct = false);
bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr);

/// A context in which code is being synthesized (where a source location
/// alone is not sufficient to identify the context). This covers template
Expand Down Expand Up @@ -9693,11 +9637,6 @@ class Sema final {
ExtParameterInfoBuilder &ParamInfos);
ExprResult SubstExpr(Expr *E,
const MultiLevelTemplateArgumentList &TemplateArgs);
// Unlike the above, this evaluates constraints, which should only happen at
// 'constraint checking' time.
ExprResult
SubstConstraintExpr(Expr *E,
const MultiLevelTemplateArgumentList &TemplateArgs);

/// Substitute the given template arguments into a list of
/// expressions, expanding pack expansions if required.
Expand All @@ -9721,14 +9660,13 @@ class Sema final {

TemplateParameterList *
SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs,
bool InstantiateConstraints = false);
const MultiLevelTemplateArgumentList &TemplateArgs);

bool
SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateArgumentListInfo &Outputs,
bool InstantiateConstraints = false);
TemplateArgumentListInfo &Outputs);


Decl *SubstDecl(Decl *D, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs);
Expand Down Expand Up @@ -9820,8 +9758,7 @@ class Sema final {
const MultiLevelTemplateArgumentList &TemplateArgs);

bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
const MultiLevelTemplateArgumentList &TemplateArgs,
bool isEvaluatingAConstraint);
const MultiLevelTemplateArgumentList &TemplateArgs);

bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
ParmVarDecl *Param);
Expand Down
41 changes: 2 additions & 39 deletions clang/include/clang/Sema/Template.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ enum class TemplateSubstitutionKind : char {
class MultiLevelTemplateArgumentList {
/// The template argument list at a certain template depth
using ArgList = ArrayRef<TemplateArgument>;
using ArgListsIterator = SmallVector<ArgList, 4>::iterator;
using ConstArgListsIterator = SmallVector<ArgList, 4>::const_iterator;

/// The template argument lists, stored from the innermost template
/// argument list (first) to the outermost template argument list (last).
Expand Down Expand Up @@ -123,12 +121,6 @@ enum class TemplateSubstitutionKind : char {
return TemplateArgumentLists.size();
}

/// Determine the number of substituted args at 'Depth'.
unsigned getNumSubstitutedArgs(unsigned Depth) const {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
return TemplateArgumentLists[getNumLevels() - Depth - 1].size();
}

unsigned getNumRetainedOuterLevels() const {
return NumRetainedOuterLevels;
}
Expand Down Expand Up @@ -166,14 +158,6 @@ enum class TemplateSubstitutionKind : char {
return !(*this)(Depth, Index).isNull();
}

bool isAnyArgInstantiationDependent() const {
for (ArgList List : TemplateArgumentLists)
for (const TemplateArgument &TA : List)
if (TA.isInstantiationDependent())
return true;
return false;
}

/// Clear out a specific template argument.
void setArgument(unsigned Depth, unsigned Index,
TemplateArgument Arg) {
Expand All @@ -199,14 +183,6 @@ enum class TemplateSubstitutionKind : char {
TemplateArgumentLists.push_back(Args);
}

/// Replaces the current 'innermost' level with the provided argument list.
/// This is useful for type deduction cases where we need to get the entire
/// list from the AST, but then add the deduced innermost list.
void replaceInnermostTemplateArguments(ArgList Args) {
assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?");
TemplateArgumentLists[0] = Args;
}

/// Add an outermost level that we are not substituting. We have no
/// arguments at this level, and do not remove it from the depth of inner
/// template parameters that we instantiate.
Expand All @@ -221,16 +197,6 @@ enum class TemplateSubstitutionKind : char {
const ArgList &getInnermost() const {
return TemplateArgumentLists.front();
}

/// Retrieve the outermost template argument list.
const ArgList &getOutermost() const { return TemplateArgumentLists.back(); }

ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
ConstArgListsIterator begin() const {
return TemplateArgumentLists.begin();
}
ArgListsIterator end() { return TemplateArgumentLists.end(); }
ConstArgListsIterator end() const { return TemplateArgumentLists.end(); }
};

/// The context in which partial ordering of function templates occurs.
Expand Down Expand Up @@ -503,7 +469,6 @@ enum class TemplateSubstitutionKind : char {
const MultiLevelTemplateArgumentList &TemplateArgs;
Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
LocalInstantiationScope *StartingScope = nullptr;
bool EvaluatingAConstraint = false;

/// A list of out-of-line class template partial
/// specializations that will need to be instantiated after the
Expand All @@ -522,12 +487,10 @@ enum class TemplateSubstitutionKind : char {

public:
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs,
bool EvaluatingConstraint = false)
const MultiLevelTemplateArgumentList &TemplateArgs)
: SemaRef(SemaRef),
SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
Owner(Owner), TemplateArgs(TemplateArgs),
EvaluatingAConstraint(EvaluatingConstraint) {}
Owner(Owner), TemplateArgs(TemplateArgs) {}

// Define all the decl visitors using DeclNodes.inc
#define DECL(DERIVED, BASE) \
Expand Down
5 changes: 0 additions & 5 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3109,11 +3109,6 @@ Error ASTNodeImporter::ImportTemplateInformation(
case FunctionDecl::TK_FunctionTemplate:
return Error::success();

case FunctionDecl::TK_DependentNonTemplate:
if (Expected<FunctionDecl *> InstFDOrErr =
import(FromFD->getInstantiatedFromDecl()))
ToFD->setInstantiatedFromDecl(*InstFDOrErr);
return Error::success();
case FunctionDecl::TK_MemberSpecialization: {
TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind();

Expand Down
23 changes: 3 additions & 20 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3732,12 +3732,8 @@ const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
if (TemplateOrSpecialization.isNull())
return TK_NonTemplate;
if (auto *ND = TemplateOrSpecialization.dyn_cast<NamedDecl *>()) {
if (isa<FunctionDecl>(ND))
return TK_DependentNonTemplate;
assert(isa<FunctionTemplateDecl>(ND) && "No other types it could be?");
if (TemplateOrSpecialization.is<FunctionTemplateDecl *>())
return TK_FunctionTemplate;
}
if (TemplateOrSpecialization.is<MemberSpecializationInfo *>())
return TK_MemberSpecialization;
if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>())
Expand Down Expand Up @@ -3778,28 +3774,15 @@ FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
}

FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const {
return dyn_cast_or_null<FunctionTemplateDecl>(
TemplateOrSpecialization.dyn_cast<NamedDecl *>());
return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl *>();
}

void FunctionDecl::setDescribedFunctionTemplate(
FunctionTemplateDecl *Template) {
void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
assert(TemplateOrSpecialization.isNull() &&
"Member function is already a specialization");
TemplateOrSpecialization = Template;
}

void FunctionDecl::setInstantiatedFromDecl(FunctionDecl *FD) {
assert(TemplateOrSpecialization.isNull() &&
"function is already a specialization");
TemplateOrSpecialization = FD;
}

FunctionDecl *FunctionDecl::getInstantiatedFromDecl() const {
return dyn_cast_or_null<FunctionDecl>(
TemplateOrSpecialization.dyn_cast<NamedDecl *>());
}

bool FunctionDecl::isImplicitlyInstantiable() const {
// If the function is invalid, it can't be implicitly instantiated.
if (isInvalidDecl())
Expand Down
Loading

0 comments on commit 258c3ae

Please sign in to comment.