r257251 - [modules] If we're treating an elaborated-type-specifier as if it introduces a

NAKAMURA Takumi via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 8 23:24:39 PST 2016


Thanks. But a few C headers are complaining. Investigating.

http://lab.llvm.org:8011/builders/clang-x86_64-linux-selfhost-modules/builds/10380

On Sat, Jan 9, 2016 at 4:02 PM Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: rsmith
> Date: Sat Jan  9 00:58:48 2016
> New Revision: 257251
>
> URL: http://llvm.org/viewvc/llvm-project?rev=257251&view=rev
> Log:
> [modules] If we're treating an elaborated-type-specifier as if it
> introduces a
> tag (because the previous declaration was found in a different module),
> inject
> the tag into the appropriate scope (that is, the enclosing scope if we're
> in a
> function prototype scope in C++).
>
> Modified:
>     cfe/trunk/lib/Sema/SemaDecl.cpp
>     cfe/trunk/test/Modules/tag-injection.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=257251&r1=257250&r2=257251&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jan  9 00:58:48 2016
> @@ -11798,6 +11798,28 @@ static bool isAcceptableTagRedeclContext
>    return false;
>  }
>
> +/// Find the DeclContext in which a tag is implicitly declared if we see
> an
> +/// elaborated type specifier in the specified context, and lookup finds
> +/// nothing.
> +static DeclContext *getTagInjectionContext(DeclContext *DC) {
> +  while (!DC->isFileContext() && !DC->isFunctionOrMethod())
> +    DC = DC->getParent();
> +  return DC;
> +}
> +
> +/// Find the Scope in which a tag is implicitly declared if we see an
> +/// elaborated type specifier in the specified context, and lookup finds
> +/// nothing.
> +static Scope *getTagInjectionScope(Scope *S, const LangOptions &LangOpts)
> {
> +  while (S->isClassScope() ||
> +         (LangOpts.CPlusPlus &&
> +          S->isFunctionPrototypeScope()) ||
> +         ((S->getFlags() & Scope::DeclScope) == 0) ||
> +         (S->getEntity() && S->getEntity()->isTransparentContext()))
> +    S = S->getParent();
> +  return S;
> +}
> +
>  /// \brief This is invoked when we see 'struct foo' or 'struct {'.  In the
>  /// former case, Name will be non-null.  In the later case, Name will be
> null.
>  /// TagSpec indicates what kind of tag this is. TUK indicates whether
> this is a
> @@ -12114,16 +12136,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned
>        // Find the context where we'll be declaring the tag.
>        // FIXME: We would like to maintain the current DeclContext as the
>        // lexical context,
> -      while (!SearchDC->isFileContext() &&
> !SearchDC->isFunctionOrMethod())
> -        SearchDC = SearchDC->getParent();
> +      SearchDC = getTagInjectionContext(SearchDC);
>
>        // Find the scope where we'll be declaring the tag.
> -      while (S->isClassScope() ||
> -             (getLangOpts().CPlusPlus &&
> -              S->isFunctionPrototypeScope()) ||
> -             ((S->getFlags() & Scope::DeclScope) == 0) ||
> -             (S->getEntity() && S->getEntity()->isTransparentContext()))
> -        S = S->getParent();
> +      S = getTagInjectionScope(S, getLangOpts());
>      } else {
>        assert(TUK == TUK_Friend);
>        // C++ [namespace.memdef]p3:
> @@ -12293,14 +12309,13 @@ Decl *Sema::ActOnTag(Scope *S, unsigned
>                // 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()))
> +              if (!getTagInjectionContext(CurContext)
> +                       ->getRedeclContext()
> +
>  ->Equals(PrevDecl->getDeclContext()->getRedeclContext()))
>                  return PrevTagDecl;
> -              // This is in the injected scope, create a new declaration.
> +              // This is in the injected scope, create a new declaration
> in
> +              // that scope.
> +              S = getTagInjectionScope(S, getLangOpts());
>              } else {
>                return PrevTagDecl;
>              }
>
> Modified: cfe/trunk/test/Modules/tag-injection.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/tag-injection.cpp?rev=257251&r1=257250&r2=257251&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/Modules/tag-injection.cpp (original)
> +++ cfe/trunk/test/Modules/tag-injection.cpp Sat Jan  9 00:58:48 2016
> @@ -1,12 +1,15 @@
>  // RUN: rm -rf %t
>  // RUN: mkdir %t
> -// RUN: touch %t/a.h
> -// RUN: echo 'struct X {};' > %t/b.h
> +// RUN: echo 'struct tm;' > %t/a.h
> +// RUN: echo 'struct X {}; void foo(struct tm*);' > %t/b.h
>  // RUN: echo 'module X { module a { header "a.h" } module b { header
> "b.h" } }' > %t/x.modulemap
> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++
> -fmodule-map-file=%t/x.modulemap %s -I%t -verify -std=c++11
>  // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++
> -fmodule-map-file=%t/x.modulemap %s -I%t -verify
> -fmodules-local-submodule-visibility -std=c++11
>
>  #include "a.h"
>
> +using ::tm;
> +
>  struct A {
>    // This use of 'struct X' makes the declaration (but not definition) of
> X visible.
>    virtual void f(struct X *p);
>
>
> _______________________________________________
> 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/20160109/49f244fd/attachment.html>


More information about the cfe-commits mailing list