summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2017-07-01 20:44:49 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2017-07-01 20:44:49 +0000
commit17fb9ad1ae41e5b764e813c4e766ae5e2ce2b210 (patch)
tree12837468397b4d4ff951f473a2258b24ccd1452e
parentd958391d29c3f78385bd097f8adea009303baf12 (diff)
[modules] Teach clang how to merge typedef over anonymous structs in C mode.
In C mode clang fails to merge the textually included definition with the one imported from a module. The C lookup rules fail to find the imported definition because its linkage is internal in non C++ mode. This patch reinstates some of the ODR merging rules for typedefs of anonymous tags for languages other than C++. Patch by Raphael Isemann and me (D34510). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306964 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/Decl.cpp3
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--test/Index/usrs.m2
3 files changed, 4 insertions, 6 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 267c6992af..24d9983912 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1259,8 +1259,7 @@ 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 (!D->getASTContext().getLangOpts().CPlusPlus ||
- !cast<TypedefNameDecl>(D)
+ if (!cast<TypedefNameDecl>(D)
->getAnonDeclWithTypedefName(/*AnyRedecl*/true))
return LinkageInfo::none();
break;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index ef8a408f90..ab2661cd71 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1998,8 +1998,7 @@ 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 (S.getLangOpts().CPlusPlus &&
- OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) &&
+ if (OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) &&
Decl->getAnonDeclWithTypedefName())
continue;
}
@@ -2117,7 +2116,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
auto *OldTag = OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true);
auto *NewTag = New->getAnonDeclWithTypedefName();
NamedDecl *Hidden = nullptr;
- if (getLangOpts().CPlusPlus && OldTag && NewTag &&
+ if (OldTag && NewTag &&
OldTag->getCanonicalDecl() != NewTag->getCanonicalDecl() &&
!hasVisibleDefinition(OldTag, &Hidden)) {
// There is a definition of this tag, but it is not visible. Use it
diff --git a/test/Index/usrs.m b/test/Index/usrs.m
index 92c3a3fafe..d0a860e1af 100644
--- a/test/Index/usrs.m
+++ b/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:usrs.m@T@MyStruct Extent=[15:1 - 18:11]
+// CHECK: usrs.m c:@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]