From 788c62d1e87bfb596078817237f672a5f000999a Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sun, 21 Feb 2010 18:26:36 +0000 Subject: [PATCH] Implement AST importing for C++ namespaces. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96740 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTImporter.cpp | 68 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index f16bf0138c..aa0cb004ce 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -80,11 +80,12 @@ namespace { // Importing declarations bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC, DeclarationName &Name, - SourceLocation &Loc); + SourceLocation &Loc); void ImportDeclContext(DeclContext *FromDC); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); Decl *VisitDecl(Decl *D); + Decl *VisitNamespaceDecl(NamespaceDecl *D); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitEnumDecl(EnumDecl *D); Decl *VisitRecordDecl(RecordDecl *D); @@ -1405,6 +1406,71 @@ Decl *ASTNodeImporter::VisitDecl(Decl *D) { return 0; } +Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) { + // Import the major distinguishing characteristics of this namespace. + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) + return 0; + + NamespaceDecl *MergeWithNamespace = 0; + if (!Name) { + // This is an anonymous namespace. Adopt an existing anonymous + // namespace if we can. + // FIXME: Not testable. + if (TranslationUnitDecl *TU = dyn_cast(DC)) + MergeWithNamespace = TU->getAnonymousNamespace(); + else + MergeWithNamespace = cast(DC)->getAnonymousNamespace(); + } else { + llvm::SmallVector ConflictingDecls; + for (DeclContext::lookup_result Lookup = DC->lookup(Name); + Lookup.first != Lookup.second; + ++Lookup.first) { + if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_Ordinary)) + continue; + + if (NamespaceDecl *FoundNS = dyn_cast(*Lookup.first)) { + MergeWithNamespace = FoundNS; + ConflictingDecls.clear(); + break; + } + + ConflictingDecls.push_back(*Lookup.first); + } + + if (!ConflictingDecls.empty()) { + Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary, + ConflictingDecls.data(), + ConflictingDecls.size()); + } + } + + // Create the "to" namespace, if needed. + NamespaceDecl *ToNamespace = MergeWithNamespace; + if (!ToNamespace) { + ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, Loc, + Name.getAsIdentifierInfo()); + ToNamespace->setLexicalDeclContext(LexicalDC); + LexicalDC->addDecl(ToNamespace); + + // If this is an anonymous namespace, register it as the anonymous + // namespace within its context. + if (!Name) { + if (TranslationUnitDecl *TU = dyn_cast(DC)) + TU->setAnonymousNamespace(ToNamespace); + else + cast(DC)->setAnonymousNamespace(ToNamespace); + } + } + Importer.Imported(D, ToNamespace); + + ImportDeclContext(D); + + return ToNamespace; +} + Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) { // Import the major distinguishing characteristics of this typedef. DeclContext *DC, *LexicalDC; -- 2.40.0