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