ahatanak updated this revision to Diff 55484.
ahatanak added a comment.

- Defined a private overload of Scope::setFlags which is called from 
Scope::setFlags and Scope::Init.
- Stop checking TmplScope->isTemplateParamScope() in 
Sema::ActOnStartOfLambdaDefinition.
- Fix test case test/CXX/drs/dr1xx.cpp to check an error message (not a 
warning) is printed when it's compiled with -std=c++98.


http://reviews.llvm.org/D19175

Files:
  include/clang/Sema/Scope.h
  lib/Parse/ParseTemplate.cpp
  lib/Sema/Scope.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/CXX/drs/dr1xx.cpp
  test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
  test/SemaCXX/vartemplate-lambda.cpp

Index: test/SemaCXX/vartemplate-lambda.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/vartemplate-lambda.cpp
@@ -0,0 +1,18 @@
+// 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>
+int foo2() {
+  X a = 0x61;
+  fn1<char>(a);
+  return 0;
+}
+
+int main() {
+  foo2<int>();
+}
Index: test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
===================================================================
--- test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
+++ test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -195,7 +195,7 @@
 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
Index: test/CXX/drs/dr1xx.cpp
===================================================================
--- test/CXX/drs/dr1xx.cpp
+++ test/CXX/drs/dr1xx.cpp
@@ -902,7 +902,11 @@
     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
   };
 }
 
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3907,9 +3907,14 @@
       PushExpressionEvaluationContext(Sema::PotentiallyEvaluated, OldVar);
 
     // Instantiate the initializer.
-    ExprResult Init =
-        SubstInitializer(OldVar->getInit(), TemplateArgs,
-                         OldVar->getInitStyle() == VarDecl::CallInit);
+    ExprResult Init;
+
+    {
+      ContextRAII SwitchContext(*this, Var->getDeclContext());
+      Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
+                              OldVar->getInitStyle() == VarDecl::CallInit);
+    }
+
     if (!Init.isInvalid()) {
       bool TypeMayContainAuto = true;
       Expr *InitExpr = Init.get();
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -814,9 +814,8 @@
   // 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;
Index: lib/Sema/Scope.cpp
===================================================================
--- lib/Sema/Scope.cpp
+++ lib/Sema/Scope.cpp
@@ -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 @@
     else
       incrementMSManglingNumber();
   }
+}
+
+void Scope::Init(Scope *parent, unsigned flags) {
+  setFlags(parent, flags);
 
   DeclsInScope.clear();
   UsingDirectives.clear();
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -147,6 +147,9 @@
     }
   } 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,
Index: include/clang/Sema/Scope.h
===================================================================
--- include/clang/Sema/Scope.h
+++ include/clang/Sema/Scope.h
@@ -197,6 +197,8 @@
   /// 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 @@
   /// 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; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to