[PATCH] D23096: [Sema] Pass CombineWithOuterScope = true to constructor of LocalInstantiationScope
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 10 16:06:42 PDT 2016
ahatanak updated this revision to Diff 67623.
ahatanak added a comment.
Handle the case in which the enum is declared inside a member function and add test cases.
The variable template test case still crashes. It looks like it crashes whenever the lambda expression takes a default argument:
template <class T> auto a = [](int f = 7) { return f; }();
auto foo1() {
return a<int>;
}
https://reviews.llvm.org/D23096
Files:
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateInstantiate.cpp
test/SemaTemplate/default-expr-arguments-3.cpp
Index: test/SemaTemplate/default-expr-arguments-3.cpp
===================================================================
--- /dev/null
+++ test/SemaTemplate/default-expr-arguments-3.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -std=c++14 -ast-dump %s 2>&1 | FileCheck %s
+
+namespace PR28795 {
+ // CHECK: FunctionDecl{{.*}}func 'void (void)'
+ // CHECK: LambdaExpr
+ // CHECK: CXXMethodDecl{{.*}}operator() 'enum foo (enum foo) const' inline
+ // CHECK: ParmVarDecl{{.*}}f 'enum foo' cinit
+ // CHECK: DeclRefExpr{{.*}}'enum foo' EnumConstant{{.*}}'a' 'enum foo'
+
+ template<typename T>
+ void func() {
+ enum class foo { a, b };
+ auto bar = [](foo f = foo::a) { return f; };
+ bar();
+ }
+
+ void foo() {
+ func<int>();
+ }
+}
+
+// Template struct case:
+
+// CHECK: ClassTemplateSpecializationDecl{{.*}}struct class2 definition
+// CHECK: LambdaExpr
+// CHECK: CXXMethodDecl{{.*}}used operator() 'enum foo (enum foo) const' inline
+// CHECK: ParmVarDecl{{.*}}f 'enum foo' cinit
+// CHECK: DeclRefExpr{{.*}}'enum foo' EnumConstant{{.*}}'a' 'enum foo'
+
+template <class T> struct class2 {
+ void bar() {
+ enum class foo { a, b };
+ [](foo f = foo::a) { return f; }();
+ }
+};
+
+template struct class2<int>;
+
+// CHECK: FunctionDecl{{.*}}f1 'void (void)'
+// CHECK: CXXMethodDecl{{.*}}g1 'int (enum foo)'
+// CHECK: ParmVarDecl{{.*}}n 'enum foo' cinit
+// CHECK: DeclRefExpr{{.*}}'enum foo' EnumConstant{{.*}}'a' 'enum foo'
+
+template<typename T>
+void f1() {
+ enum class foo { a, b };
+ struct S {
+ int g1(foo n = foo::a);
+ };
+}
+
+template void f1<int>();
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1670,7 +1670,7 @@
// Instantiate default arguments for methods of local classes (DR1484)
// and non-defining declarations.
Sema::ContextRAII SavedContext(*this, OwningFunc);
- LocalInstantiationScope Local(*this);
+ LocalInstantiationScope Local(*this, true);
ExprResult NewArg = SubstExpr(Arg, TemplateArgs);
if (NewArg.isUsable()) {
// It would be nice if we still had this.
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -429,7 +429,12 @@
bool MightBeCxx11UnevalField =
getLangOpts().CPlusPlus11 && isUnevaluatedContext();
- if (!MightBeCxx11UnevalField && !isAddressOfOperand &&
+ // Check if the nested name specifier is an enum type.
+ bool IsEnum = false;
+ if (NestedNameSpecifier *NNS = SS.getScopeRep())
+ IsEnum = dyn_cast_or_null<EnumType>(NNS->getAsType());
+
+ if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->isInstance()) {
QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23096.67623.patch
Type: text/x-patch
Size: 3007 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160810/0965a9a7/attachment.bin>
More information about the cfe-commits
mailing list