 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
0.0% |
0 / 32 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
0.0% |
0 / 32 |
| |
|
Line Coverage: |
0.0% |
0 / 86 |
| |
 |
|
 |
1 : //===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===//
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 : // This file implements the generation and use of USRs from CXEntities.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "CIndexer.h"
15 : #include "CXCursor.h"
16 : #include "clang/AST/DeclVisitor.h"
17 : #include "llvm/ADT/SmallString.h"
18 : #include "llvm/Support/raw_ostream.h"
19 :
20 : //===----------------------------------------------------------------------===//
21 : // USR generation.
22 : //===----------------------------------------------------------------------===//
23 :
24 : namespace {
25 : class USRGenerator : public DeclVisitor<USRGenerator> {
26 : llvm::raw_ostream &Out;
27 : bool IgnoreResults;
28 : public:
29 0: USRGenerator(llvm::raw_ostream &out) : Out(out), IgnoreResults(false) {}
30 :
31 0: bool ignoreResults() const { return IgnoreResults; }
32 :
33 : void VisitBlockDecl(BlockDecl *D);
34 : void VisitDeclContext(DeclContext *D);
35 : void VisitFieldDecl(FieldDecl *D);
36 : void VisitFunctionDecl(FunctionDecl *D);
37 : void VisitNamedDecl(NamedDecl *D);
38 : void VisitNamespaceDecl(NamespaceDecl *D);
39 : void VisitObjCContainerDecl(ObjCContainerDecl *CD);
40 : void VisitObjCMethodDecl(ObjCMethodDecl *MD);
41 : void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
42 : void VisitTagDecl(TagDecl *D);
43 : void VisitTypedefDecl(TypedefDecl *D);
44 : };
45 : } // end anonymous namespace
46 :
47 0: void USRGenerator::VisitBlockDecl(BlockDecl *D) {
48 0: VisitDeclContext(D->getDeclContext());
49 : // FIXME: Better support for anonymous blocks.
50 0: Out << "@B^anon";
51 0: }
52 :
53 0: void USRGenerator::VisitDeclContext(DeclContext *DC) {
0: branch 1 not taken
0: branch 2 not taken
54 0: if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
55 0: Visit(D);
56 0: }
57 :
58 0: void USRGenerator::VisitFieldDecl(FieldDecl *D) {
59 0: const std::string &s = D->getNameAsString();
0: branch 1 not taken
0: branch 2 not taken
60 0: if (s.empty()) {
61 : // Bit fields can be anonymous.
62 0: IgnoreResults = true;
63 0: return;
64 : }
65 0: VisitDeclContext(D->getDeclContext());
0: branch 3 not taken
0: branch 4 not taken
66 0: Out << "@^FI^" << s;
67 : }
68 :
69 0: void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
70 0: VisitDeclContext(D->getDeclContext());
71 0: Out << "@F^" << D->getNameAsString();
72 0: }
73 :
74 0: void USRGenerator::VisitNamedDecl(NamedDecl *D) {
75 0: VisitDeclContext(D->getDeclContext());
76 0: const std::string &s = D->getNameAsString();
77 : // assert(!s.empty());
78 0: Out << "@^" << s;
79 0: }
80 :
81 0: void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
82 0: VisitDeclContext(D->getDeclContext());
83 0: Out << "@N^" << D->getNameAsString();
84 0: }
85 :
86 0: void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
87 0: Visit(cast<Decl>(D->getDeclContext()));
0: branch 1 not taken
0: branch 2 not taken
88 0: Out << (D->isInstanceMethod() ? "(im)" : "(cm)");
89 0: Out << DeclarationName(D->getSelector()).getAsString();
90 0: }
91 :
92 0: void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
93 0: switch (D->getKind()) {
94 : default:
95 0: assert(false && "Invalid ObjC container.");
96 : case Decl::ObjCInterface:
97 : case Decl::ObjCImplementation:
98 0: Out << "objc(cs)" << D->getName();
99 0: break;
100 : case Decl::ObjCCategory: {
101 0: ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
102 : Out << "objc(cy)" << CD->getClassInterface()->getName()
103 0: << '^' << CD->getName();
104 0: break;
105 : }
106 : case Decl::ObjCCategoryImpl: {
107 0: ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
108 : Out << "objc(cy)" << CD->getClassInterface()->getName()
109 0: << '^' << CD->getName();
110 0: break;
111 : }
112 : case Decl::ObjCProtocol:
113 0: Out << "objc(pl)" << cast<ObjCProtocolDecl>(D)->getName();
114 : break;
115 : }
116 0: }
117 :
118 0: void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
119 0: Visit(cast<Decl>(D->getDeclContext()));
120 0: Out << "(py)" << D->getName();
121 0: }
122 :
123 0: void USRGenerator::VisitTagDecl(TagDecl *D) {
124 0: VisitDeclContext(D->getDeclContext());
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
125 0: switch (D->getTagKind()) {
126 0: case TagDecl::TK_struct: Out << "@S^"; break;
127 0: case TagDecl::TK_class: Out << "@C^"; break;
128 0: case TagDecl::TK_union: Out << "@U^"; break;
129 0: case TagDecl::TK_enum: Out << "@E^"; break;
130 : }
131 :
132 : // FIXME: Better support for anonymous structures and enums.
133 0: const std::string &s = D->getNameAsString();
0: branch 1 not taken
0: branch 2 not taken
134 0: if (s.empty()) {
0: branch 1 not taken
0: branch 2 not taken
135 0: if (TypedefDecl *TD = D->getTypedefForAnonDecl())
136 0: Out << "^anontd^" << TD->getNameAsString();
137 : else
138 0: Out << "^anon";
139 : }
140 : else
141 0: Out << s;
142 0: }
143 :
144 0: void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
145 0: DeclContext *DC = D->getDeclContext();
0: branch 1 not taken
0: branch 2 not taken
146 0: if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
147 0: Visit(DCN);
148 0: Out << "typedef@" << D->getName();
149 0: }
150 :
151 : // FIXME: This is a skeleton implementation. It will be overhauled.
152 0: static CXString ConstructUSR(Decl *D) {
153 0: llvm::SmallString<1024> StrBuf;
154 : {
155 0: llvm::raw_svector_ostream Out(StrBuf);
156 0: USRGenerator UG(Out);
157 0: UG.Visit(static_cast<Decl*>(D));
0: branch 1 not taken
0: branch 2 not taken
158 0: if (UG.ignoreResults())
0: branch 2 not taken
0: branch 3 not taken
159 0: return CIndexer::createCXString(NULL);
160 : }
161 :
0: branch 1 not taken
0: branch 2 not taken
162 0: if (StrBuf.empty())
163 0: return CIndexer::createCXString(NULL);
164 :
165 : // Return a copy of the string that must be disposed by the caller.
166 0: return CIndexer::createCXString(StrBuf.c_str(), true);
167 : }
168 :
169 :
170 : extern "C" {
171 :
172 0: CXString clang_getCursorUSR(CXCursor C) {
0: branch 1 not taken
0: branch 2 not taken
173 0: if (Decl *D = cxcursor::getCursorDecl(C))
174 0: return ConstructUSR(D);
175 :
176 0: return CIndexer::createCXString(NULL);
177 : }
178 :
179 : } // end extern "C"
Generated: 2010-02-10 01:31 by zcov