diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 3f6941ab72d9..edbbc6a8c4f5 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1256,7 +1256,8 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D, case Decl::TypeAlias: // A typedef declaration has linkage if it gives a type a name for // linkage purposes. - if (!cast(D) + if (!D->getASTContext().getLangOpts().CPlusPlus || + !cast(D) ->getAnonDeclWithTypedefName(/*AnyRedecl*/true)) return LinkageInfo::none(); break; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e7c10d18a669..d051c4318dd2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1829,7 +1829,8 @@ static void filterNonConflictingPreviousTypedefDecls(Sema &S, // If both declarations give a tag declaration a typedef name for linkage // purposes, then they declare the same entity. - if (OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) && + if (S.getLangOpts().CPlusPlus && + OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) && Decl->getAnonDeclWithTypedefName()) continue; } diff --git a/clang/test/Index/usrs.m b/clang/test/Index/usrs.m index aa0c4a04fc7e..fc3fbc910578 100644 --- a/clang/test/Index/usrs.m +++ b/clang/test/Index/usrs.m @@ -119,7 +119,7 @@ int test_multi_declaration(void) { // CHECK: usrs.m c:@SA@MyStruct Extent=[15:9 - 18:2] // CHECK: usrs.m c:@SA@MyStruct@FI@wa Extent=[16:3 - 16:9] // CHECK: usrs.m c:@SA@MyStruct@FI@moo Extent=[17:3 - 17:10] -// CHECK: usrs.m c:@T@MyStruct Extent=[15:1 - 18:11] +// CHECK: usrs.m c:usrs.m@T@MyStruct Extent=[15:1 - 18:11] // CHECK: usrs.m c:@E@Pizza Extent=[20:1 - 23:2] // CHECK: usrs.m c:@E@Pizza@CHEESE Extent=[21:3 - 21:9] // CHECK: usrs.m c:@E@Pizza@MUSHROOMS Extent=[22:3 - 22:12] diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map index d195e2f0980f..226d45fdf44b 100644 --- a/clang/test/Modules/Inputs/module.map +++ b/clang/test/Modules/Inputs/module.map @@ -379,3 +379,10 @@ module DebugSubmodules { module ExtensionTestA { header "ExtensionTestA.h" } + +module TypedefTag { + header "typedef-tag.h" + explicit module Hidden { + header "typedef-tag-hidden.h" + } +} diff --git a/clang/test/Modules/Inputs/typedef-tag-hidden.h b/clang/test/Modules/Inputs/typedef-tag-hidden.h new file mode 100644 index 000000000000..eb59d69cc6e9 --- /dev/null +++ b/clang/test/Modules/Inputs/typedef-tag-hidden.h @@ -0,0 +1 @@ +typedef struct { int x; } TypedefStructHidden_t; diff --git a/clang/test/Modules/Inputs/typedef-tag.h b/clang/test/Modules/Inputs/typedef-tag.h new file mode 100644 index 000000000000..77dff951174e --- /dev/null +++ b/clang/test/Modules/Inputs/typedef-tag.h @@ -0,0 +1 @@ +typedef struct { int x; } TypedefStructVisible_t; diff --git a/clang/test/Modules/typedef-tag-not-visible.m b/clang/test/Modules/typedef-tag-not-visible.m new file mode 100644 index 000000000000..e1a640633f69 --- /dev/null +++ b/clang/test/Modules/typedef-tag-not-visible.m @@ -0,0 +1,8 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify + +@import TypedefTag; + +typedef struct { int x; } TypedefStructHidden_t; +typedef struct { int x; } TypedefStructVisible_t; // expected-error{{typedef redefinition}} +// expected-note@typedef-tag.h:1 {{here}}