r267975 - [Parser] Clear the TemplateParamScope bit of the current scope's flag

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 28 19:24:15 PDT 2016


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>




More information about the cfe-commits mailing list