 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
48.2% |
27 / 56 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
64.3% |
36 / 56 |
| |
|
Line Coverage: |
75.8% |
69 / 91 |
| |
 |
|
 |
1 : //===--- MinimalAction.cpp - Implement the MinimalAction class ------------===//
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 MinimalAction interface.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Parse/Parser.h"
15 : #include "clang/Parse/DeclSpec.h"
16 : #include "clang/Parse/Scope.h"
17 : #include "clang/Basic/TargetInfo.h"
18 : #include "llvm/Support/Allocator.h"
19 : #include "llvm/Support/RecyclingAllocator.h"
20 : #include "llvm/Support/raw_ostream.h"
21 : using namespace clang;
22 :
23 : /// Out-of-line virtual destructor to provide home for ActionBase class.
2251: branch 0 taken
2251: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
2251: branch 7 taken
24 2251: ActionBase::~ActionBase() {}
25 :
26 : /// Out-of-line virtual destructor to provide home for Action class.
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 9 not taken
2251: branch 10 taken
27 2251: Action::~Action() {}
28 :
29 : // Defined out-of-line here because of dependecy on AttributeList
30 : Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope,
31 : SourceLocation UsingLoc,
32 : SourceLocation NamespcLoc,
33 : const CXXScopeSpec &SS,
34 : SourceLocation IdentLoc,
35 : IdentifierInfo *NamespcName,
36 0: AttributeList *AttrList) {
37 :
38 : // FIXME: Parser seems to assume that Action::ActOn* takes ownership over
39 : // passed AttributeList, however other actions don't free it, is it
40 : // temporary state or bug?
0: branch 0 not taken
0: branch 1 not taken
41 0: delete AttrList;
42 0: return DeclPtrTy();
43 : }
44 :
45 : // Defined out-of-line here because of dependency on AttributeList
46 : Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope,
47 : AccessSpecifier AS,
48 : bool HasUsingKeyword,
49 : SourceLocation UsingLoc,
50 : const CXXScopeSpec &SS,
51 : UnqualifiedId &Name,
52 : AttributeList *AttrList,
53 : bool IsTypeName,
54 0: SourceLocation TypenameLoc) {
55 :
56 : // FIXME: Parser seems to assume that Action::ActOn* takes ownership over
57 : // passed AttributeList, however other actions don't free it, is it
58 : // temporary state or bug?
0: branch 0 not taken
0: branch 1 not taken
59 0: delete AttrList;
60 0: return DeclPtrTy();
61 : }
62 :
63 :
64 0: void PrettyStackTraceActionsDecl::print(llvm::raw_ostream &OS) const {
0: branch 1 not taken
0: branch 2 not taken
65 0: if (Loc.isValid()) {
66 0: Loc.print(OS, SM);
67 0: OS << ": ";
68 : }
69 0: OS << Message;
70 :
71 0: std::string Name = Actions.getDeclName(TheDecl);
0: branch 1 not taken
0: branch 2 not taken
72 0: if (!Name.empty())
73 0: OS << " '" << Name << '\'';
74 :
75 0: OS << '\n';
76 0: }
77 :
78 : /// TypeNameInfo - A link exists here for each scope that an identifier is
79 : /// defined.
80 : namespace {
81 32: struct TypeNameInfo {
82 : TypeNameInfo *Prev;
83 : bool isTypeName;
84 :
85 63: TypeNameInfo(bool istypename, TypeNameInfo *prev) {
86 63: isTypeName = istypename;
87 63: Prev = prev;
88 63: }
89 : };
90 :
91 30: struct TypeNameInfoTable {
92 : llvm::RecyclingAllocator<llvm::BumpPtrAllocator, TypeNameInfo> Allocator;
93 :
94 63: void AddEntry(bool isTypename, IdentifierInfo *II) {
95 63: TypeNameInfo *TI = Allocator.Allocate<TypeNameInfo>();
63: branch 2 taken
0: branch 3 not taken
96 63: new (TI) TypeNameInfo(isTypename, II->getFETokenInfo<TypeNameInfo>());
97 63: II->setFETokenInfo(TI);
98 63: }
99 :
100 32: void DeleteEntry(TypeNameInfo *Entry) {
101 32: Entry->~TypeNameInfo();
102 32: Allocator.Deallocate(Entry);
103 32: }
104 : };
105 : }
106 :
107 85: static TypeNameInfoTable *getTable(void *TP) {
108 85: return static_cast<TypeNameInfoTable*>(TP);
109 : }
110 :
111 15: MinimalAction::MinimalAction(Preprocessor &pp)
112 15: : Idents(pp.getIdentifierTable()), PP(pp) {
113 15: TypeNameInfoTablePtr = new TypeNameInfoTable();
114 15: }
115 :
116 15: MinimalAction::~MinimalAction() {
13: branch 1 taken
0: branch 2 not taken
0: branch 6 not taken
0: branch 7 not taken
2: branch 11 taken
0: branch 12 not taken
117 15: delete getTable(TypeNameInfoTablePtr);
13: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 9 not taken
2: branch 10 taken
118 15: }
119 :
120 15: void MinimalAction::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
121 15: TUScope = S;
122 :
123 15: TypeNameInfoTable &TNIT = *getTable(TypeNameInfoTablePtr);
124 :
0: branch 2 not taken
15: branch 3 taken
125 15: if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
126 : // Install [u]int128_t for 64-bit targets.
127 0: TNIT.AddEntry(true, &Idents.get("__int128_t"));
128 0: TNIT.AddEntry(true, &Idents.get("__uint128_t"));
129 : }
130 :
6: branch 1 taken
9: branch 2 taken
131 15: if (PP.getLangOptions().ObjC1) {
132 : // Recognize the ObjC built-in type identifiers as types.
133 6: TNIT.AddEntry(true, &Idents.get("id"));
134 6: TNIT.AddEntry(true, &Idents.get("SEL"));
135 6: TNIT.AddEntry(true, &Idents.get("Class"));
136 6: TNIT.AddEntry(true, &Idents.get("Protocol"));
137 : }
138 15: }
139 :
140 : /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to
141 : /// determine whether the name is a type name (objc class name or typedef) or
142 : /// not in this scope.
143 : ///
144 : /// FIXME: Use the passed CXXScopeSpec for accurate C++ type checking.
145 : Action::TypeTy *
146 : MinimalAction::getTypeName(IdentifierInfo &II, SourceLocation Loc,
147 : Scope *S, const CXXScopeSpec *SS,
148 115: bool isClassName, TypeTy *ObjectType) {
62: branch 1 taken
53: branch 2 taken
149 115: if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>())
61: branch 0 taken
1: branch 1 taken
150 62: if (TI->isTypeName)
151 61: return TI;
152 54: return 0;
153 : }
154 :
155 : /// isCurrentClassName - Always returns false, because MinimalAction
156 : /// does not support C++ classes with constructors.
157 : bool MinimalAction::isCurrentClassName(const IdentifierInfo &, Scope *,
158 0: const CXXScopeSpec *) {
159 0: return false;
160 : }
161 :
162 : TemplateNameKind
163 : MinimalAction::isTemplateName(Scope *S,
164 : const CXXScopeSpec &SS,
165 : UnqualifiedId &Name,
166 : TypeTy *ObjectType,
167 : bool EnteringScope,
168 0: TemplateTy &TemplateDecl) {
169 0: return TNK_Non_template;
170 : }
171 :
172 : /// ActOnDeclarator - If this is a typedef declarator, we modify the
173 : /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
174 : /// popped.
175 : Action::DeclPtrTy
176 222: MinimalAction::ActOnDeclarator(Scope *S, Declarator &D) {
177 222: IdentifierInfo *II = D.getIdentifier();
178 :
179 : // If there is no identifier associated with this declarator, bail out.
0: branch 0 not taken
222: branch 1 taken
180 222: if (II == 0) return DeclPtrTy();
181 :
182 222: TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>();
183 : bool isTypeName =
184 222: D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef;
185 :
186 : // this check avoids creating TypeNameInfo objects for the common case.
187 : // It does need to handle the uncommon case of shadowing a typedef name with a
188 : // non-typedef name. e.g. { typedef int a; a xx; { int a; } }
221: branch 0 taken
1: branch 1 taken
29: branch 2 taken
192: branch 3 taken
189 222: if (weCurrentlyHaveTypeInfo || isTypeName) {
190 : // Allocate and add the 'TypeNameInfo' "decl".
191 30: getTable(TypeNameInfoTablePtr)->AddEntry(isTypeName, II);
192 :
193 : // Remember that this needs to be removed when the scope is popped.
194 30: S->AddDecl(DeclPtrTy::make(II));
195 : }
196 222: return DeclPtrTy();
197 : }
198 :
199 : Action::DeclPtrTy
200 : MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
201 : IdentifierInfo *ClassName,
202 : SourceLocation ClassLoc,
203 : IdentifierInfo *SuperName,
204 : SourceLocation SuperLoc,
205 : const DeclPtrTy *ProtoRefs,
206 : unsigned NumProtocols,
207 : const SourceLocation *ProtoLocs,
208 : SourceLocation EndProtoLoc,
209 7: AttributeList *AttrList) {
210 : // Allocate and add the 'TypeNameInfo' "decl".
211 7: getTable(TypeNameInfoTablePtr)->AddEntry(true, ClassName);
212 7: return DeclPtrTy();
213 : }
214 :
215 : /// ActOnForwardClassDeclaration -
216 : /// Scope will always be top level file scope.
217 : Action::DeclPtrTy
218 : MinimalAction::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
219 : IdentifierInfo **IdentList,
220 : SourceLocation *IdentLocs,
221 2: unsigned NumElts) {
2: branch 0 taken
2: branch 1 taken
222 4: for (unsigned i = 0; i != NumElts; ++i) {
223 : // Allocate and add the 'TypeNameInfo' "decl".
224 2: getTable(TypeNameInfoTablePtr)->AddEntry(true, IdentList[i]);
225 :
226 : // Remember that this needs to be removed when the scope is popped.
227 2: TUScope->AddDecl(DeclPtrTy::make(IdentList[i]));
228 : }
229 2: return DeclPtrTy();
230 : }
231 :
232 : /// ActOnPopScope - When a scope is popped, if any typedefs are now
233 : /// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field.
234 16: void MinimalAction::ActOnPopScope(SourceLocation Loc, Scope *S) {
235 16: TypeNameInfoTable &Table = *getTable(TypeNameInfoTablePtr);
236 :
32: branch 4 taken
16: branch 5 taken
237 48: for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
238 : I != E; ++I) {
239 32: IdentifierInfo &II = *(*I).getAs<IdentifierInfo>();
240 32: TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>();
0: branch 0 not taken
32: branch 1 taken
241 32: assert(TI && "This decl didn't get pushed??");
242 :
32: branch 0 taken
0: branch 1 not taken
243 32: if (TI) {
244 32: TypeNameInfo *Next = TI->Prev;
245 32: Table.DeleteEntry(TI);
246 :
247 32: II.setFETokenInfo(Next);
248 : }
249 : }
250 16: }
Generated: 2010-02-10 01:31 by zcov