summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/Decl.cpp8
-rw-r--r--clang/lib/AST/DeclBase.cpp18
-rw-r--r--clang/lib/AST/DeclCXX.cpp11
-rw-r--r--clang/lib/AST/DeclSerialization.cpp8
-rw-r--r--clang/lib/AST/DeclarationName.cpp18
-rw-r--r--clang/lib/AST/StmtDumper.cpp9
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");
}
OpenPOWER on IntegriCloud