Skip to content
Snippets Groups Projects
Commit fd2dea56 authored by Richard Smith's avatar Richard Smith
Browse files

[modules] Use DeclContext::equals rather than == on DeclContext* when

determining whether a declaration is out of line, instead of assuming
that the semantic and lexical DeclContext will be the same declaration
whenever they're the same entity.

This fixes behavior of declarations within merged classes and enums.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217008 91177308-0d34-0410-b5e6-96231b3b80d8
parent e9783b3a
No related branches found
No related tags found
No related merge requests found
...@@ -679,9 +679,9 @@ public: ...@@ -679,9 +679,9 @@ public:
return const_cast<Decl*>(this)->getLexicalDeclContext(); return const_cast<Decl*>(this)->getLexicalDeclContext();
} }
virtual bool isOutOfLine() const { /// Determine whether this declaration is declared out of line (outside its
return getLexicalDeclContext() != getDeclContext(); /// semantic context).
} virtual bool isOutOfLine() const;
/// setDeclContext - Set both the semantic and lexical DeclContext /// setDeclContext - Set both the semantic and lexical DeclContext
/// to DC. /// to DC.
......
...@@ -38,6 +38,11 @@ Decl *clang::getPrimaryMergedDecl(Decl *D) { ...@@ -38,6 +38,11 @@ Decl *clang::getPrimaryMergedDecl(Decl *D) {
return D->getASTContext().getPrimaryMergedDecl(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 // NamedDecl Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
......
...@@ -66,3 +66,7 @@ namespace EmitDefaultedSpecialMembers { ...@@ -66,3 +66,7 @@ namespace EmitDefaultedSpecialMembers {
SmallString<256> SS; SmallString<256> SS;
}; };
} }
inline int *getStaticDataMemberLeft() {
return WithUndefinedStaticDataMember<int[]>::undefined;
}
...@@ -43,3 +43,7 @@ template<typename T> struct MergePatternDecl; ...@@ -43,3 +43,7 @@ template<typename T> struct MergePatternDecl;
void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f); void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
void outOfLineInlineUseRightG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g); void outOfLineInlineUseRightG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g);
void outOfLineInlineUseRightH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h); void outOfLineInlineUseRightH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h);
inline int *getStaticDataMemberRight() {
return WithUndefinedStaticDataMember<int[]>::undefined;
}
...@@ -53,3 +53,7 @@ namespace EmitDefaultedSpecialMembers { ...@@ -53,3 +53,7 @@ namespace EmitDefaultedSpecialMembers {
// trivial dtor // trivial dtor
}; };
} }
template<typename T> struct WithUndefinedStaticDataMember {
static T undefined;
};
...@@ -12,10 +12,11 @@ void testInlineRedeclEarly() { ...@@ -12,10 +12,11 @@ void testInlineRedeclEarly() {
@import templates_right; @import templates_right;
// CHECK: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8, // CHECK-DAG: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8,
// CHECK: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12, // CHECK-DAG: @list_right = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 12,
// CHECK: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1, // CHECK-DAG: @_ZZ15testMixedStructvE1l = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 1,
// CHECK: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2, // CHECK-DAG: @_ZZ15testMixedStructvE1r = {{.*}} constant { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 2,
// CHECK-DAG: @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE = external global
void testTemplateClasses() { void testTemplateClasses() {
Vector<int> vec_int; Vector<int> vec_int;
...@@ -100,3 +101,17 @@ template struct ExplicitInstantiation<false, true>; ...@@ -100,3 +101,17 @@ template struct ExplicitInstantiation<false, true>;
template struct ExplicitInstantiation<true, true>; template struct ExplicitInstantiation<true, true>;
void testDelayUpdatesImpl() { testDelayUpdates<int>(); } 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();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment