[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.

llvm-svn: 217008
This commit is contained in:
Richard Smith 2014-09-03 02:33:22 +00:00
parent a1148b2173
commit 73b21d8fa1
6 changed files with 39 additions and 7 deletions

View File

@ -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.

View File

@ -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
//===----------------------------------------------------------------------===//

View File

@ -66,3 +66,7 @@ namespace EmitDefaultedSpecialMembers {
SmallString<256> SS;
};
}
inline int *getStaticDataMemberLeft() {
return WithUndefinedStaticDataMember<int[]>::undefined;
}

View File

@ -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;
}

View File

@ -53,3 +53,7 @@ namespace EmitDefaultedSpecialMembers {
// trivial dtor
};
}
template<typename T> struct WithUndefinedStaticDataMember {
static T undefined;
};

View File

@ -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();
}