if we are parsing a template specialization.
This commit makes changes to clear the TemplateParamScope bit and set
the TemplateParamParent field of the current scope to null if a template
specialization is being parsed.
Before this commit, Sema::ActOnStartOfLambdaDefinition would check
whether the parent template scope had any decls to determine whether
or not a template specialization was being parsed. This wasn't correct
since it couldn't distinguish between a real template specialization and
a template defintion with an unnamed template parameter (only template
parameters with names are added to the scope's decl list). To fix the
bug, this commit changes the code to check the pointer to the parent
template scope rather than the decl list.
rdar://problem/
23440346
Differential Revision: http://reviews.llvm.org/D19175
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@267975
91177308-0d34-0410-b5e6-
96231b3b80d8
/// this scope, or over-defined. The bit is true when over-defined.
llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
+ void setFlags(Scope *Parent, unsigned F);
+
public:
Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
: ErrorTrap(Diag) {
/// getFlags - Return the flags for this scope.
///
unsigned getFlags() const { return Flags; }
- void setFlags(unsigned F) { Flags = F; }
+ void setFlags(unsigned F) { setFlags(getParent(), F); }
/// isBlockScope - Return true if this scope correspond to a closure.
bool isBlockScope() const { return Flags & BlockScope; }
}
} while (Tok.isOneOf(tok::kw_export, tok::kw_template));
+ unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope;
+ ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);
+
// Parse the actual template declaration.
return ParseSingleDeclarationAfterTemplate(Context,
ParsedTemplateInfo(&ParamLists,
using namespace clang;
-void Scope::Init(Scope *parent, unsigned flags) {
+void Scope::setFlags(Scope *parent, unsigned flags) {
AnyParent = parent;
Flags = flags;
else
incrementMSManglingNumber();
}
+}
+
+void Scope::Init(Scope *parent, unsigned flags) {
+ setFlags(parent, flags);
DeclsInScope.clear();
UsingDirectives.clear();
// The lambda-expression's closure type might be dependent even if its
// semantic context isn't, if it appears within a default argument of a
// function template.
- if (Scope *TmplScope = CurScope->getTemplateParamParent())
- if (!TmplScope->decl_empty())
- KnownDependent = true;
+ if (CurScope->getTemplateParamParent())
+ KnownDependent = true;
// Determine the signature of the call operator.
TypeSourceInfo *MethodTyInfo;
typedef int X;
};
template<> struct A<int> {
+#if __cplusplus <= 199711
+ typename B<int>::X x; // expected-error {{'typename' occurs outside of a template}}
+#else
typename B<int>::X x;
+#endif
};
}
namespace default_args {
#ifdef CPP11ONLY
namespace lambdas {
-template<int I = ([] { return 5; }())> //expected-error 2{{constant expression}} expected-note{{constant expression}}
+template<int I = ([] { return 5; }())> //expected-error {{constant expression}}
int f();
}
#endif // CPP11ONLY
// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
// expected-no-diagnostics
+template <class> auto fn0 = [] {};
+template <typename> void foo0() { fn0<char>(); }
+
template<typename T> auto fn1 = [](auto a) { return a + T(1); };
template <typename X>