diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 11 | ||||
-rw-r--r-- | clang/lib/AST/DeclSerialization.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/DeclarationName.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/StmtDumper.cpp | 9 |
6 files changed, 68 insertions, 4 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 0a3801a78f5..6bc02e0a972 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/Expr.h" @@ -146,6 +147,13 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch"); + // UsingDirectiveDecl's are not really NamedDecl's, and all have same name. + // We want to keep it, unless it nominates same namespace. + if (getKind() == Decl::UsingDirective) { + return cast<UsingDirectiveDecl>(this)->getNominatedNamespace() == + cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace(); + } + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) // For function declarations, we keep track of redeclarations. return FD->getPreviousDeclaration() == OldD; diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 6d0cda1fcea..21e1e0ce10c 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -499,8 +499,9 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { // [FirstMatch, LastMatch) contains the set of declarations that // have the same name as this declaration. Determine where the - // declaration D will be inserted into this range. - if (D->getIdentifierNamespace() == Decl::IDNS_Tag) + // declaration D will be inserted into this range. + if (D->getKind() == Decl::UsingDirective || + D->getIdentifierNamespace() == Decl::IDNS_Tag) InsertPos = LastMatch; else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag) InsertPos = LastMatch - 1; @@ -549,7 +550,9 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { } // Put this declaration into the appropriate slot. - if (D->getIdentifierNamespace() == Decl::IDNS_Tag || Pos->second.empty()) + if (D->getKind() == Decl::UsingDirective || + D->getIdentifierNamespace() == Decl::IDNS_Tag + || Pos->second.empty()) Pos->second.push_back(D); else if (Pos->second.back()->getIdentifierNamespace() == Decl::IDNS_Tag) { NamedDecl *TagD = Pos->second.back(); @@ -561,3 +564,12 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { (*Map)[D->getDeclName()].push_back(D); } } + +/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within +/// this context. +DeclContext::udir_iterator_range DeclContext::getUsingDirectives() const { + lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); + return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first), + reinterpret_cast<udir_iterator>(Result.second)); +} + diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 39ca8787914..5e1875ab652 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -363,3 +363,14 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, LanguageIDs Lang, bool Braces) { return new (C) LinkageSpecDecl(DC, L, Lang, Braces); } + +UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + SourceLocation NamespaceLoc, + SourceLocation IdentLoc, + NamespaceDecl *Used, + DeclContext *CommonAncestor) { + return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, IdentLoc, + Used, CommonAncestor); +} + diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index 5b881f21862..a10b229fcd6 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -203,6 +203,10 @@ void NamedDecl::EmitInRec(Serializer& S) const { case DeclarationName::CXXOperatorName: S.EmitInt(Name.getCXXOverloadedOperator()); break; + + case DeclarationName::CXXUsingDirective: + // No extra data to emit + break; } } @@ -242,6 +246,10 @@ void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) { Name = C.DeclarationNames.getCXXOperatorName(Op); break; } + + case DeclarationName::CXXUsingDirective: + Name = DeclarationName::getUsingDirectiveName(); + break; } } diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp index ae579c26fa8..0a6adef15b2 100644 --- a/clang/lib/AST/DeclarationName.cpp +++ b/clang/lib/AST/DeclarationName.cpp @@ -95,10 +95,13 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { case DeclarationNameExtra::CXXConversionFunction: return CXXConversionFunctionName; + case DeclarationNameExtra::CXXUsingDirective: + return CXXUsingDirective; + default: // Check if we have one of the CXXOperator* enumeration values. if (getExtra()->ExtraKindOrNumArgs < - DeclarationNameExtra::NUM_EXTRA_KINDS) + DeclarationNameExtra::CXXUsingDirective) return CXXOperatorName; return ObjCMultiArgSelector; @@ -165,6 +168,8 @@ std::string DeclarationName::getAsString() const { Result += Type.getAsString(); return Result; } + case CXXUsingDirective: + return "<using-directive>"; } assert(false && "Unexpected declaration name kind"); @@ -246,6 +251,17 @@ void DeclarationName::setFETokenInfo(void *T) { } } +DeclarationName DeclarationName::getUsingDirectiveName() { + // Single instance of DeclarationNameExtra for using-directive + static DeclarationNameExtra UDirExtra = + { DeclarationNameExtra::CXXUsingDirective }; + + uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); + Ptr |= StoredDeclarationNameExtra; + + return DeclarationName(Ptr); +} + DeclarationNameTable::DeclarationNameTable() { CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index 83313ed9be9..87a9f8e36b6 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -14,6 +14,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclCXX.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/Compiler.h" #include <cstdio> @@ -247,6 +248,14 @@ void StmtDumper::DumpDeclarator(Decl *D) { tagname = "<anonymous>"; fprintf(F, "\"%s %s;\"", TD->getKindName(), tagname); // FIXME: print tag bodies. + } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) { + // print using-directive decl (e.g. "using namespace x;") + const char *ns; + if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier()) + ns = II->getName(); + else + ns = "<anonymous>"; + fprintf(F, "\"%s %s;\"",UD->getDeclKindName(), ns); } else { assert(0 && "Unexpected decl"); } |