Add LLVM runtime checks to build path
[clang/acc.git] / lib / Index / Entity.cpp
blob7a6c05c416a4e45af92f7785c603f190f2b1f1b2
1 //===--- Entity.cpp - Cross-translation-unit "token" for decls ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Entity is a ASTContext-independent way to refer to declarations that are
11 // visible across translation units.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Index/Entity.h"
16 #include "clang/Index/Program.h"
17 #include "ProgramImpl.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/DeclVisitor.h"
21 using namespace clang;
22 using namespace idx;
24 // FIXME: Entity is really really basic currently, mostly written to work
25 // on variables and functions. Should support types and other decls eventually..
28 //===----------------------------------------------------------------------===//
29 // EntityGetter
30 //===----------------------------------------------------------------------===//
32 namespace clang {
33 namespace idx {
35 /// \brief Gets the Entity associated with a Decl.
36 class EntityGetter : public DeclVisitor<EntityGetter, Entity *> {
37 ProgramImpl &Prog;
39 public:
40 EntityGetter(ProgramImpl &prog) : Prog(prog) { }
42 Entity *get(Entity *Parent, DeclarationName Name);
44 Entity *VisitNamedDecl(NamedDecl *D);
45 Entity *VisitVarDecl(VarDecl *D);
46 Entity *VisitFunctionDecl(FunctionDecl *D);
52 Entity *EntityGetter::get(Entity *Parent, DeclarationName Name) {
53 // FIXME: Only works for DeclarationNames that are identifiers.
55 if (!Name.isIdentifier())
56 return 0;
58 IdentifierInfo *II = Name.getAsIdentifierInfo();
59 if (!II)
60 return 0;
62 ProgramImpl::IdEntryTy *Id =
63 &Prog.getIdents().GetOrCreateValue(II->getName(),
64 II->getName() + II->getLength());
66 llvm::FoldingSetNodeID ID;
67 Entity::Profile(ID, Parent, Id);
69 ProgramImpl::EntitySetTy &Entities = Prog.getEntities();
70 void *InsertPos = 0;
71 if (Entity *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
72 return Ent;
74 void *Buf = Prog.Allocate(sizeof(Entity));
75 Entity *New = new (Buf) Entity(Parent, Id);
76 Entities.InsertNode(New, InsertPos);
77 return New;
80 Entity *EntityGetter::VisitNamedDecl(NamedDecl *D) {
81 // FIXME: Function declarations that are inside functions ?
82 if (!D->getDeclContext()->isFileContext())
83 return 0;
85 Entity *Parent = Visit(cast<Decl>(D->getDeclContext()));
86 return get(Parent, D->getDeclName());
89 Entity *EntityGetter::VisitVarDecl(VarDecl *D) {
90 // If it's static it cannot be referred to by another translation unit.
91 if (D->getStorageClass() == VarDecl::Static)
92 return 0;
94 return VisitNamedDecl(D);
97 Entity *EntityGetter::VisitFunctionDecl(FunctionDecl *D) {
98 // If it's static it cannot be refered to by another translation unit.
99 if (D->getStorageClass() == FunctionDecl::Static)
100 return 0;
102 return VisitNamedDecl(D);
105 //===----------------------------------------------------------------------===//
106 // Entity Implementation
107 //===----------------------------------------------------------------------===//
109 /// \brief Find the Decl that can be referred to by this entity.
110 Decl *Entity::getDecl(ASTContext &AST) {
111 DeclContext *DC =
112 Parent == 0 ? AST.getTranslationUnitDecl()
113 : cast<DeclContext>(Parent->getDecl(AST));
114 if (!DC)
115 return 0; // Couldn't get the parent context.
117 ProgramImpl::IdEntryTy *Entry = static_cast<ProgramImpl::IdEntryTy *>(Id);
118 IdentifierInfo &II = AST.Idents.get(Entry->getKeyData());
120 DeclContext::lookup_result Res = DC->lookup(DeclarationName(&II));
121 for (DeclContext::lookup_iterator I = Res.first, E = Res.second; I!=E; ++I) {
122 if (!isa<TagDecl>(*I))
123 return *I;
126 return 0; // Failed to find a decl using this Entity.
129 std::string Entity::getPrintableName(ASTContext &Ctx) {
130 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl(Ctx))) {
131 return ND->getNameAsString();
133 return std::string();
136 /// \brief Get an Entity associated with the given Decl.
137 /// \returns Null if an Entity cannot refer to this Decl.
138 Entity *Entity::get(Decl *D, Program &Prog) {
139 assert(D && "Passed null Decl");
140 ProgramImpl &Impl = *static_cast<ProgramImpl*>(Prog.Impl);
141 return EntityGetter(Impl).Visit(D);