Skip to content

Commit

Permalink
[ODRHash] Hash typedefs and usings statements in classes.
Browse files Browse the repository at this point in the history
llvm-svn: 297246
  • Loading branch information
Weverything committed Mar 8, 2017
1 parent 1351db4 commit 33562c2
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
17 changes: 17 additions & 0 deletions clang/lib/AST/ODRHash.cpp
Expand Up @@ -211,6 +211,20 @@ class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {

Inherited::VisitCXXMethodDecl(D);
}

void VisitTypedefNameDecl(const TypedefNameDecl *D) {
AddQualType(D->getUnderlyingType());

Inherited::VisitTypedefNameDecl(D);
}

void VisitTypedefDecl(const TypedefDecl *D) {
Inherited::VisitTypedefDecl(D);
}

void VisitTypeAliasDecl(const TypeAliasDecl *D) {
Inherited::VisitTypeAliasDecl(D);
}
};

// Only allow a small portion of Decl's to be processed. Remove this once
Expand All @@ -226,6 +240,8 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
case Decl::CXXMethod:
case Decl::Field:
case Decl::StaticAssert:
case Decl::TypeAlias:
case Decl::Typedef:
return true;
}
}
Expand Down Expand Up @@ -313,6 +329,7 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {

void VisitTypedefType(const TypedefType *T) {
AddDecl(T->getDecl());
Hash.AddQualType(T->getDecl()->getUnderlyingType());
VisitType(T);
}
};
Expand Down
105 changes: 105 additions & 0 deletions clang/test/Modules/odr_hash.cpp
Expand Up @@ -430,6 +430,99 @@ struct NestedNamespaceSpecifier {};
#endif
} // namespace SelfReference

namespace TypeDef {
#if defined(FIRST)
struct S1 {
typedef int a;
};
#elif defined(SECOND)
struct S1 {
typedef double a;
};
#else
S1 s1;
// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'a' does not match}}
#endif

#if defined(FIRST)
struct S2 {
typedef int a;
};
#elif defined(SECOND)
struct S2 {
typedef int b;
};
#else
S2 s2;
// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}}
// expected-note@second.h:* {{definition has no member 'a'}}
#endif

#if defined(FIRST)
typedef int T;
struct S3 {
typedef T a;
};
#elif defined(SECOND)
typedef double T;
struct S3 {
typedef T a;
};
#else
S3 s3;
// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'a' does not match}}
#endif
} // namespace TypeDef

namespace Using {
#if defined(FIRST)
struct S1 {
using a = int;
};
#elif defined(SECOND)
struct S1 {
using a = double;
};
#else
S1 s1;
// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'a' does not match}}
#endif

#if defined(FIRST)
struct S2 {
using a = int;
};
#elif defined(SECOND)
struct S2 {
using b = int;
};
#else
S2 s2;
// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}}
// expected-note@second.h:* {{definition has no member 'a'}}
#endif

#if defined(FIRST)
typedef int T;
struct S3 {
using a = T;
};
#elif defined(SECOND)
typedef double T;
struct S3 {
using a = T;
};
#else
S3 s3;
// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
// expected-note@second.h:* {{declaration of 'a' does not match}}
#endif
} // namespace Using


// Interesting cases that should not cause errors. struct S should not error
// while struct T should error at the access specifier mismatch at the end.
namespace AllDecls {
Expand Down Expand Up @@ -460,6 +553,9 @@ struct S {
inline void inline_method() {}
void volatile_method() volatile {}
void const_method() const {}

typedef int typedef_int;
using using_int = int;
};
#elif defined(SECOND)
typedef int INT;
Expand Down Expand Up @@ -488,6 +584,9 @@ struct S {
inline void inline_method() {}
void volatile_method() volatile {}
void const_method() const {}

typedef int typedef_int;
using using_int = int;
};
#else
S *s;
Expand Down Expand Up @@ -521,6 +620,9 @@ struct T {
void volatile_method() volatile {}
void const_method() const {}

typedef int typedef_int;
using using_int = int;

private:
};
#elif defined(SECOND)
Expand Down Expand Up @@ -551,6 +653,9 @@ struct T {
void volatile_method() volatile {}
void const_method() const {}

typedef int typedef_int;
using using_int = int;

public:
};
#else
Expand Down

0 comments on commit 33562c2

Please sign in to comment.