diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-01-06 03:52:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-01-06 03:52:10 +0000 |
commit | 26dfbace823d7febcf2ce1fc57e5bb90e1276b61 (patch) | |
tree | a1b150855156f7f22565575fc6df78d16c3b0d29 /clang/lib/Sema/SemaDecl.cpp | |
parent | 3ec882feed9c5293075bc7a4f286ddccc977198a (diff) | |
download | bcm5719-llvm-26dfbace823d7febcf2ce1fc57e5bb90e1276b61.tar.gz bcm5719-llvm-26dfbace823d7febcf2ce1fc57e5bb90e1276b61.zip |
[modules] When a tag type that was imported from a module is referenced via an
elaborated-type-specifier, create a declaration of it to track that the current
module makes it visible too.
llvm-svn: 256907
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a41faa3880d..f27fb2b1071 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12277,16 +12277,35 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (!Invalid) { // If this is a use, just return the declaration we found, unless // we have attributes. - - // FIXME: In the future, return a variant or some other clue - // for the consumer of this Decl to know it doesn't own it. - // For our current ASTs this shouldn't be a problem, but will - // need to be changed with DeclGroups. - if (!Attr && - ((TUK == TUK_Reference && - (!PrevTagDecl->getFriendObjectKind() || getLangOpts().MicrosoftExt)) - || TUK == TUK_Friend)) - return PrevTagDecl; + if (TUK == TUK_Reference || TUK == TUK_Friend) { + if (Attr) { + // FIXME: Diagnose these attributes. For now, we create a new + // declaration to hold them. + } else if (TUK == TUK_Reference && + (PrevTagDecl->getFriendObjectKind() == + Decl::FOK_Undeclared || + getOwningModule(PrevDecl) != + PP.getModuleContainingLocation(KWLoc)) && + SS.isEmpty()) { + // This declaration is a reference to an existing entity, but + // has different visibility from that entity: it either makes + // a friend visible or it makes a type visible in a new module. + // In either case, create a new declaration. We only do this if + // the declaration would have meant the same thing if no prior + // declaration were found, that is, if it was found in the same + // scope where we would have injected a declaration. + DeclContext *InjectedDC = CurContext; + while (!InjectedDC->isFileContext() && + !InjectedDC->isFunctionOrMethod()) + InjectedDC = InjectedDC->getParent(); + if (!InjectedDC->getRedeclContext()->Equals( + PrevDecl->getDeclContext()->getRedeclContext())) + return PrevTagDecl; + // This is in the injected scope, create a new declaration. + } else { + return PrevTagDecl; + } + } // Diagnose attempts to redefine a tag. if (TUK == TUK_Definition) { |