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