<div dir="ltr"><div dir="ltr">Galina,<div><br></div><div>Thank you for letting me know. The test case used an enum with default type which has different behavior on Window systems. I've added a triple in r341496 which should fix the test.</div><div><br></div><div>Richard</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 5, 2018 at 1:45 PM Galina Kistanova <<a href="mailto:gkistanova@gmail.com">gkistanova@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr">Hello Richard,<br><br>This commit added broken test to one of our builders:<br><a href="http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/12240" target="_blank">http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/12240</a><br><br>. . .<br>Failing Tests (3):<br> Clang :: Modules/odr_hash.cpp<br> LLVM :: CodeGen/AMDGPU/mubuf-legalize-operands.ll<br> LLVM :: CodeGen/AMDGPU/mubuf-legalize-operands.mir<br><br>Please have a look?<br>The builder was already red and did not send notifications on this.<br><br>Thanks<br><br>Galina<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 4, 2018 at 3:54 PM Richard Trieu via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rtrieu<br>
Date: Tue Sep 4 15:53:19 2018<br>
New Revision: 341421<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=341421&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=341421&view=rev</a><br>
Log:<br>
[ODRHash] Extend hash to support all Type's.<br>
<br>
Added:<br>
cfe/trunk/test/Modules/odr_hash-gnu.cpp<br>
cfe/trunk/test/Modules/odr_hash-vector.cpp<br>
cfe/trunk/test/Modules/<a href="http://odr_hash.cl" rel="noreferrer" target="_blank">odr_hash.cl</a><br>
Modified:<br>
cfe/trunk/include/clang/AST/ODRHash.h<br>
cfe/trunk/lib/AST/ODRHash.cpp<br>
cfe/trunk/lib/AST/StmtProfile.cpp<br>
cfe/trunk/test/Modules/odr_hash-blocks.cpp<br>
cfe/trunk/test/Modules/odr_hash.cpp<br>
cfe/trunk/test/Modules/<a href="http://odr_hash.mm" rel="noreferrer" target="_blank">odr_hash.mm</a><br>
<br>
Modified: cfe/trunk/include/clang/AST/ODRHash.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ODRHash.h?rev=341421&r1=341420&r2=341421&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ODRHash.h?rev=341421&r1=341420&r2=341421&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/ODRHash.h (original)<br>
+++ cfe/trunk/include/clang/AST/ODRHash.h Tue Sep 4 15:53:19 2018<br>
@@ -83,7 +83,7 @@ public:<br>
void AddIdentifierInfo(const IdentifierInfo *II);<br>
void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);<br>
void AddTemplateName(TemplateName Name);<br>
- void AddDeclarationName(DeclarationName Name);<br>
+ void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false);<br>
void AddTemplateArgument(TemplateArgument TA);<br>
void AddTemplateParameterList(const TemplateParameterList *TPL);<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/ODRHash.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=341421&r1=341420&r2=341421&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=341421&r1=341420&r2=341421&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ODRHash.cpp (original)<br>
+++ cfe/trunk/lib/AST/ODRHash.cpp Tue Sep 4 15:53:19 2018<br>
@@ -32,7 +32,10 @@ void ODRHash::AddIdentifierInfo(const Id<br>
ID.AddString(II->getName());<br>
}<br>
<br>
-void ODRHash::AddDeclarationName(DeclarationName Name) {<br>
+void ODRHash::AddDeclarationName(DeclarationName Name, bool TreatAsDecl) {<br>
+ if (TreatAsDecl)<br>
+ AddBoolean(true);<br>
+<br>
// Index all DeclarationName and use index numbers to refer to them.<br>
auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size()));<br>
ID.AddInteger(Result.first->second);<br>
@@ -88,6 +91,9 @@ void ODRHash::AddDeclarationName(Declara<br>
}<br>
}<br>
}<br>
+<br>
+ if (TreatAsDecl)<br>
+ AddBoolean(false);<br>
}<br>
<br>
void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {<br>
@@ -405,6 +411,7 @@ public:<br>
<br>
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {<br>
AddDecl(D->getTemplatedDecl());<br>
+ ID.AddInteger(D->getTemplatedDecl()->getODRHash());<br>
Inherited::VisitFunctionTemplateDecl(D);<br>
}<br>
<br>
@@ -552,11 +559,27 @@ void ODRHash::AddFunctionDecl(const Func<br>
!Function->isDefaulted() && !Function->isDeleted() &&<br>
!Function->isLateTemplateParsed();<br>
AddBoolean(HasBody);<br>
- if (HasBody) {<br>
- auto *Body = Function->getBody();<br>
- AddBoolean(Body);<br>
- if (Body)<br>
- AddStmt(Body);<br>
+ if (!HasBody) {<br>
+ return;<br>
+ }<br>
+<br>
+ auto *Body = Function->getBody();<br>
+ AddBoolean(Body);<br>
+ if (Body)<br>
+ AddStmt(Body);<br>
+<br>
+ // Filter out sub-Decls which will not be processed in order to get an<br>
+ // accurate count of Decl's.<br>
+ llvm::SmallVector<const Decl *, 16> Decls;<br>
+ for (Decl *SubDecl : Function->decls()) {<br>
+ if (isWhitelistedDecl(SubDecl, Function)) {<br>
+ Decls.push_back(SubDecl);<br>
+ }<br>
+ }<br>
+<br>
+ ID.AddInteger(Decls.size());<br>
+ for (auto SubDecl : Decls) {<br>
+ AddSubDecl(SubDecl);<br>
}<br>
}<br>
<br>
@@ -592,13 +615,24 @@ void ODRHash::AddDecl(const Decl *D) {<br>
assert(D && "Expecting non-null pointer.");<br>
D = D->getCanonicalDecl();<br>
<br>
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {<br>
- AddDeclarationName(ND->getDeclName());<br>
+ const NamedDecl *ND = dyn_cast<NamedDecl>(D);<br>
+ AddBoolean(ND);<br>
+ if (!ND) {<br>
+ ID.AddInteger(D->getKind());<br>
return;<br>
}<br>
<br>
- ID.AddInteger(D->getKind());<br>
- // TODO: Handle non-NamedDecl here.<br>
+ AddDeclarationName(ND->getDeclName());<br>
+<br>
+ const auto *Specialization =<br>
+ dyn_cast<ClassTemplateSpecializationDecl>(D);<br>
+ AddBoolean(Specialization);<br>
+ if (Specialization) {<br>
+ const TemplateArgumentList &List = Specialization->getTemplateArgs();<br>
+ ID.AddInteger(List.size());<br>
+ for (const TemplateArgument &TA : List.asArray())<br>
+ AddTemplateArgument(TA);<br>
+ }<br>
}<br>
<br>
namespace {<br>
@@ -700,11 +734,67 @@ public:<br>
VisitArrayType(T);<br>
}<br>
<br>
+ void VisitAttributedType(const AttributedType *T) {<br>
+ ID.AddInteger(T->getAttrKind());<br>
+ AddQualType(T->getModifiedType());<br>
+ AddQualType(T->getEquivalentType());<br>
+<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitBlockPointerType(const BlockPointerType *T) {<br>
+ AddQualType(T->getPointeeType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
void VisitBuiltinType(const BuiltinType *T) {<br>
ID.AddInteger(T->getKind());<br>
VisitType(T);<br>
}<br>
<br>
+ void VisitComplexType(const ComplexType *T) {<br>
+ AddQualType(T->getElementType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitDecltypeType(const DecltypeType *T) {<br>
+ AddStmt(T->getUnderlyingExpr());<br>
+ AddQualType(T->getUnderlyingType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitDependentDecltypeType(const DependentDecltypeType *T) {<br>
+ VisitDecltypeType(T);<br>
+ }<br>
+<br>
+ void VisitDeducedType(const DeducedType *T) {<br>
+ AddQualType(T->getDeducedType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitAutoType(const AutoType *T) {<br>
+ ID.AddInteger((unsigned)T->getKeyword());<br>
+ VisitDeducedType(T);<br>
+ }<br>
+<br>
+ void VisitDeducedTemplateSpecializationType(<br>
+ const DeducedTemplateSpecializationType *T) {<br>
+ Hash.AddTemplateName(T->getTemplateName());<br>
+ VisitDeducedType(T);<br>
+ }<br>
+<br>
+ void VisitDependentAddressSpaceType(const DependentAddressSpaceType *T) {<br>
+ AddQualType(T->getPointeeType());<br>
+ AddStmt(T->getAddrSpaceExpr());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {<br>
+ AddQualType(T->getElementType());<br>
+ AddStmt(T->getSizeExpr());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
void VisitFunctionType(const FunctionType *T) {<br>
AddQualType(T->getReturnType());<br>
T->getExtInfo().Profile(ID);<br>
@@ -726,6 +816,74 @@ public:<br>
VisitFunctionType(T);<br>
}<br>
<br>
+ void VisitInjectedClassNameType(const InjectedClassNameType *T) {<br>
+ AddDecl(T->getDecl());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitMemberPointerType(const MemberPointerType *T) {<br>
+ AddQualType(T->getPointeeType());<br>
+ AddType(T->getClass());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {<br>
+ AddQualType(T->getPointeeType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitObjCObjectType(const ObjCObjectType *T) {<br>
+ AddDecl(T->getInterface());<br>
+<br>
+ auto TypeArgs = T->getTypeArgsAsWritten();<br>
+ ID.AddInteger(TypeArgs.size());<br>
+ for (auto Arg : TypeArgs) {<br>
+ AddQualType(Arg);<br>
+ }<br>
+<br>
+ auto Protocols = T->getProtocols();<br>
+ ID.AddInteger(Protocols.size());<br>
+ for (auto Protocol : Protocols) {<br>
+ AddDecl(Protocol);<br>
+ }<br>
+<br>
+ Hash.AddBoolean(T->isKindOfType());<br>
+<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitObjCInterfaceType(const ObjCInterfaceType *T) {<br>
+ // This type is handled by the parent type ObjCObjectType.<br>
+ VisitObjCObjectType(T);<br>
+ }<br>
+<br>
+ void VisitObjCTypeParamType(const ObjCTypeParamType *T) {<br>
+ AddDecl(T->getDecl());<br>
+ auto Protocols = T->getProtocols();<br>
+ ID.AddInteger(Protocols.size());<br>
+ for (auto Protocol : Protocols) {<br>
+ AddDecl(Protocol);<br>
+ }<br>
+<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitPackExpansionType(const PackExpansionType *T) {<br>
+ AddQualType(T->getPattern());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitParenType(const ParenType *T) {<br>
+ AddQualType(T->getInnerType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitPipeType(const PipeType *T) {<br>
+ AddQualType(T->getElementType());<br>
+ Hash.AddBoolean(T->isReadOnly());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
void VisitPointerType(const PointerType *T) {<br>
AddQualType(T->getPointeeType());<br>
VisitType(T);<br>
@@ -744,6 +902,43 @@ public:<br>
VisitReferenceType(T);<br>
}<br>
<br>
+ void<br>
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {<br>
+ AddType(T->getReplacedParameter());<br>
+ Hash.AddTemplateArgument(T->getArgumentPack());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {<br>
+ AddType(T->getReplacedParameter());<br>
+ AddQualType(T->getReplacementType());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitTagType(const TagType *T) {<br>
+ AddDecl(T->getDecl());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitRecordType(const RecordType *T) { VisitTagType(T); }<br>
+ void VisitEnumType(const EnumType *T) { VisitTagType(T); }<br>
+<br>
+ void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {<br>
+ ID.AddInteger(T->getNumArgs());<br>
+ for (const auto &TA : T->template_arguments()) {<br>
+ Hash.AddTemplateArgument(TA);<br>
+ }<br>
+ Hash.AddTemplateName(T->getTemplateName());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {<br>
+ ID.AddInteger(T->getDepth());<br>
+ ID.AddInteger(T->getIndex());<br>
+ Hash.AddBoolean(T->isParameterPack());<br>
+ AddDecl(T->getDecl());<br>
+ }<br>
+<br>
void VisitTypedefType(const TypedefType *T) {<br>
AddDecl(T->getDecl());<br>
QualType UnderlyingType = T->getDecl()->getUnderlyingType();<br>
@@ -766,13 +961,18 @@ public:<br>
VisitType(T);<br>
}<br>
<br>
- void VisitTagType(const TagType *T) {<br>
- AddDecl(T->getDecl());<br>
+ void VisitTypeOfExprType(const TypeOfExprType *T) {<br>
+ AddStmt(T->getUnderlyingExpr());<br>
+ Hash.AddBoolean(T->isSugared());<br>
+ if (T->isSugared())<br>
+ AddQualType(T->desugar());<br>
+<br>
+ VisitType(T);<br>
+ }<br>
+ void VisitTypeOfType(const TypeOfType *T) {<br>
+ AddQualType(T->getUnderlyingType());<br>
VisitType(T);<br>
}<br>
-<br>
- void VisitRecordType(const RecordType *T) { VisitTagType(T); }<br>
- void VisitEnumType(const EnumType *T) { VisitTagType(T); }<br>
<br>
void VisitTypeWithKeyword(const TypeWithKeyword *T) {<br>
ID.AddInteger(T->getKeyword());<br>
@@ -802,20 +1002,26 @@ public:<br>
VisitTypeWithKeyword(T);<br>
}<br>
<br>
- void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {<br>
- ID.AddInteger(T->getNumArgs());<br>
- for (const auto &TA : T->template_arguments()) {<br>
- Hash.AddTemplateArgument(TA);<br>
- }<br>
- Hash.AddTemplateName(T->getTemplateName());<br>
+ void VisitUnaryTransformType(const UnaryTransformType *T) {<br>
+ AddQualType(T->getUnderlyingType());<br>
+ AddQualType(T->getBaseType());<br>
VisitType(T);<br>
}<br>
<br>
- void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {<br>
- ID.AddInteger(T->getDepth());<br>
- ID.AddInteger(T->getIndex());<br>
- Hash.AddBoolean(T->isParameterPack());<br>
+ void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {<br>
AddDecl(T->getDecl());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitVectorType(const VectorType *T) {<br>
+ AddQualType(T->getElementType());<br>
+ ID.AddInteger(T->getNumElements());<br>
+ ID.AddInteger(T->getVectorKind());<br>
+ VisitType(T);<br>
+ }<br>
+<br>
+ void VisitExtVectorType(const ExtVectorType * T) {<br>
+ VisitVectorType(T);<br>
}<br>
};<br>
} // namespace<br>
<br>
Modified: cfe/trunk/lib/AST/StmtProfile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=341421&r1=341420&r2=341421&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=341421&r1=341420&r2=341421&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Sep 4 15:53:19 2018<br>
@@ -189,7 +189,7 @@ namespace {<br>
// store its nullness. Add a boolean here to match.<br>
ID.AddBoolean(true);<br>
}<br>
- Hash.AddDeclarationName(Name);<br>
+ Hash.AddDeclarationName(Name, TreatAsDecl);<br>
}<br>
void VisitIdentifierInfo(IdentifierInfo *II) override {<br>
ID.AddBoolean(II);<br>
<br>
Modified: cfe/trunk/test/Modules/odr_hash-blocks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-blocks.cpp?rev=341421&r1=341420&r2=341421&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-blocks.cpp?rev=341421&r1=341420&r2=341421&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/odr_hash-blocks.cpp (original)<br>
+++ cfe/trunk/test/Modules/odr_hash-blocks.cpp Tue Sep 4 15:53:19 2018<br>
@@ -41,7 +41,7 @@<br>
#define ACCESS private:<br>
#endif<br>
<br>
-// TODO: S1, S2, and S3 should generate errors.<br>
+// TODO: S1 and S2 should generate errors.<br>
namespace Blocks {<br>
#if defined(FIRST)<br>
struct S1 {<br>
@@ -77,6 +77,8 @@ struct S3 {<br>
};<br>
#else<br>
S3 s3;<br>
+// expected-error@first.h:* {{'Blocks::S3::run' from module 'FirstModule' is not present in definition of 'Blocks::S3' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'run' does not match}}<br>
#endif<br>
<br>
#define DECLS \<br>
<br>
Added: cfe/trunk/test/Modules/odr_hash-gnu.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-gnu.cpp?rev=341421&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-gnu.cpp?rev=341421&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/odr_hash-gnu.cpp (added)<br>
+++ cfe/trunk/test/Modules/odr_hash-gnu.cpp Tue Sep 4 15:53:19 2018<br>
@@ -0,0 +1,130 @@<br>
+// Clear and create directories<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+// RUN: mkdir %t/cache<br>
+// RUN: mkdir %t/Inputs<br>
+<br>
+// Build first header file<br>
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h<br>
+// RUN: cat %s >> %t/Inputs/first.h<br>
+<br>
+// Build second header file<br>
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h<br>
+// RUN: cat %s >> %t/Inputs/second.h<br>
+<br>
+// Test that each header can compile<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/first.h<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=gnu++11 %t/Inputs/second.h<br>
+<br>
+// Build module map file<br>
+// RUN: echo "module FirstModule {" >> %t/Inputs/module.map<br>
+// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map<br>
+// RUN: echo "}" >> %t/Inputs/module.map<br>
+// RUN: echo "module SecondModule {" >> %t/Inputs/module.map<br>
+// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map<br>
+// RUN: echo "}" >> %t/Inputs/module.map<br>
+<br>
+// Run test<br>
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=gnu++11 -fcolor-diagnostics<br>
+<br>
+#if !defined(FIRST) && !defined(SECOND)<br>
+#include "first.h"<br>
+#include "second.h"<br>
+#endif<br>
+<br>
+namespace Types {<br>
+namespace TypeOfExpr {<br>
+#if defined(FIRST)<br>
+struct Invalid1 {<br>
+ typeof(1 + 2) x;<br>
+};<br>
+double global;<br>
+struct Invalid2 {<br>
+ typeof(global) x;<br>
+};<br>
+struct Valid {<br>
+ typeof(3) x;<br>
+ typeof(x) y;<br>
+ typeof(Valid*) self;<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid1 {<br>
+ typeof(3) x;<br>
+};<br>
+int global;<br>
+struct Invalid2 {<br>
+ typeof(global) x;<br>
+};<br>
+struct Valid {<br>
+ typeof(3) x;<br>
+ typeof(x) y;<br>
+ typeof(Valid*) self;<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@first.h:* {{'Types::TypeOfExpr::Invalid1' has different definitions in different modules; first difference is definition in module 'FirstModule' found field 'x' with type 'typeof (1 + 2)' (aka 'int')}}<br>
+// expected-note@second.h:* {{but in 'SecondModule' found field 'x' with type 'typeof (3)' (aka 'int')}}<br>
+Invalid2 i2;<br>
+// expected-error@second.h:* {{'Types::TypeOfExpr::Invalid2::x' from module 'SecondModule' is not present in definition of 'Types::TypeOfExpr::Invalid2' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+Valid v;<br>
+#endif<br>
+} // namespace TypeOfExpr<br>
+<br>
+namespace TypeOf {<br>
+#if defined(FIRST)<br>
+struct Invalid1 {<br>
+ typeof(int) x;<br>
+};<br>
+struct Invalid2 {<br>
+ typeof(int) x;<br>
+};<br>
+using T = int;<br>
+struct Invalid3 {<br>
+ typeof(T) x;<br>
+};<br>
+struct Valid {<br>
+ typeof(int) x;<br>
+ using T = typeof(double);<br>
+ typeof(T) y;<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid1 {<br>
+ typeof(double) x;<br>
+};<br>
+using I = int;<br>
+struct Invalid2 {<br>
+ typeof(I) x;<br>
+};<br>
+using T = short;<br>
+struct Invalid3 {<br>
+ typeof(T) x;<br>
+};<br>
+struct Valid {<br>
+ typeof(int) x;<br>
+ using T = typeof(double);<br>
+ typeof(T) y;<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@second.h:* {{'Types::TypeOf::Invalid1::x' from module 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid1' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+Invalid2 i2;<br>
+// expected-error@first.h:* {{'Types::TypeOf::Invalid2' has different definitions in different modules; first difference is definition in module 'FirstModule' found field 'x' with type 'typeof(int)' (aka 'int')}}<br>
+// expected-note@second.h:* {{but in 'SecondModule' found field 'x' with type 'typeof(Types::TypeOf::I)' (aka 'int')}}<br>
+Invalid3 i3;<br>
+// expected-error@second.h:* {{'Types::TypeOf::Invalid3::x' from module 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid3' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+Valid v;<br>
+#endif<br>
+} // namespace TypeOf<br>
+} // namespace Types<br>
+<br>
+// Keep macros contained to one file.<br>
+#ifdef FIRST<br>
+#undef FIRST<br>
+#endif<br>
+<br>
+#ifdef SECOND<br>
+#undef SECOND<br>
+#endif<br>
<br>
Added: cfe/trunk/test/Modules/odr_hash-vector.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-vector.cpp?rev=341421&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash-vector.cpp?rev=341421&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/odr_hash-vector.cpp (added)<br>
+++ cfe/trunk/test/Modules/odr_hash-vector.cpp Tue Sep 4 15:53:19 2018<br>
@@ -0,0 +1,128 @@<br>
+// Clear and create directories<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+// RUN: mkdir %t/cache<br>
+// RUN: mkdir %t/Inputs<br>
+<br>
+// Build first header file<br>
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h<br>
+// RUN: cat %s >> %t/Inputs/first.h<br>
+<br>
+// Build second header file<br>
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h<br>
+// RUN: cat %s >> %t/Inputs/second.h<br>
+<br>
+// Test that each header can compile<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 %t/Inputs/first.h -fzvector<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 %t/Inputs/second.h -fzvector<br>
+<br>
+// Build module map file<br>
+// RUN: echo "module FirstModule {" >> %t/Inputs/module.map<br>
+// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map<br>
+// RUN: echo "}" >> %t/Inputs/module.map<br>
+// RUN: echo "module SecondModule {" >> %t/Inputs/module.map<br>
+// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map<br>
+// RUN: echo "}" >> %t/Inputs/module.map<br>
+<br>
+// Run test<br>
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++11 -fzvector<br>
+<br>
+#if !defined(FIRST) && !defined(SECOND)<br>
+#include "first.h"<br>
+#include "second.h"<br>
+#endif<br>
+<br>
+namespace Types {<br>
+namespace Vector {<br>
+#if defined(FIRST)<br>
+struct Invalid1 {<br>
+ __attribute((vector_size(8))) int x;<br>
+};<br>
+struct Invalid2 {<br>
+ __attribute((vector_size(8))) int x;<br>
+};<br>
+struct Invalid3 {<br>
+ __attribute((vector_size(16))) int x;<br>
+};<br>
+struct Valid {<br>
+ __attribute((vector_size(8))) int x1;<br>
+ __attribute((vector_size(16))) int x2;<br>
+ __attribute((vector_size(8))) unsigned x3;<br>
+ __attribute((vector_size(16))) long x4;<br>
+ vector unsigned x5;<br>
+ vector int x6;<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid1 {<br>
+ __attribute((vector_size(16))) int x;<br>
+};<br>
+struct Invalid2 {<br>
+ __attribute((vector_size(8))) unsigned x;<br>
+};<br>
+struct Invalid3 {<br>
+ vector unsigned x;<br>
+};<br>
+struct Valid {<br>
+ __attribute((vector_size(8))) int x1;<br>
+ __attribute((vector_size(16))) int x2;<br>
+ __attribute((vector_size(8))) unsigned x3;<br>
+ __attribute((vector_size(16))) long x4;<br>
+ vector unsigned x5;<br>
+ vector int x6;<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@second.h:* {{'Types::Vector::Invalid1::x' from module 'SecondModule' is not present in definition of 'Types::Vector::Invalid1' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+Invalid2 i2;<br>
+// expected-error@second.h:* {{'Types::Vector::Invalid2::x' from module 'SecondModule' is not present in definition of 'Types::Vector::Invalid2' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+Invalid3 i3;<br>
+// expected-error@second.h:* {{'Types::Vector::Invalid3::x' from module 'SecondModule' is not present in definition of 'Types::Vector::Invalid3' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+<br>
+Valid v;<br>
+#endif<br>
+} // namespace Vector<br>
+<br>
+<br>
+<br>
+namespace ExtVector {<br>
+} // namespace ExtVector<br>
+#if defined(FIRST)<br>
+struct Invalid {<br>
+ using f = __attribute__((ext_vector_type(4))) float;<br>
+};<br>
+struct Valid {<br>
+ using f = __attribute__((ext_vector_type(8))) float;<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid {<br>
+ using f = __attribute__((ext_vector_type(8))) float;<br>
+};<br>
+struct Valid {<br>
+ using f = __attribute__((ext_vector_type(8))) float;<br>
+};<br>
+#else<br>
+Invalid i;<br>
+// expected-error@first.h:* {{'Types::Invalid::f' from module 'FirstModule' is not present in definition of 'Types::Invalid' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'f' does not match}}<br>
+<br>
+Valid v;<br>
+#endif<br>
+<br>
+} // namespace Types<br>
+<br>
+<br>
+// Keep macros contained to one file.<br>
+#ifdef FIRST<br>
+#undef FIRST<br>
+#endif<br>
+<br>
+#ifdef SECOND<br>
+#undef SECOND<br>
+#endif<br>
+<br>
+#ifdef ACCESS<br>
+#undef ACCESS<br>
+#endif<br>
<br>
Added: cfe/trunk/test/Modules/<a href="http://odr_hash.cl" rel="noreferrer" target="_blank">odr_hash.cl</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cl?rev=341421&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cl?rev=341421&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/<a href="http://odr_hash.cl" rel="noreferrer" target="_blank">odr_hash.cl</a> (added)<br>
+++ cfe/trunk/test/Modules/<a href="http://odr_hash.cl" rel="noreferrer" target="_blank">odr_hash.cl</a> Tue Sep 4 15:53:19 2018<br>
@@ -0,0 +1,80 @@<br>
+// Clear and create directories<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+// RUN: mkdir %t/cache<br>
+// RUN: mkdir %t/Inputs<br>
+<br>
+// Build first header file<br>
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h<br>
+// RUN: cat %s >> %t/Inputs/first.h<br>
+<br>
+// Build second header file<br>
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h<br>
+// RUN: cat %s >> %t/Inputs/second.h<br>
+<br>
+// Test that each header can compile<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ %t/Inputs/first.h -cl-std=CL2.0<br>
+// RUN: %clang_cc1 -fsyntax-only -x c++ %t/Inputs/second.h -cl-std=CL2.0<br>
+<br>
+// Build module map file<br>
+// RUN: echo "module FirstModule {" >> %t/Inputs/module.map<br>
+// RUN: echo " header \"first.h\"" >> %t/Inputs/module.map<br>
+// RUN: echo "}" >> %t/Inputs/module.map<br>
+// RUN: echo "module SecondModule {" >> %t/Inputs/module.map<br>
+// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map<br>
+// RUN: echo "}" >> %t/Inputs/module.map<br>
+<br>
+// Run test<br>
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -cl-std=CL2.0<br>
+<br>
+#if !defined(FIRST) && !defined(SECOND)<br>
+#include "first.h"<br>
+#include "second.h"<br>
+#endif<br>
+<br>
+<br>
+#if defined(FIRST)<br>
+void invalid1() {<br>
+ typedef read_only pipe int x;<br>
+}<br>
+void invalid2() {<br>
+ typedef read_only pipe int x;<br>
+}<br>
+void valid() {<br>
+ typedef read_only pipe int x;<br>
+ typedef write_only pipe int y;<br>
+ typedef read_write pipe int z;<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid1() {<br>
+ typedef write_only pipe int x;<br>
+}<br>
+void invalid2() {<br>
+ typedef read_only pipe float x;<br>
+}<br>
+void valid() {<br>
+ typedef read_only pipe int x;<br>
+ typedef write_only pipe int y;<br>
+ typedef read_write pipe int z;<br>
+}<br>
+#else<br>
+void run() {<br>
+ invalid1();<br>
+// expected-error@second.h:* {{'invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+ invalid2();<br>
+// expected-error@second.h:* {{'invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+ valid();<br>
+}<br>
+#endif<br>
+<br>
+<br>
+// Keep macros contained to one file.<br>
+#ifdef FIRST<br>
+#undef FIRST<br>
+#endif<br>
+<br>
+#ifdef SECOND<br>
+#undef SECOND<br>
+#endif<br>
<br>
Modified: cfe/trunk/test/Modules/odr_hash.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=341421&r1=341420&r2=341421&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=341421&r1=341420&r2=341421&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/odr_hash.cpp (original)<br>
+++ cfe/trunk/test/Modules/odr_hash.cpp Tue Sep 4 15:53:19 2018<br>
@@ -25,7 +25,7 @@<br>
// RUN: echo "}" >> %t/Inputs/module.map<br>
<br>
// Run test<br>
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z<br>
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs -verify %s -std=c++1z -fcolor-diagnostics<br>
<br>
#if !defined(FIRST) && !defined(SECOND)<br>
#include "first.h"<br>
@@ -3299,6 +3299,568 @@ Valid V;<br>
#endif<br>
} // namespace Enums<br>
<br>
+namespace Types {<br>
+namespace Complex {<br>
+#if defined(FIRST)<br>
+void invalid() {<br>
+ _Complex float x;<br>
+}<br>
+void valid() {<br>
+ _Complex float x;<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid() {<br>
+ _Complex double x;<br>
+}<br>
+void valid() {<br>
+ _Complex float x;<br>
+}<br>
+#else<br>
+auto function1 = invalid;<br>
+// expected-error@second.h:* {{'Types::Complex::invalid' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = valid;<br>
+#endif<br>
+} // namespace Complex<br>
+<br>
+namespace Decltype {<br>
+#if defined(FIRST)<br>
+void invalid1() {<br>
+ decltype(1 + 1) x;<br>
+}<br>
+int global;<br>
+void invalid2() {<br>
+ decltype(global) x;<br>
+}<br>
+void valid() {<br>
+ decltype(1.5) x;<br>
+ decltype(x) y;<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid1() {<br>
+ decltype(2) x;<br>
+}<br>
+float global;<br>
+void invalid2() {<br>
+ decltype(global) x;<br>
+}<br>
+void valid() {<br>
+ decltype(1.5) x;<br>
+ decltype(x) y;<br>
+}<br>
+#else<br>
+auto function1 = invalid1;<br>
+// expected-error@second.h:* {{'Types::Decltype::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = invalid2;<br>
+// expected-error@second.h:* {{'Types::Decltype::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function3 = valid;<br>
+#endif<br>
+} // namespace Decltype<br>
+<br>
+namespace Auto {<br>
+#if defined(FIRST)<br>
+void invalid1() {<br>
+ decltype(auto) x = 1;<br>
+}<br>
+void invalid2() {<br>
+ auto x = 1;<br>
+}<br>
+void invalid3() {<br>
+ __auto_type x = 1;<br>
+}<br>
+void valid() {<br>
+ decltype(auto) x = 1;<br>
+ auto y = 1;<br>
+ __auto_type z = 1;<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid1() {<br>
+ auto x = 1;<br>
+}<br>
+void invalid2() {<br>
+ __auto_type x = 1;<br>
+}<br>
+void invalid3() {<br>
+ decltype(auto) x = 1;<br>
+}<br>
+void valid() {<br>
+ decltype(auto) x = 1;<br>
+ auto y = 1;<br>
+ __auto_type z = 1;<br>
+}<br>
+#else<br>
+auto function1 = invalid1;<br>
+// expected-error@second.h:* {{'Types::Auto::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = invalid3;<br>
+// expected-error@second.h:* {{'Types::Auto::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function3 = invalid2;<br>
+// expected-error@second.h:* {{'Types::Auto::invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function4 = valid;<br>
+#endif<br>
+} // namespace Auto<br>
+<br>
+namespace DeducedTemplateSpecialization {<br>
+#if defined(FIRST)<br>
+template<typename T> struct A {};<br>
+A() -> A<int>;<br>
+template<typename T> struct B {};<br>
+B() -> B<int>;<br>
+<br>
+void invalid1() {<br>
+ A a{};<br>
+}<br>
+void invalid2() {<br>
+ A a{};<br>
+}<br>
+void valid() {<br>
+ B b{};<br>
+}<br>
+#elif defined(SECOND)<br>
+template<typename T> struct A {};<br>
+A() -> A<float>;<br>
+template<typename T> struct B {};<br>
+B() -> B<int>;<br>
+<br>
+void invalid1() {<br>
+ A a{};<br>
+}<br>
+void invalid2() {<br>
+ B a{};<br>
+}<br>
+void valid() {<br>
+ B b{};<br>
+}<br>
+#else<br>
+auto function1 = invalid1;<br>
+// expected-error@second.h:* {{'Types::DeducedTemplateSpecialization::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = invalid2;<br>
+// expected-error@second.h:* {{'Types::DeducedTemplateSpecialization::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function3 = valid;<br>
+#endif<br>
+} // namespace DeducedTemplateSpecialization<br>
+<br>
+namespace DependentAddressSpace {<br>
+#if defined(FIRST)<br>
+template <int A1, int A2><br>
+void invalid1() {<br>
+ using type = int __attribute__((address_space(A1)));<br>
+}<br>
+template <int A1><br>
+void invalid2() {<br>
+ using type = float __attribute__((address_space(A1)));<br>
+}<br>
+template <int A1, int A2><br>
+void valid() {<br>
+ using type1 = float __attribute__((address_space(A1)));<br>
+ using type2 = int __attribute__((address_space(A2)));<br>
+ using type3 = int __attribute__((address_space(A1 + A2)));<br>
+}<br>
+#elif defined(SECOND)<br>
+template <int A1, int A2><br>
+void invalid1() {<br>
+ using type = int __attribute__((address_space(A2)));<br>
+}<br>
+template <int A1><br>
+void invalid2() {<br>
+ using type = int __attribute__((address_space(A1)));<br>
+}<br>
+template <int A1, int A2><br>
+void valid() {<br>
+ using type1 = float __attribute__((address_space(A1)));<br>
+ using type2 = int __attribute__((address_space(A2)));<br>
+ using type3 = int __attribute__((address_space(A1 + A2)));<br>
+}<br>
+#else<br>
+template <int A, int B><br>
+class S {<br>
+ static auto function1 = invalid1<A, B>;<br>
+ // expected-error@first.h:* {{'Types::DependentAddressSpace::invalid1' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}<br>
+ // expected-note@second.h:* {{but in 'SecondModule' found a different body}}<br>
+ static auto function2 = invalid2<B>;<br>
+ // expected-error@first.h:* {{'Types::DependentAddressSpace::invalid2' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}<br>
+ // expected-note@second.h:* {{but in 'SecondModule' found a different body}}<br>
+ static auto function3 = valid<A, B>;<br>
+};<br>
+#endif<br>
+} // namespace DependentAddressSpace<br>
+<br>
+namespace DependentSizedExtVector {<br>
+#if defined(FIRST)<br>
+template<int Size><br>
+void invalid1() {<br>
+ typedef int __attribute__((ext_vector_type(Size))) type;<br>
+}<br>
+template<int Size><br>
+void invalid2() {<br>
+ typedef int __attribute__((ext_vector_type(Size + 0))) type;<br>
+}<br>
+template<int Size><br>
+void valid() {<br>
+ typedef int __attribute__((ext_vector_type(Size))) type;<br>
+}<br>
+#elif defined(SECOND)<br>
+template<int Size><br>
+void invalid1() {<br>
+ typedef float __attribute__((ext_vector_type(Size))) type;<br>
+}<br>
+template<int Size><br>
+void invalid2() {<br>
+ typedef int __attribute__((ext_vector_type(Size + 1))) type;<br>
+}<br>
+template<int Size><br>
+void valid() {<br>
+ typedef int __attribute__((ext_vector_type(Size))) type;<br>
+}<br>
+#else<br>
+template <int Num><br>
+class S {<br>
+ static auto Function1 = invalid1<Num>;<br>
+ // expected-error@first.h:* {{'Types::DependentSizedExtVector::invalid1' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}<br>
+ // expected-note@second.h:* {{but in 'SecondModule' found a different body}}<br>
+ static auto Function2 = invalid2<Num>;<br>
+ // expected-error@first.h:* {{'Types::DependentSizedExtVector::invalid2' has different definitions in different modules; definition in module 'FirstModule' first difference is function body}}<br>
+ // expected-note@second.h:* {{but in 'SecondModule' found a different body}}<br>
+ static auto Function3 = valid<Num>;<br>
+};<br>
+#endif<br>
+} // namespace DependentSizedExtVector<br>
+<br>
+namespace InjectedClassName {<br>
+#if defined(FIRST)<br>
+struct Invalid {<br>
+ template <int><br>
+ struct L2 {<br>
+ template <int><br>
+ struct L3 {<br>
+ L3 *x;<br>
+ };<br>
+ };<br>
+};<br>
+struct Valid {<br>
+ template <int><br>
+ struct L2 {<br>
+ template <int><br>
+ struct L3 {<br>
+ L2 *x;<br>
+ L3 *y;<br>
+ };<br>
+ };<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid {<br>
+ template <int><br>
+ struct L2 {<br>
+ template <int><br>
+ struct L3 {<br>
+ L2 *x;<br>
+ };<br>
+ };<br>
+};<br>
+struct Valid {<br>
+ template <int><br>
+ struct L2 {<br>
+ template <int><br>
+ struct L3 {<br>
+ L2 *x;<br>
+ L3 *y;<br>
+ };<br>
+ };<br>
+};<br>
+#else<br>
+Invalid::L2<1>::L3<1> invalid;<br>
+// expected-error@second.h:* {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule' is not present in definition of 'L3<>' in module 'FirstModule'}}<br>
+// expected-note@first.h:* {{declaration of 'x' does not match}}<br>
+Valid::L2<1>::L3<1> valid;<br>
+#endif<br>
+} // namespace InjectedClassName<br>
+<br>
+namespace MemberPointer {<br>
+#if defined(FIRST)<br>
+struct A {};<br>
+struct B {};<br>
+<br>
+void Invalid1() {<br>
+ int A::*x;<br>
+};<br>
+void Invalid2() {<br>
+ int A::*x;<br>
+}<br>
+void Invalid3() {<br>
+ int (A::*x)(int);<br>
+}<br>
+void Valid() {<br>
+ int A::*x;<br>
+ float A::*y;<br>
+ bool B::*z;<br>
+ void (A::*fun1)();<br>
+ int (A::*fun2)();<br>
+ void (B::*fun3)(int);<br>
+ void (B::*fun4)(bool*, int);<br>
+}<br>
+#elif defined(SECOND)<br>
+struct A {};<br>
+struct B {};<br>
+<br>
+void Invalid1() {<br>
+ float A::*x;<br>
+};<br>
+void Invalid2() {<br>
+ int B::*x;<br>
+}<br>
+void Invalid3() {<br>
+ int (A::*x)(int, int);<br>
+}<br>
+void Valid() {<br>
+ int A::*x;<br>
+ float A::*y;<br>
+ bool B::*z;<br>
+ void (A::*fun1)();<br>
+ int (A::*fun2)();<br>
+ void (B::*fun3)(int);<br>
+ void (B::*fun4)(bool*, int);<br>
+}<br>
+#else<br>
+auto function1 = Invalid1;<br>
+// expected-error@second.h:* {{'Types::MemberPointer::Invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = Invalid2;<br>
+// expected-error@second.h:* {{'Types::MemberPointer::Invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function3 = Invalid3;<br>
+// expected-error@second.h:* {{'Types::MemberPointer::Invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function4 = Valid;<br>
+#endif<br>
+<br>
+} // namespace MemberPointer<br>
+<br>
+namespace PackExpansion {<br>
+#if defined(FIRST)<br>
+struct Invalid {<br>
+ template <class... A><br>
+ struct L2 {<br>
+ template <class... B><br>
+ struct L3 {<br>
+ void run(A...);<br>
+ void run(B...);<br>
+ };<br>
+ };<br>
+};<br>
+struct Valid {<br>
+ template <class... A><br>
+ struct L2 {<br>
+ template <class... B><br>
+ struct L3 {<br>
+ void run(A...);<br>
+ void run(B...);<br>
+ };<br>
+ };<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid {<br>
+ template <class... A><br>
+ struct L2 {<br>
+ template <class... B><br>
+ struct L3 {<br>
+ void run(B...);<br>
+ void run(A...);<br>
+ };<br>
+ };<br>
+};<br>
+struct Valid {<br>
+ template <class... A><br>
+ struct L2 {<br>
+ template <class... B><br>
+ struct L3 {<br>
+ void run(A...);<br>
+ void run(B...);<br>
+ };<br>
+ };<br>
+};<br>
+#else<br>
+Invalid::L2<int>::L3<short, bool> invalid;<br>
+// expected-error@first.h:* {{'Types::PackExpansion::Invalid::L2::L3' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'run' with 1st parameter of type 'A...'}}<br>
+// expected-note@second.h:* {{but in 'SecondModule' found method 'run' with 1st parameter of type 'B...'}}<br>
+Valid::L2<int>::L3<short, bool> valid;<br>
+#endif<br>
+<br>
+} // namespace PackExpansion<br>
+<br>
+namespace Paren {<br>
+#if defined(FIRST)<br>
+void invalid() {<br>
+ int (*x);<br>
+}<br>
+void valid() {<br>
+ int (*x);<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid() {<br>
+ float (*x);<br>
+}<br>
+void valid() {<br>
+ int (*x);<br>
+}<br>
+#else<br>
+auto function1 = invalid;<br>
+// expected-error@second.h:* {{'Types::Paren::invalid' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = valid;<br>
+#endif<br>
+} // namespace Paren<br>
+<br>
+namespace SubstTemplateTypeParm {<br>
+#if defined(FIRST)<br>
+template <class> struct wrapper {};<br>
+template <class, class, class> struct triple {};<br>
+struct Valid {<br>
+ template <class T,<br>
+ template <class _T, class _U, class = wrapper<_T>> class A = triple><br>
+ struct L2 {<br>
+ A<T, T> x;<br>
+ };<br>
+};<br>
+#elif defined(SECOND)<br>
+template <class> struct wrapper {};<br>
+template <class, class, class> struct triple {};<br>
+struct Valid {<br>
+ template <class T,<br>
+ template <class _T, class _U, class = wrapper<_T>> class A = triple><br>
+ struct L2 {<br>
+ A<T, T> x;<br>
+ };<br>
+};<br>
+#else<br>
+template <class T,<br>
+ template <class _T, class _U, class = wrapper<_T>> class A = triple><br>
+using V = Valid::L2<T, A>;<br>
+#endif<br>
+} // namespace SubstTemplateTypeParm<br>
+<br>
+namespace SubstTemplateTypeParmPack {<br>
+} // namespace SubstTemplateTypeParmPack<br>
+<br>
+namespace UnaryTransform {<br>
+#if defined(FIRST)<br>
+enum class E1a : unsigned {};<br>
+struct Invalid1 {<br>
+ __underlying_type(E1a) x;<br>
+};<br>
+enum E2a : unsigned {};<br>
+struct Invalid2 {<br>
+ __underlying_type(E2a) x;<br>
+};<br>
+enum E3a {};<br>
+struct Invalid3 {<br>
+ __underlying_type(E3a) x;<br>
+};<br>
+enum E4a {};<br>
+struct Invalid4 {<br>
+ __underlying_type(E4a) x;<br>
+};<br>
+enum E1 {};<br>
+struct Valid1 {<br>
+ __underlying_type(E1) x;<br>
+};<br>
+enum E2 : unsigned {};<br>
+struct Valid2 {<br>
+ __underlying_type(E2) x;<br>
+};<br>
+enum class E3 {};<br>
+struct Valid3 {<br>
+ __underlying_type(E3) x;<br>
+};<br>
+#elif defined(SECOND)<br>
+enum class E1b : signed {};<br>
+struct Invalid1 {<br>
+ __underlying_type(E1b) x;<br>
+};<br>
+enum class E2b : unsigned {};<br>
+struct Invalid2 {<br>
+ __underlying_type(E2b) x;<br>
+};<br>
+enum E3b : int {};<br>
+struct Invalid3 {<br>
+ __underlying_type(E3b) x;<br>
+};<br>
+enum E4b {};<br>
+struct Invalid4 {<br>
+ __underlying_type(E4b) x;<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@first.h:* {{'Types::UnaryTransform::Invalid1::x' from module 'FirstModule' is not present in definition of 'Types::UnaryTransform::Invalid1' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'x' does not match}}<br>
+Invalid2 i2;<br>
+// expected-error@second.h:* {{'Types::UnaryTransform::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '__underlying_type(Types::UnaryTransform::E2b)' (aka 'unsigned int')}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type '__underlying_type(Types::UnaryTransform::E2a)' (aka 'unsigned int')}}<br>
+Invalid3 i3;<br>
+// expected-error@first.h:* {{'Types::UnaryTransform::Invalid3::x' from module 'FirstModule' is not present in definition of 'Types::UnaryTransform::Invalid3' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'x' does not match}}<br>
+Invalid4 i4;<br>
+// expected-error@second.h:* {{'Types::UnaryTransform::Invalid4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '__underlying_type(Types::UnaryTransform::E4b)' (aka 'unsigned int')}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type '__underlying_type(Types::UnaryTransform::E4a)' (aka 'unsigned int')}}<br>
+Valid1 v1;<br>
+Valid2 v2;<br>
+Valid3 v3;<br>
+#endif<br>
+} // namespace UnaryTransform<br>
+<br>
+namespace UnresolvedUsing {<br>
+#if defined(FIRST)<br>
+template <class T> struct wrapper {};<br>
+template <class T><br>
+struct Invalid {<br>
+ using typename wrapper<T>::T1;<br>
+ using typename wrapper<T>::T2;<br>
+ T1 x;<br>
+};<br>
+template <class T><br>
+struct Valid {<br>
+ using typename wrapper<T>::T1;<br>
+ using typename wrapper<T>::T2;<br>
+ T1 x;<br>
+ T2 y;<br>
+};<br>
+#elif defined(SECOND)<br>
+template <class T> struct wrapper {};<br>
+template <class T><br>
+struct Invalid {<br>
+ using typename wrapper<T>::T1;<br>
+ using typename wrapper<T>::T2;<br>
+ T2 x;<br>
+};<br>
+template <class T><br>
+struct Valid {<br>
+ using typename wrapper<T>::T1;<br>
+ using typename wrapper<T>::T2;<br>
+ T1 x;<br>
+ T2 y;<br>
+};<br>
+#else<br>
+template <class T> using I = Invalid<T>;<br>
+// expected-error@first.h:* {{'Types::UnresolvedUsing::Invalid::x' from module 'FirstModule' is not present in definition of 'Invalid<T>' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'x' does not match}}<br>
+<br>
+template <class T> using V = Valid<T>;<br>
+#endif<br>
+<br>
+} // namespace UnresolvedUsing<br>
+<br>
+// Vector<br>
+// void invalid1() {<br>
+// __attribute((vector_size(8))) int *x1;<br>
+//}<br>
+<br>
+} // namespace Types<br>
+<br>
// Collection of interesting cases below.<br>
<br>
// Naive parsing of AST can lead to cycles in processing. Ensure<br>
<br>
Modified: cfe/trunk/test/Modules/<a href="http://odr_hash.mm" rel="noreferrer" target="_blank">odr_hash.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.mm?rev=341421&r1=341420&r2=341421&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.mm?rev=341421&r1=341420&r2=341421&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/<a href="http://odr_hash.mm" rel="noreferrer" target="_blank">odr_hash.mm</a> (original)<br>
+++ cfe/trunk/test/Modules/<a href="http://odr_hash.mm" rel="noreferrer" target="_blank">odr_hash.mm</a> Tue Sep 4 15:53:19 2018<br>
@@ -36,14 +36,27 @@<br>
@protocol P1<br>
@end<br>
<br>
+@protocol P2<br>
+@end<br>
+<br>
@interface I1<br>
@end<br>
<br>
+@interface I2 : I1<br>
+@end<br>
+<br>
@interface Interface1 <T : I1 *> {<br>
@public<br>
T<P1> x;<br>
}<br>
@end<br>
+<br>
+@interface Interface2 <T : I1 *><br>
+@end<br>
+<br>
+@interface Interface3 <T : I1 *><br>
+@end<br>
+<br>
#endif<br>
<br>
#if defined(FIRST)<br>
@@ -64,6 +77,218 @@ S s;<br>
// expected-note@first.h:* {{declaration of 'y' does not match}}<br>
#endif<br>
<br>
+namespace Types {<br>
+namespace Attributed {<br>
+#if defined(FIRST)<br>
+void invalid1() {<br>
+ static double __attribute((objc_gc(strong))) *x;<br>
+}<br>
+void invalid2() {<br>
+ static int __attribute((objc_gc(strong))) *x;<br>
+}<br>
+void valid() {<br>
+ static int __attribute((objc_gc(strong))) *x;<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid1() {<br>
+ static int __attribute((objc_gc(strong))) *x;<br>
+}<br>
+void invalid2() {<br>
+ static int __attribute((objc_gc(weak))) *x;<br>
+}<br>
+void valid() {<br>
+ static int __attribute((objc_gc(strong))) *x;<br>
+}<br>
+#else<br>
+auto function1 = invalid1;<br>
+// expected-error@second.h:* {{Types::Attributed::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = invalid2;<br>
+// expected-error@second.h:* {{'Types::Attributed::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function3 = valid;<br>
+#endif<br>
+} // namespace Attributed<br>
+<br>
+namespace BlockPointer {<br>
+#if defined(FIRST)<br>
+void invalid1() {<br>
+ void (^x)(int);<br>
+}<br>
+void invalid2() {<br>
+ void (^x)(int);<br>
+}<br>
+void invalid3() {<br>
+ void (^x)(int);<br>
+}<br>
+void invalid4() {<br>
+ void (^x)(int);<br>
+}<br>
+void valid() {<br>
+ void (^x1)(int);<br>
+ int (^x2)(int);<br>
+ void (^x3)(int, int);<br>
+ void (^x4)(short);<br>
+}<br>
+#elif defined(SECOND)<br>
+void invalid1() {<br>
+ void (^x)();<br>
+}<br>
+void invalid2() {<br>
+ void (^x)(int, int);<br>
+}<br>
+void invalid3() {<br>
+ int (^x)(int);<br>
+}<br>
+void invalid4() {<br>
+ void (^x)(float);<br>
+}<br>
+void valid() {<br>
+ void (^x1)(int);<br>
+ int (^x2)(int);<br>
+ void (^x3)(int, int);<br>
+ void (^x4)(short);<br>
+}<br>
+#else<br>
+auto function1 = invalid1;<br>
+// expected-error@second.h:* {{'Types::BlockPointer::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function2 = invalid2;<br>
+// expected-error@second.h:* {{'Types::BlockPointer::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function3 = invalid3;<br>
+// expected-error@second.h:* {{'Types::BlockPointer::invalid3' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function4 = invalid4;<br>
+// expected-error@second.h:* {{'Types::BlockPointer::invalid4' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found a different body}}<br>
+auto function5 = valid;<br>
+#endif<br>
+} // namespace BlockPointer<br>
+<br>
+namespace ObjCObject {<br>
+#if defined(FIRST)<br>
+struct Invalid1 {<br>
+ using T = Interface2<I1*>;<br>
+};<br>
+struct Invalid2 {<br>
+ using T = Interface2<I1*>;<br>
+};<br>
+struct Invalid3 {<br>
+ using T = Interface2<P1, P1>;<br>
+};<br>
+struct Invalid4 {<br>
+ using T = Interface2<P1>;<br>
+};<br>
+struct Valid {<br>
+ using T1 = Interface2<I1*>;<br>
+ using T2 = Interface3<I1*>;<br>
+ using T3 = Interface2<P1>;<br>
+ using T4 = Interface3<P1, P2>;<br>
+ using T5 = __kindof Interface2;<br>
+};<br>
+#elif defined(SECOND)<br>
+struct Invalid1 {<br>
+ using T = Interface3<I1*>;<br>
+};<br>
+struct Invalid2 {<br>
+ using T = Interface2<I2*>;<br>
+};<br>
+struct Invalid3 {<br>
+ using T = Interface2<P1>;<br>
+};<br>
+struct Invalid4 {<br>
+ using T = Interface2<P2>;<br>
+};<br>
+struct Valid {<br>
+ using T1 = Interface2<I1*>;<br>
+ using T2 = Interface3<I1*>;<br>
+ using T3 = Interface2<P1>;<br>
+ using T4 = Interface3<P1, P2>;<br>
+ using T5 = __kindof Interface2;<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@first.h:* {{'Types::ObjCObject::Invalid1::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid1' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'T' does not match}}<br>
+Invalid2 i2;<br>
+// expected-error@first.h:* {{'Types::ObjCObject::Invalid2::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid2' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'T' does not match}}<br>
+Invalid3 i3;<br>
+// expected-error@second.h:* {{'Types::ObjCObject::Invalid3' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'T' with underlying type 'Interface2<P1>'}}<br>
+// expected-note@first.h:* {{but in 'FirstModule' found type alias 'T' with different underlying type 'Interface2<P1,P1>'}}<br>
+Invalid4 i4;<br>
+// expected-error@first.h:* {{'Types::ObjCObject::Invalid4::T' from module 'FirstModule' is not present in definition of 'Types::ObjCObject::Invalid4' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'T' does not match}}<br>
+Valid v;<br>
+#endif<br>
+} // namespace VisitObjCObject<br>
+} // namespace Types<br>
+<br>
+#if defined(FIRST)<br>
+@interface Interface4 <T : I1 *> {<br>
+@public<br>
+ T<P1> x;<br>
+}<br>
+@end<br>
+@interface Interface5 <T : I1 *> {<br>
+@public<br>
+ T<P1> x;<br>
+}<br>
+@end<br>
+@interface Interface6 <T1 : I1 *, T2 : I2 *> {<br>
+@public<br>
+ T1 x;<br>
+}<br>
+@end<br>
+#elif defined(SECOND)<br>
+@interface Interface4 <T : I1 *> {<br>
+@public<br>
+ T<P2> x;<br>
+}<br>
+@end<br>
+@interface Interface5 <T : I1 *> {<br>
+@public<br>
+ T<P1, P2> x;<br>
+}<br>
+@end<br>
+@interface Interface6 <T1 : I1 *, T2 : I2 *> {<br>
+@public<br>
+ T2 x;<br>
+}<br>
+@end<br>
+#endif<br>
+<br>
+namespace Types {<br>
+namespace ObjCTypeParam {<br>
+#if defined(FIRST) || defined(SECOND)<br>
+struct Invalid1 {<br>
+ Interface4 *I;<br>
+ decltype(I->x) x;<br>
+};<br>
+struct Invalid2 {<br>
+ Interface5 *I;<br>
+ decltype(I->x) x;<br>
+};<br>
+struct Invalid3 {<br>
+ Interface6 *I;<br>
+ decltype(I->x) x;<br>
+};<br>
+#else<br>
+Invalid1 i1;<br>
+// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid1::x' from module 'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid1' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'x' does not match}}<br>
+Invalid2 i2;<br>
+// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid2::x' from module 'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid2' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'x' does not match}}<br>
+Invalid3 i3;<br>
+// expected-error@first.h:* {{'Types::ObjCTypeParam::Invalid3::x' from module 'FirstModule' is not present in definition of 'Types::ObjCTypeParam::Invalid3' in module 'SecondModule'}}<br>
+// expected-note@second.h:* {{declaration of 'x' does not match}}<br>
+#endif<br>
+<br>
+} // namespace ObjCTypeParam<br>
+} // namespace Types<br>
+<br>
// Keep macros contained to one file.<br>
#ifdef FIRST<br>
#undef FIRST<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>
</blockquote></div>