Author: ahatanak Date: Thu Apr 28 21:24:14 2016 New Revision: 267975 URL: http://llvm.org/viewvc/llvm-project?rev=267975&view=rev Log: [Parser] Clear the TemplateParamScope bit of the current scope's flag 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 Modified: cfe/trunk/include/clang/Sema/Scope.h cfe/trunk/lib/Parse/ParseTemplate.cpp cfe/trunk/lib/Sema/Scope.cpp cfe/trunk/lib/Sema/SemaLambda.cpp cfe/trunk/test/CXX/drs/dr1xx.cpp cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp Modified: cfe/trunk/include/clang/Sema/Scope.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Scope.h (original) +++ cfe/trunk/include/clang/Sema/Scope.h Thu Apr 28 21:24:14 2016 @@ -197,6 +197,8 @@ private: /// 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) { @@ -206,7 +208,7 @@ public: /// 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; } Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseTemplate.cpp (original) +++ cfe/trunk/lib/Parse/ParseTemplate.cpp Thu Apr 28 21:24:14 2016 @@ -147,6 +147,9 @@ Parser::ParseTemplateDeclarationOrSpecia } } 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, Modified: cfe/trunk/lib/Sema/Scope.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Scope.cpp?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Scope.cpp (original) +++ cfe/trunk/lib/Sema/Scope.cpp Thu Apr 28 21:24:14 2016 @@ -18,7 +18,7 @@ using namespace clang; -void Scope::Init(Scope *parent, unsigned flags) { +void Scope::setFlags(Scope *parent, unsigned flags) { AnyParent = parent; Flags = flags; @@ -83,6 +83,10 @@ void Scope::Init(Scope *parent, unsigned else incrementMSManglingNumber(); } +} + +void Scope::Init(Scope *parent, unsigned flags) { + setFlags(parent, flags); DeclsInScope.clear(); UsingDirectives.clear(); Modified: cfe/trunk/lib/Sema/SemaLambda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) +++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu Apr 28 21:24:14 2016 @@ -814,9 +814,8 @@ void Sema::ActOnStartOfLambdaDefinition( // 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; Modified: cfe/trunk/test/CXX/drs/dr1xx.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/test/CXX/drs/dr1xx.cpp (original) +++ cfe/trunk/test/CXX/drs/dr1xx.cpp Thu Apr 28 21:24:14 2016 @@ -902,7 +902,11 @@ namespace dr183 { // dr183: sup 382 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 }; } Modified: cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp (original) +++ cfe/trunk/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp Thu Apr 28 21:24:14 2016 @@ -195,7 +195,7 @@ namespace bad_args { 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 Modified: cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp?rev=267975&r1=267974&r2=267975&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp (original) +++ cfe/trunk/test/SemaCXX/vartemplate-lambda.cpp Thu Apr 28 21:24:14 2016 @@ -1,6 +1,9 @@ // 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> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits