forked from OSchip/llvm-project
Internal-linkage variables with constant-evaluatable initializers do not need to be emitted. (Also reduces the set of variables that need to be eagerly deserialized when using PCH / modules.)
llvm-svn: 245497
This commit is contained in:
parent
39259ffc65
commit
7747ce2260
|
@ -8311,6 +8311,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
|
|||
// Global named register variables (GNU extension) are never emitted.
|
||||
if (VD->getStorageClass() == SC_Register)
|
||||
return false;
|
||||
if (VD->getDescribedVarTemplate() ||
|
||||
isa<VarTemplatePartialSpecializationDecl>(VD))
|
||||
return false;
|
||||
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// We never need to emit an uninstantiated function template.
|
||||
if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
|
||||
|
@ -8383,7 +8386,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
|
|||
return true;
|
||||
|
||||
// Variables that have initialization with side-effects are required.
|
||||
if (VD->getInit() && VD->getInit()->HasSideEffects(*this))
|
||||
if (VD->getInit() && VD->getInit()->HasSideEffects(*this) &&
|
||||
!VD->evaluateValue())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -5,6 +5,7 @@ void syslog(const char *, ...);
|
|||
|
||||
void handler( );
|
||||
|
||||
__attribute__((used))
|
||||
static void (^spd)() = ^()
|
||||
{
|
||||
handler( ^(){ syslog("%s", __FUNCTION__); } );
|
||||
|
|
|
@ -350,6 +350,7 @@ namespace VirtualMembers {
|
|||
virtual void f();
|
||||
};
|
||||
// CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i64 0, i64 2) }
|
||||
__attribute__((used))
|
||||
static nsMemoryImpl sGlobalMemory;
|
||||
|
||||
template<class T>
|
||||
|
|
|
@ -581,7 +581,7 @@ struct __declspec(dllimport) KeyFuncClass {
|
|||
constexpr KeyFuncClass() {}
|
||||
virtual void foo();
|
||||
};
|
||||
constexpr KeyFuncClass keyFuncClassVar;
|
||||
extern constexpr KeyFuncClass keyFuncClassVar = {};
|
||||
// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
|
||||
|
||||
struct __declspec(dllimport) X : public virtual W {};
|
||||
|
|
|
@ -18,8 +18,8 @@ struct A { virtual ~A(); };
|
|||
struct B : virtual A {};
|
||||
struct C { int n; };
|
||||
|
||||
// CHECK: @_ZN5Test1L5itemsE = internal constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }]
|
||||
constexpr Item items[] = {
|
||||
// CHECK: @_ZN5Test15itemsE = constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }]
|
||||
extern constexpr Item items[] = {
|
||||
item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
|
||||
};
|
||||
|
||||
|
|
|
@ -14,8 +14,13 @@ static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSA
|
|||
return (NSArray *)0;
|
||||
};
|
||||
|
||||
extern NSArray *address;
|
||||
extern unsigned long level;
|
||||
|
||||
void FUNC()
|
||||
{
|
||||
ArrayRecurs(address, level);
|
||||
|
||||
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
|
||||
|
||||
for(id rawAddress in addresses)
|
||||
|
@ -25,6 +30,7 @@ void FUNC()
|
|||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
ArrayRecurs(address, level);
|
||||
|
||||
if (ArrayRecurs) {
|
||||
static NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
|
||||
|
@ -36,6 +42,7 @@ void FUNC()
|
|||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
ArrayRecurs(address, level);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,8 +57,9 @@ void FUNC1()
|
|||
}
|
||||
return (NSArray *)0;
|
||||
};
|
||||
ArrayRecurs(address, level);
|
||||
}
|
||||
// CHECK-LP64: @ArrayRecurs = internal global
|
||||
// CHECK-LP64: @FUNC.ArrayRecurs = internal global
|
||||
// CHECK-LP64: @FUNC.ArrayRecurs.3 = internal global
|
||||
// CHECK-LP64: @FUNC.ArrayRecurs.1 = internal global
|
||||
// CHECK-LP64: @FUNC1.ArrayRecurs = internal global
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-pch -o %t.1 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_keyfunc -error-on-deserialized-decl S3 -include-pch %t.1 -emit-pch -o %t.2 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_method -error-on-deserialized-decl S3 -include-pch %t.2 -emit-llvm-only %s
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-pch -o %t.1 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_keyfunc -error-on-deserialized-decl S3 -error-on-deserialized-decl DND -std=c++11 -include-pch %t.1 -emit-pch -o %t.2 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_method -error-on-deserialized-decl S3 -error-on-deserialized-decl DND -std=c++11 -include-pch %t.2 -emit-llvm-only %s
|
||||
|
||||
// FIXME: Why does this require an x86 target?
|
||||
// REQUIRES: x86-registered-target
|
||||
|
@ -20,6 +20,15 @@ struct S2 {
|
|||
operator S3();
|
||||
};
|
||||
|
||||
namespace vars {
|
||||
constexpr int f() { return 0; }
|
||||
struct X { constexpr X() {} };
|
||||
namespace v1 { const int DND = 0; }
|
||||
namespace v2 { constexpr int DND = f(); }
|
||||
namespace v3 { static X DND; }
|
||||
namespace v4 { constexpr X DND = {}; }
|
||||
}
|
||||
|
||||
#elif !defined(HEADER2)
|
||||
#define HEADER2
|
||||
|
||||
|
|
Loading…
Reference in New Issue