diff options
| -rw-r--r-- | clang/include/clang/AST/DeclBase.h | 6 | ||||
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 5 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-left.h | 4 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-right.h | 4 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-top.h | 4 | ||||
| -rw-r--r-- | clang/test/Modules/templates.mm | 23 |
6 files changed, 39 insertions, 7 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 551a883a8fa..58860b27ad5 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -679,9 +679,9 @@ public: return const_cast<Decl*>(this)->getLexicalDeclContext(); } - virtual bool isOutOfLine() const { - return getLexicalDeclContext() != getDeclContext(); - } + /// Determine whether this declaration is declared out of line (outside its + /// semantic context). + virtual bool isOutOfLine() const; /// setDeclContext - Set both the semantic and lexical DeclContext /// to DC. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 04431ced36a..08a6490f140 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -38,6 +38,11 @@ Decl *clang::getPrimaryMergedDecl(Decl *D) { return D->getASTContext().getPrimaryMergedDecl(D); } +// Defined here so that it can be inlined into its direct callers. +bool Decl::isOutOfLine() const { + return !getLexicalDeclContext()->Equals(getDeclContext()); +} + //===----------------------------------------------------------------------===// // NamedDecl Implementation //===----------------------------------------------------------------------===// diff --git a/clang/test/Modules/Inputs/templates-left.h b/clang/test/Modules/Inputs/templates-left.h index 7ca5cc52a12..cbe89434f9f 100644 --- a/clang/test/Modules/Inputs/templates-left.h +++ b/clang/test/Modules/Inputs/templates-left.h @@ -66,3 +66,7 @@ namespace EmitDefaultedSpecialMembers { SmallString<256> SS; }; } + +inline int *getStaticDataMemberLeft() { + return WithUndefinedStaticDataMember<int[]>::undefined; +} diff --git a/clang/test/Modules/Inputs/templates-right.h b/clang/test/Modules/Inputs/templates-right.h index 5907cbca73e..daea97b86b8 100644 --- a/clang/test/Modules/Inputs/templates-right.h +++ b/clang/test/Modules/Inputs/templates-right.h @@ -43,3 +43,7 @@ template<typename T> struct MergePatternDecl; void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f); void outOfLineInlineUseRightG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g); void outOfLineInlineUseRightH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h); + +inline int *getStaticDataMemberRight() { + return WithUndefinedStaticDataMember<int[]>::undefined; +} diff --git a/clang/test/Modules/Inputs/templates-top.h b/clang/test/Modules/Inputs/templates-top.h index b1e0548d41e..31f5e419928 100644 --- a/clang/test/Modules/Inputs/templates-top.h +++ b/clang/test/Modules/Inputs/templates-top.h @@ -53,3 +53,7 @@ namespace EmitDefaultedSpecialMembers { // trivial dtor }; } + +template<typename T> struct WithUndefinedStaticDataMember { + static T undefined; +}; diff --git a/clang/test/Modules/templates.mm b/clang/test/Modules/templates.mm index 78348af41e7..67a1e070e23 100644 --- a/clang/test/Modules/templates.mm +++ b/clang/test/Modules/templates.mm @@ -12,10 +12,11 @@ void testInlineRedeclEarly() { @import templates_right; -// CHECK: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8, -// CHECK: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12, -// CHECK: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1, -// CHECK: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2, +// CHECK-DAG: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8, +// CHECK-DAG: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12, +// CHECK-DAG: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1, +// CHECK-DAG: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2, +// CHECK-DAG: @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE = external global void testTemplateClasses() { Vector<int> vec_int; @@ -100,3 +101,17 @@ template struct ExplicitInstantiation<false, true>; template struct ExplicitInstantiation<true, true>; void testDelayUpdatesImpl() { testDelayUpdates<int>(); } + +void testStaticDataMember() { + WithUndefinedStaticDataMember<int[]> load_it; + + // CHECK-LABEL: define linkonce_odr i32* @_Z23getStaticDataMemberLeftv( + // CHECK: ret i32* getelementptr inbounds ([0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i32 0, i32 0) + (void) getStaticDataMemberLeft(); + + // CHECK-LABEL: define linkonce_odr i32* @_Z24getStaticDataMemberRightv( + // CHECK: ret i32* getelementptr inbounds ([0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i32 0, i32 0) + (void) getStaticDataMemberRight(); +} + + |

