asutton/clang

[metaclass-def] Metaclass declarations are not added to the current declaration context

Closed this issue · 0 comments

Metaclass declarations are instead added to the current scope instead of the current declaration context at the end of semantic analysis. As a result, MetaclassDecl nodes are conspicuously missing from the AST.

DeclResult Sema::ActOnMetaclassDefinition(SourceLocation DLoc,
                                          SourceLocation IdLoc,
                                          IdentifierInfo *II, Stmt *Body) {
  assert(isa<CompoundStmt>(Body));
  assert(II);

  // Make sure that this definition doesn't conflict with existing tag
  // definitions.
  //
  // TODO: Should this be valid?
  //
  //    int x;
  //    $class x { }
  //
  // I think that pinning $class x to a tag name means that the variable
  // declaration will effectively hide $class x. We'd have to add $class to
  // the elaborated-type-specifier grammar.
  //
  // This is probably fine for now.
  LookupResult R(*this, II, IdLoc, LookupAnyName, ForRedeclaration);
  LookupName(R, CurScope);
  if (!R.empty()) {
    if (MetaclassDecl *D = R.getAsSingle<MetaclassDecl>()) {
      Diag(IdLoc, diag::err_redefinition) << II;
      Diag(D->getLocation(), diag::note_previous_definition);
    } else {
      Diag(IdLoc, diag::err_redefinition_different_kind) << II;
      if (Decl *D = R.getAsSingle<Decl>())
        Diag(D->getLocation(), diag::note_previous_definition);
    }
    return DeclResult();
  }

  MetaclassDecl *D =
      MetaclassDecl::Create(Context, CurContext, DLoc, IdLoc, II, Body);
  CurScope->AddDecl(D);
  IdResolver.AddDecl(D);

  return D;
}