r341421 - [ODRHash] Extend hash to support all Type's.
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 5 14:58:22 PDT 2018
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 <gkistanova at 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 at 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 at first.h:* {{'Blocks::S3::run' from module
>> 'FirstModule' is not present in definition of 'Blocks::S3' in module
>> 'SecondModule'}}
>> +// expected-note at 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 at 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 at second.h:* {{but in 'SecondModule' found field 'x'
>> with type 'typeof (3)' (aka 'int')}}
>> +Invalid2 i2;
>> +// expected-error at second.h:* {{'Types::TypeOfExpr::Invalid2::x' from
>> module 'SecondModule' is not present in definition of
>> 'Types::TypeOfExpr::Invalid2' in module 'FirstModule'}}
>> +// expected-note at 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 at second.h:* {{'Types::TypeOf::Invalid1::x' from module
>> 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid1' in
>> module 'FirstModule'}}
>> +// expected-note at first.h:* {{declaration of 'x' does not match}}
>> +Invalid2 i2;
>> +// expected-error at 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 at second.h:* {{but in 'SecondModule' found field 'x'
>> with type 'typeof(Types::TypeOf::I)' (aka 'int')}}
>> +Invalid3 i3;
>> +// expected-error at second.h:* {{'Types::TypeOf::Invalid3::x' from module
>> 'SecondModule' is not present in definition of 'Types::TypeOf::Invalid3' in
>> module 'FirstModule'}}
>> +// expected-note at 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 at second.h:* {{'Types::Vector::Invalid1::x' from module
>> 'SecondModule' is not present in definition of 'Types::Vector::Invalid1' in
>> module 'FirstModule'}}
>> +// expected-note at first.h:* {{declaration of 'x' does not match}}
>> +Invalid2 i2;
>> +// expected-error at second.h:* {{'Types::Vector::Invalid2::x' from module
>> 'SecondModule' is not present in definition of 'Types::Vector::Invalid2' in
>> module 'FirstModule'}}
>> +// expected-note at first.h:* {{declaration of 'x' does not match}}
>> +Invalid3 i3;
>> +// expected-error at second.h:* {{'Types::Vector::Invalid3::x' from module
>> 'SecondModule' is not present in definition of 'Types::Vector::Invalid3' in
>> module 'FirstModule'}}
>> +// expected-note at 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 at first.h:* {{'Types::Invalid::f' from module
>> 'FirstModule' is not present in definition of 'Types::Invalid' in module
>> 'SecondModule'}}
>> +// expected-note at 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 at second.h:* {{'invalid1' has different definitions in
>> different modules; definition in module 'SecondModule' first difference is
>> function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> + invalid2();
>> +// expected-error at second.h:* {{'invalid2' has different definitions in
>> different modules; definition in module 'SecondModule' first difference is
>> function body}}
>> +// expected-note at 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 at second.h:* {{'Types::Complex::invalid' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at 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 at second.h:* {{'Types::Decltype::invalid1' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function2 = invalid2;
>> +// expected-error at second.h:* {{'Types::Decltype::invalid2' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at 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 at second.h:* {{'Types::Auto::invalid1' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function2 = invalid3;
>> +// expected-error at second.h:* {{'Types::Auto::invalid2' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function3 = invalid2;
>> +// expected-error at second.h:* {{'Types::Auto::invalid3' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at 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 at second.h:*
>> {{'Types::DeducedTemplateSpecialization::invalid1' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function2 = invalid2;
>> +// expected-error at second.h:*
>> {{'Types::DeducedTemplateSpecialization::invalid2' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at 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 at first.h:*
>> {{'Types::DependentAddressSpace::invalid1' has different definitions in
>> different modules; definition in module 'FirstModule' first difference is
>> function body}}
>> + // expected-note at second.h:* {{but in 'SecondModule' found a different
>> body}}
>> + static auto function2 = invalid2<B>;
>> + // expected-error at first.h:*
>> {{'Types::DependentAddressSpace::invalid2' has different definitions in
>> different modules; definition in module 'FirstModule' first difference is
>> function body}}
>> + // expected-note at 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 at first.h:*
>> {{'Types::DependentSizedExtVector::invalid1' has different definitions in
>> different modules; definition in module 'FirstModule' first difference is
>> function body}}
>> + // expected-note at second.h:* {{but in 'SecondModule' found a different
>> body}}
>> + static auto Function2 = invalid2<Num>;
>> + // expected-error at first.h:*
>> {{'Types::DependentSizedExtVector::invalid2' has different definitions in
>> different modules; definition in module 'FirstModule' first difference is
>> function body}}
>> + // expected-note at 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 at second.h:*
>> {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule'
>> is not present in definition of 'L3<>' in module 'FirstModule'}}
>> +// expected-note at 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 at second.h:* {{'Types::MemberPointer::Invalid1' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function2 = Invalid2;
>> +// expected-error at second.h:* {{'Types::MemberPointer::Invalid2' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function3 = Invalid3;
>> +// expected-error at second.h:* {{'Types::MemberPointer::Invalid3' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at 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 at 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 at 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 at second.h:* {{'Types::Paren::invalid' has different
>> definitions in different modules; definition in module 'SecondModule' first
>> difference is function body}}
>> +// expected-note at 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 at first.h:* {{'Types::UnaryTransform::Invalid1::x' from
>> module 'FirstModule' is not present in definition of
>> 'Types::UnaryTransform::Invalid1' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'x' does not match}}
>> +Invalid2 i2;
>> +// expected-error at 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 at first.h:* {{but in 'FirstModule' found field 'x' with
>> type '__underlying_type(Types::UnaryTransform::E2a)' (aka 'unsigned int')}}
>> +Invalid3 i3;
>> +// expected-error at first.h:* {{'Types::UnaryTransform::Invalid3::x' from
>> module 'FirstModule' is not present in definition of
>> 'Types::UnaryTransform::Invalid3' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'x' does not match}}
>> +Invalid4 i4;
>> +// expected-error at 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 at 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 at first.h:* {{'Types::UnresolvedUsing::Invalid::x' from
>> module 'FirstModule' is not present in definition of 'Invalid<T>' in module
>> 'SecondModule'}}
>> +// expected-note at 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
>>
>> + at protocol P2
>> + at end
>> +
>> @interface I1
>> @end
>>
>> + at interface I2 : I1
>> + at end
>> +
>> @interface Interface1 <T : I1 *> {
>> @public
>> T<P1> x;
>> }
>> @end
>> +
>> + at interface Interface2 <T : I1 *>
>> + at end
>> +
>> + at interface Interface3 <T : I1 *>
>> + at end
>> +
>> #endif
>>
>> #if defined(FIRST)
>> @@ -64,6 +77,218 @@ S s;
>> // expected-note at 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 at second.h:* {{Types::Attributed::invalid1' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function2 = invalid2;
>> +// expected-error at second.h:* {{'Types::Attributed::invalid2' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at 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 at second.h:* {{'Types::BlockPointer::invalid1' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function2 = invalid2;
>> +// expected-error at second.h:* {{'Types::BlockPointer::invalid2' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function3 = invalid3;
>> +// expected-error at second.h:* {{'Types::BlockPointer::invalid3' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at first.h:* {{but in 'FirstModule' found a different
>> body}}
>> +auto function4 = invalid4;
>> +// expected-error at second.h:* {{'Types::BlockPointer::invalid4' has
>> different definitions in different modules; definition in module
>> 'SecondModule' first difference is function body}}
>> +// expected-note at 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 at first.h:* {{'Types::ObjCObject::Invalid1::T' from
>> module 'FirstModule' is not present in definition of
>> 'Types::ObjCObject::Invalid1' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'T' does not match}}
>> +Invalid2 i2;
>> +// expected-error at first.h:* {{'Types::ObjCObject::Invalid2::T' from
>> module 'FirstModule' is not present in definition of
>> 'Types::ObjCObject::Invalid2' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'T' does not match}}
>> +Invalid3 i3;
>> +// expected-error at 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 at first.h:* {{but in 'FirstModule' found type alias 'T'
>> with different underlying type 'Interface2<P1,P1>'}}
>> +Invalid4 i4;
>> +// expected-error at first.h:* {{'Types::ObjCObject::Invalid4::T' from
>> module 'FirstModule' is not present in definition of
>> 'Types::ObjCObject::Invalid4' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'T' does not match}}
>> +Valid v;
>> +#endif
>> +} // namespace VisitObjCObject
>> +} // namespace Types
>> +
>> +#if defined(FIRST)
>> + at interface Interface4 <T : I1 *> {
>> + at public
>> + T<P1> x;
>> +}
>> + at end
>> + at interface Interface5 <T : I1 *> {
>> + at public
>> + T<P1> x;
>> +}
>> + at end
>> + at interface Interface6 <T1 : I1 *, T2 : I2 *> {
>> + at public
>> + T1 x;
>> +}
>> + at end
>> +#elif defined(SECOND)
>> + at interface Interface4 <T : I1 *> {
>> + at public
>> + T<P2> x;
>> +}
>> + at end
>> + at interface Interface5 <T : I1 *> {
>> + at public
>> + T<P1, P2> x;
>> +}
>> + at end
>> + at interface Interface6 <T1 : I1 *, T2 : I2 *> {
>> + at public
>> + T2 x;
>> +}
>> + at 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 at first.h:* {{'Types::ObjCTypeParam::Invalid1::x' from
>> module 'FirstModule' is not present in definition of
>> 'Types::ObjCTypeParam::Invalid1' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'x' does not match}}
>> +Invalid2 i2;
>> +// expected-error at first.h:* {{'Types::ObjCTypeParam::Invalid2::x' from
>> module 'FirstModule' is not present in definition of
>> 'Types::ObjCTypeParam::Invalid2' in module 'SecondModule'}}
>> +// expected-note at second.h:* {{declaration of 'x' does not match}}
>> +Invalid3 i3;
>> +// expected-error at first.h:* {{'Types::ObjCTypeParam::Invalid3::x' from
>> module 'FirstModule' is not present in definition of
>> 'Types::ObjCTypeParam::Invalid3' in module 'SecondModule'}}
>> +// expected-note at 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 at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180905/8b4755c5/attachment-0001.html>
More information about the cfe-commits
mailing list