diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/CallGraph.cpp | 12 | ||||
-rw-r--r-- | lib/Index/Entity.cpp | 124 | ||||
-rw-r--r-- | lib/Index/EntityImpl.h | 63 | ||||
-rw-r--r-- | lib/Index/IndexProvider.cpp | 18 | ||||
-rw-r--r-- | lib/Index/Program.cpp | 8 | ||||
-rw-r--r-- | lib/Index/ProgramImpl.h | 12 |
6 files changed, 169 insertions, 68 deletions
diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp index cf8f6205ab..2530fc0ad7 100644 --- a/lib/Analysis/CallGraph.cpp +++ b/lib/Analysis/CallGraph.cpp @@ -25,12 +25,12 @@ class CGBuilder : public StmtVisitor<CGBuilder> { CallGraph &G; FunctionDecl *FD; - Entity *CallerEnt; + Entity CallerEnt; CallGraphNode *CallerNode; public: - CGBuilder(CallGraph &g, FunctionDecl *fd, Entity *E, CallGraphNode *N) + CGBuilder(CallGraph &g, FunctionDecl *fd, Entity E, CallGraphNode *N) : G(g), FD(fd), CallerEnt(E), CallerNode(N) {} void VisitStmt(Stmt *S) { VisitChildren(S); } @@ -47,7 +47,7 @@ public: void CGBuilder::VisitCallExpr(CallExpr *CE) { if (FunctionDecl *CalleeDecl = CE->getDirectCallee()) { - Entity *Ent = Entity::get(CalleeDecl, G.getProgram()); + Entity Ent = Entity::get(CalleeDecl, G.getProgram()); CallGraphNode *CalleeNode = G.getOrInsertFunction(Ent); Decl *Parent = ASTLocation::FindImmediateParent(FD, CE); @@ -75,7 +75,7 @@ void CallGraph::addTU(ASTUnit &AST) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { if (FD->isThisDeclarationADefinition()) { // Set caller's ASTContext. - Entity *Ent = Entity::get(FD, Prog); + Entity Ent = Entity::get(FD, Prog); CallGraphNode *Node = getOrInsertFunction(Ent); CallerCtx[Node] = &Ctx; @@ -86,7 +86,7 @@ void CallGraph::addTU(ASTUnit &AST) { } } -CallGraphNode *CallGraph::getOrInsertFunction(Entity *F) { +CallGraphNode *CallGraph::getOrInsertFunction(Entity F) { CallGraphNode *&Node = FunctionMap[F]; if (Node) return Node; @@ -98,7 +98,7 @@ void CallGraph::print(llvm::raw_ostream &os) { for (iterator I = begin(), E = end(); I != E; ++I) { if (I->second->hasCallee()) { ASTContext &Ctx = *CallerCtx[I->second]; - os << "function: " << I->first->getPrintableName(Ctx).c_str() + os << "function: " << I->first.getPrintableName(Ctx).c_str() << " calls:\n"; for (CallGraphNode::iterator CI = I->second->begin(), CE = I->second->end(); CI != CE; ++CI) { diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp index 7a6c05c416..feed3e4c80 100644 --- a/lib/Index/Entity.cpp +++ b/lib/Index/Entity.cpp @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// -#include "clang/Index/Entity.h" -#include "clang/Index/Program.h" +#include "EntityImpl.h" #include "ProgramImpl.h" +#include "clang/Index/Program.h" #include "clang/AST/Decl.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclVisitor.h" @@ -33,99 +33,123 @@ namespace clang { namespace idx { /// \brief Gets the Entity associated with a Decl. -class EntityGetter : public DeclVisitor<EntityGetter, Entity *> { +class EntityGetter : public DeclVisitor<EntityGetter, Entity> { ProgramImpl &Prog; - + public: EntityGetter(ProgramImpl &prog) : Prog(prog) { } - Entity *get(Entity *Parent, DeclarationName Name); - - Entity *VisitNamedDecl(NamedDecl *D); - Entity *VisitVarDecl(VarDecl *D); - Entity *VisitFunctionDecl(FunctionDecl *D); + Entity VisitNamedDecl(NamedDecl *D); + Entity VisitVarDecl(VarDecl *D); + Entity VisitFunctionDecl(FunctionDecl *D); }; } } -Entity *EntityGetter::get(Entity *Parent, DeclarationName Name) { +Entity EntityGetter::VisitNamedDecl(NamedDecl *D) { + Entity Parent; + if (!D->getDeclContext()->isTranslationUnit()) { + Parent = Visit(cast<Decl>(D->getDeclContext())); + // FIXME: Anonymous structs ? + if (Parent.isInvalid()) + return Entity(); + } + if (Parent.isValid() && Parent.isInternalToTU()) + return Entity(D); + // FIXME: Only works for DeclarationNames that are identifiers. + DeclarationName Name = D->getDeclName(); + if (!Name.isIdentifier()) - return 0; + return Entity(); IdentifierInfo *II = Name.getAsIdentifierInfo(); if (!II) - return 0; + return Entity(); - ProgramImpl::IdEntryTy *Id = + EntityImpl::IdEntryTy *Id = &Prog.getIdents().GetOrCreateValue(II->getName(), II->getName() + II->getLength()); - + unsigned IdNS = D->getIdentifierNamespace(); + llvm::FoldingSetNodeID ID; - Entity::Profile(ID, Parent, Id); - + EntityImpl::Profile(ID, Parent, Id, IdNS); + ProgramImpl::EntitySetTy &Entities = Prog.getEntities(); void *InsertPos = 0; - if (Entity *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos)) - return Ent; - - void *Buf = Prog.Allocate(sizeof(Entity)); - Entity *New = new (Buf) Entity(Parent, Id); - Entities.InsertNode(New, InsertPos); - return New; -} + if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos)) + return Entity(Ent); -Entity *EntityGetter::VisitNamedDecl(NamedDecl *D) { - // FIXME: Function declarations that are inside functions ? - if (!D->getDeclContext()->isFileContext()) - return 0; - - Entity *Parent = Visit(cast<Decl>(D->getDeclContext())); - return get(Parent, D->getDeclName()); + void *Buf = Prog.Allocate(sizeof(EntityImpl)); + EntityImpl *New = new (Buf) EntityImpl(Parent, Id, IdNS); + Entities.InsertNode(New, InsertPos); + + return Entity(New); } -Entity *EntityGetter::VisitVarDecl(VarDecl *D) { +Entity EntityGetter::VisitVarDecl(VarDecl *D) { // If it's static it cannot be referred to by another translation unit. if (D->getStorageClass() == VarDecl::Static) - return 0; + return Entity(D); return VisitNamedDecl(D); } -Entity *EntityGetter::VisitFunctionDecl(FunctionDecl *D) { +Entity EntityGetter::VisitFunctionDecl(FunctionDecl *D) { // If it's static it cannot be refered to by another translation unit. if (D->getStorageClass() == FunctionDecl::Static) - return 0; + return Entity(D); return VisitNamedDecl(D); } //===----------------------------------------------------------------------===// -// Entity Implementation +// EntityImpl Implementation //===----------------------------------------------------------------------===// -/// \brief Find the Decl that can be referred to by this entity. -Decl *Entity::getDecl(ASTContext &AST) { +Decl *EntityImpl::getDecl(ASTContext &AST) { DeclContext *DC = - Parent == 0 ? AST.getTranslationUnitDecl() - : cast<DeclContext>(Parent->getDecl(AST)); + Parent.isInvalid() ? AST.getTranslationUnitDecl() + : cast<DeclContext>(Parent.getDecl(AST)); if (!DC) return 0; // Couldn't get the parent context. - ProgramImpl::IdEntryTy *Entry = static_cast<ProgramImpl::IdEntryTy *>(Id); - IdentifierInfo &II = AST.Idents.get(Entry->getKeyData()); + IdentifierInfo &II = AST.Idents.get(Id->getKeyData()); DeclContext::lookup_result Res = DC->lookup(DeclarationName(&II)); for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) { - if (!isa<TagDecl>(*I)) + if ((*I)->getIdentifierNamespace() == IdNS) return *I; } return 0; // Failed to find a decl using this Entity. } +/// \brief Get an Entity associated with the given Decl. +/// \returns Null if an Entity cannot refer to this Decl. +Entity EntityImpl::get(Decl *D, ProgramImpl &Prog) { + assert(D && "Passed null Decl"); + return EntityGetter(Prog).Visit(D); +} + +//===----------------------------------------------------------------------===// +// Entity Implementation +//===----------------------------------------------------------------------===// + +/// \brief Find the Decl that can be referred to by this entity. +Decl *Entity::getDecl(ASTContext &AST) { + if (isInvalid()) + return 0; + + if (Decl *D = Val.dyn_cast<Decl *>()) + // Check that the passed AST is actually the one that this Decl belongs to. + return (&D->getASTContext() == &AST) ? D : 0; + + return Val.get<EntityImpl *>()->getDecl(AST); +} + std::string Entity::getPrintableName(ASTContext &Ctx) { if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl(Ctx))) { return ND->getNameAsString(); @@ -135,8 +159,14 @@ std::string Entity::getPrintableName(ASTContext &Ctx) { /// \brief Get an Entity associated with the given Decl. /// \returns Null if an Entity cannot refer to this Decl. -Entity *Entity::get(Decl *D, Program &Prog) { - assert(D && "Passed null Decl"); - ProgramImpl &Impl = *static_cast<ProgramImpl*>(Prog.Impl); - return EntityGetter(Impl).Visit(D); +Entity Entity::get(Decl *D, Program &Prog) { + if (D == 0) + return Entity(); + ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl); + return EntityImpl::get(D, ProgImpl); +} + +unsigned +llvm::DenseMapInfo<Entity>::getHashValue(Entity E) { + return DenseMapInfo<void*>::getHashValue(E.getAsOpaquePtr()); } diff --git a/lib/Index/EntityImpl.h b/lib/Index/EntityImpl.h new file mode 100644 index 0000000000..334dcfb4ec --- /dev/null +++ b/lib/Index/EntityImpl.h @@ -0,0 +1,63 @@ +//===--- EntityImpl.h - Internal Entity implementation---------*- C++ -*-=====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Internal implementation for the Entity class +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_ENTITYIMPL_H +#define LLVM_CLANG_INDEX_ENTITYIMPL_H + +#include "clang/Index/Entity.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/StringSet.h" + +namespace clang { + +namespace idx { + class ProgramImpl; + +class EntityImpl : public llvm::FoldingSetNode { +public: + typedef llvm::StringMapEntry<char> IdEntryTy; + +private: + Entity Parent; + IdEntryTy *Id; + + /// \brief Identifier namespace. + unsigned IdNS; + +public: + EntityImpl(Entity parent, IdEntryTy *id, unsigned idNS) + : Parent(parent), Id(id), IdNS(idNS) { } + + /// \brief Find the Decl that can be referred to by this entity. + Decl *getDecl(ASTContext &AST); + + /// \brief Get an Entity associated with the given Decl. + /// \returns Null if an Entity cannot refer to this Decl. + static Entity get(Decl *D, ProgramImpl &Prog); + + void Profile(llvm::FoldingSetNodeID &ID) const { + Profile(ID, Parent, Id, IdNS); + } + static void Profile(llvm::FoldingSetNodeID &ID, Entity Parent, IdEntryTy *Id, + unsigned IdNS) { + ID.AddPointer(Parent.getAsOpaquePtr()); + ID.AddPointer(Id); + ID.AddInteger(IdNS); + } +}; + +} // namespace idx + +} // namespace clang + +#endif diff --git a/lib/Index/IndexProvider.cpp b/lib/Index/IndexProvider.cpp index 074a83d9a6..38317eb9c2 100644 --- a/lib/Index/IndexProvider.cpp +++ b/lib/Index/IndexProvider.cpp @@ -13,6 +13,7 @@ #include "clang/Index/IndexProvider.h" #include "clang/Index/Program.h" +#include "clang/Index/Entity.h" #include "clang/Index/EntityHandler.h" #include "clang/Index/TranslationUnit.h" using namespace clang; @@ -25,7 +26,10 @@ class IndexProvider::Indexer : public EntityHandler { public: Indexer(TranslationUnit *tu, MapTy &map) : TU(tu), Map(map) { } - virtual void HandleEntity(Entity *Ent) { + virtual void HandleEntity(Entity Ent) { + if (Ent.isInternalToTU()) + return; + MapTy::iterator I = Map.find(Ent); if (I != Map.end()) { I->second.insert(TU); @@ -41,25 +45,27 @@ void IndexProvider::IndexAST(TranslationUnit *TU) { Prog.FindEntities(TU->getASTContext(), &Idx); } +static IndexProvider::TUSetTy EmptySet; + IndexProvider::translation_unit_iterator -IndexProvider::translation_units_begin(Entity *Ent) const { +IndexProvider::translation_units_begin(Entity Ent) const { MapTy::iterator I = Map.find(Ent); if (I == Map.end()) - return translation_unit_iterator(0); + return EmptySet.begin(); return I->second.begin(); } IndexProvider::translation_unit_iterator -IndexProvider::translation_units_end(Entity *Ent) const { +IndexProvider::translation_units_end(Entity Ent) const { MapTy::iterator I = Map.find(Ent); if (I == Map.end()) - return translation_unit_iterator(0); + return EmptySet.end(); return I->second.end(); } -bool IndexProvider::translation_units_empty(Entity *Ent) const { +bool IndexProvider::translation_units_empty(Entity Ent) const { MapTy::iterator I = Map.find(Ent); if (I == Map.end()) return true; diff --git a/lib/Index/Program.cpp b/lib/Index/Program.cpp index 807d18c699..73759dc95c 100644 --- a/lib/Index/Program.cpp +++ b/lib/Index/Program.cpp @@ -25,6 +25,8 @@ using namespace idx; EntityHandler::~EntityHandler() { } TranslationUnit::~TranslationUnit() { } +void EntityHandler::HandleEntity(Entity Ent) { } + Program::Program() : Impl(new ProgramImpl()) { } Program::~Program() { @@ -34,8 +36,10 @@ Program::~Program() { static void FindEntitiesInDC(DeclContext *DC, Program &Prog, EntityHandler *Handler) { for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { - Entity *Ent = Entity::get(*I, Prog); - if (Ent) + if (I->getLocation().isInvalid()) + continue; + Entity Ent = Entity::get(*I, Prog); + if (Ent.isValid()) Handler->HandleEntity(Ent); if (DeclContext *SubDC = dyn_cast<DeclContext>(*I)) FindEntitiesInDC(SubDC, Prog, Handler); diff --git a/lib/Index/ProgramImpl.h b/lib/Index/ProgramImpl.h index 52f153f1dc..39fc184677 100644 --- a/lib/Index/ProgramImpl.h +++ b/lib/Index/ProgramImpl.h @@ -14,8 +14,7 @@ #ifndef LLVM_CLANG_INDEX_PROGRAMIMPL_H #define LLVM_CLANG_INDEX_PROGRAMIMPL_H -#include "clang/Index/Entity.h" -#include "llvm/ADT/StringSet.h" +#include "EntityImpl.h" namespace clang { @@ -24,11 +23,10 @@ namespace idx { class ProgramImpl { public: - typedef llvm::FoldingSet<Entity> EntitySetTy; - typedef llvm::StringMapEntry<char> IdEntryTy; - + typedef llvm::FoldingSet<EntityImpl> EntitySetTy; + private: - llvm::FoldingSet<Entity> Entities; + EntitySetTy Entities; llvm::StringSet<> Idents; llvm::BumpPtrAllocator BumpAlloc; @@ -38,7 +36,7 @@ private: public: ProgramImpl() { } - llvm::FoldingSet<Entity> &getEntities() { return Entities; } + EntitySetTy &getEntities() { return Entities; } llvm::StringSet<> &getIdents() { return Idents; } void *Allocate(unsigned Size, unsigned Align = 8) { |