summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/DeclBase.h6
-rw-r--r--clang/lib/AST/Decl.cpp5
-rw-r--r--clang/test/Modules/Inputs/templates-left.h4
-rw-r--r--clang/test/Modules/Inputs/templates-right.h4
-rw-r--r--clang/test/Modules/Inputs/templates-top.h4
-rw-r--r--clang/test/Modules/templates.mm23
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();
+}
+
+
OpenPOWER on IntegriCloud