diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-10 02:20:15 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-10 02:20:15 +0000 |
commit | ca40f9b39a8d4dda199741acb4d4e2e4f2548bfd (patch) | |
tree | 09659c2af0ccbf056f8452dab7e45d141fb47533 /clang/lib/Sema/SemaDecl.cpp | |
parent | 502dca7bb0ec97109c9ccf6bbf97d23aab89b7c3 (diff) | |
download | bcm5719-llvm-ca40f9b39a8d4dda199741acb4d4e2e4f2548bfd.tar.gz bcm5719-llvm-ca40f9b39a8d4dda199741acb4d4e2e4f2548bfd.zip |
[modules] When considering merging a newly-declared typedef into an imported
one, perform the import if the types match even if the imported declaration is
hidden. Otherwise, NamedDecl::declarationReplaces will drop one of the name
lookup entries, making the typedef effectively inaccessible from one of the
modules that declared it.
llvm-svn: 215306
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5f65593aa83..85c88a3f576 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1725,6 +1725,43 @@ static void filterNonConflictingPreviousDecls(ASTContext &context, filter.done(); } +/// Typedef declarations don't have linkage, but they still denote the same +/// entity if their types are the same. +/// FIXME: This is notionally doing the same thing as ASTReaderDecl's +/// isSameEntity. +static void filterNonConflictingPreviousTypedefDecls(ASTContext &Context, + TypedefNameDecl *Decl, + LookupResult &Previous) { + // This is only interesting when modules are enabled. + if (!Context.getLangOpts().Modules) + return; + + // Empty sets are uninteresting. + if (Previous.empty()) + return; + + LookupResult::Filter Filter = Previous.makeFilter(); + while (Filter.hasNext()) { + NamedDecl *Old = Filter.next(); + + // Non-hidden declarations are never ignored. + if (!Old->isHidden()) + continue; + + // Declarations of the same entity are not ignored, even if they have + // different linkages. + if (auto *OldTD = dyn_cast<TypedefNameDecl>(Old)) + if (Context.hasSameType(OldTD->getUnderlyingType(), + Decl->getUnderlyingType())) + continue; + + if (!Old->isExternallyVisible()) + Filter.erase(); + } + + Filter.done(); +} + bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) { QualType OldType; if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) @@ -4835,7 +4872,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD, // in an outer scope, it isn't the same thing. FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false, /*AllowInlineNamespace*/false); - filterNonConflictingPreviousDecls(Context, NewTD, Previous); + filterNonConflictingPreviousTypedefDecls(Context, NewTD, Previous); if (!Previous.empty()) { Redeclaration = true; MergeTypedefNameDecl(NewTD, Previous); |