Index: lib/AST/ODRHash.cpp =================================================================== --- lib/AST/ODRHash.cpp +++ lib/AST/ODRHash.cpp @@ -749,7 +749,10 @@ void ODRHash::AddType(const Type *T) { assert(T && "Expecting non-null pointer."); - auto Result = TypeMap.insert(std::make_pair(T, TypeMap.size())); + const Type *TypeInTypeMap = T; + if (const ElaboratedType *ElTy = dyn_cast(T)) + TypeInTypeMap = ElTy->getNamedType().getTypePtr(); + auto Result = TypeMap.insert(std::make_pair(TypeInTypeMap, TypeMap.size())); ID.AddInteger(Result.first->second); // On first encounter of a Type pointer, process it. Every time afterwards, // only the index value is needed. Index: test/Modules/Inputs/odr_hash-elaborated-types/first.h =================================================================== --- test/Modules/Inputs/odr_hash-elaborated-types/first.h +++ test/Modules/Inputs/odr_hash-elaborated-types/first.h @@ -0,0 +1,6 @@ +#ifndef FIRST +#define FIRST + +#include "textual_time.h" + +#endif Index: test/Modules/Inputs/odr_hash-elaborated-types/module.modulemap =================================================================== --- test/Modules/Inputs/odr_hash-elaborated-types/module.modulemap +++ test/Modules/Inputs/odr_hash-elaborated-types/module.modulemap @@ -0,0 +1,5 @@ +module M { + module first { header "first.h" export *} + module second { header "second.h" export *} + export * +} Index: test/Modules/Inputs/odr_hash-elaborated-types/second.h =================================================================== --- test/Modules/Inputs/odr_hash-elaborated-types/second.h +++ test/Modules/Inputs/odr_hash-elaborated-types/second.h @@ -0,0 +1,6 @@ +#ifndef SECOND +#define SECOND + +#include "textual_stat.h" + +#endif Index: test/Modules/Inputs/odr_hash-elaborated-types/textual_stat.h =================================================================== --- test/Modules/Inputs/odr_hash-elaborated-types/textual_stat.h +++ test/Modules/Inputs/odr_hash-elaborated-types/textual_stat.h @@ -0,0 +1,11 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include "textual_time.h" + +struct stat { + struct timespec st_atim; + struct timespec st_mtim; +}; + +#endif Index: test/Modules/Inputs/odr_hash-elaborated-types/textual_time.h =================================================================== --- test/Modules/Inputs/odr_hash-elaborated-types/textual_time.h +++ test/Modules/Inputs/odr_hash-elaborated-types/textual_time.h @@ -0,0 +1,6 @@ +#ifndef _TIME_H +#define _TIME_H + +struct timespec { }; + +#endif Index: test/Modules/odr_hash-elaborated-types.cpp =================================================================== --- test/Modules/odr_hash-elaborated-types.cpp +++ test/Modules/odr_hash-elaborated-types.cpp @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -std=c++1z -I%S/Inputs/odr_hash-elaborated-types -verify %s +// RUN: %clang_cc1 -std=c++1z -fmodules -fmodules-local-submodule-visibility -fmodule-map-file=%S/Inputs/odr_hash-elaborated-types/module.modulemap -fmodules-cache-path=%t -x c++ -I%S/Inputs/odr_hash-elaborated-types -verify %s + +#include "textual_stat.h" + +#include "first.h" +#include "second.h" + +void use() { struct stat value; } + +// expected-no-diagnostics