 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
24.9% |
49 / 197 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
56.3% |
111 / 197 |
| |
|
Line Coverage: |
33.4% |
119 / 356 |
| |
 |
|
 |
1 : //===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
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 defines the ASTImporter class which imports AST nodes from one
11 : // context into another context.
12 : //
13 : //===----------------------------------------------------------------------===//
14 : #include "clang/AST/ASTImporter.h"
15 :
16 : #include "clang/AST/ASTContext.h"
17 : #include "clang/AST/ASTDiagnostic.h"
18 : #include "clang/AST/DeclObjC.h"
19 : #include "clang/AST/DeclVisitor.h"
20 : #include "clang/AST/TypeVisitor.h"
21 : #include "clang/Basic/FileManager.h"
22 : #include "clang/Basic/SourceManager.h"
23 : #include "llvm/Support/MemoryBuffer.h"
24 :
25 : using namespace clang;
26 :
27 : namespace {
28 : class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
29 : public DeclVisitor<ASTNodeImporter, Decl *> {
30 : ASTImporter &Importer;
31 :
32 : public:
33 16: explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
34 :
35 : using TypeVisitor<ASTNodeImporter, QualType>::Visit;
36 : using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
37 :
38 : // Importing types
39 : QualType VisitType(Type *T);
40 : QualType VisitBuiltinType(BuiltinType *T);
41 : QualType VisitComplexType(ComplexType *T);
42 : QualType VisitPointerType(PointerType *T);
43 : QualType VisitBlockPointerType(BlockPointerType *T);
44 : QualType VisitLValueReferenceType(LValueReferenceType *T);
45 : QualType VisitRValueReferenceType(RValueReferenceType *T);
46 : QualType VisitMemberPointerType(MemberPointerType *T);
47 : QualType VisitConstantArrayType(ConstantArrayType *T);
48 : QualType VisitIncompleteArrayType(IncompleteArrayType *T);
49 : QualType VisitVariableArrayType(VariableArrayType *T);
50 : // FIXME: DependentSizedArrayType
51 : // FIXME: DependentSizedExtVectorType
52 : QualType VisitVectorType(VectorType *T);
53 : QualType VisitExtVectorType(ExtVectorType *T);
54 : QualType VisitFunctionNoProtoType(FunctionNoProtoType *T);
55 : QualType VisitFunctionProtoType(FunctionProtoType *T);
56 : // FIXME: UnresolvedUsingType
57 : QualType VisitTypedefType(TypedefType *T);
58 : QualType VisitTypeOfExprType(TypeOfExprType *T);
59 : // FIXME: DependentTypeOfExprType
60 : QualType VisitTypeOfType(TypeOfType *T);
61 : QualType VisitDecltypeType(DecltypeType *T);
62 : // FIXME: DependentDecltypeType
63 : QualType VisitRecordType(RecordType *T);
64 : QualType VisitEnumType(EnumType *T);
65 : QualType VisitElaboratedType(ElaboratedType *T);
66 : // FIXME: TemplateTypeParmType
67 : // FIXME: SubstTemplateTypeParmType
68 : // FIXME: TemplateSpecializationType
69 : QualType VisitQualifiedNameType(QualifiedNameType *T);
70 : // FIXME: TypenameType
71 : QualType VisitObjCInterfaceType(ObjCInterfaceType *T);
72 : QualType VisitObjCObjectPointerType(ObjCObjectPointerType *T);
73 :
74 : // Importing declarations
75 : Decl *VisitDecl(Decl *D);
76 : Decl *VisitVarDecl(VarDecl *D);
77 : };
78 : }
79 :
80 : //----------------------------------------------------------------------------
81 : // Import Types
82 : //----------------------------------------------------------------------------
83 :
84 0: QualType ASTNodeImporter::VisitType(Type *T) {
85 : Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
86 0: << T->getTypeClassName();
87 0: return QualType();
88 : }
89 :
90 5: QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
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
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
0: branch 15 not taken
2: branch 16 taken
0: branch 17 not taken
0: branch 18 not taken
0: branch 19 not taken
1: branch 20 taken
2: branch 21 taken
0: branch 22 not taken
0: branch 23 not taken
0: branch 24 not taken
0: branch 25 not taken
0: branch 26 not taken
0: branch 27 not taken
0: branch 28 not taken
0: branch 29 not taken
0: branch 30 not taken
91 5: switch (T->getKind()) {
92 0: case BuiltinType::Void: return Importer.getToContext().VoidTy;
93 0: case BuiltinType::Bool: return Importer.getToContext().BoolTy;
94 :
95 : case BuiltinType::Char_U:
96 : // The context we're importing from has an unsigned 'char'. If we're
97 : // importing into a context with a signed 'char', translate to
98 : // 'unsigned char' instead.
0: branch 2 not taken
0: branch 3 not taken
99 0: if (Importer.getToContext().getLangOptions().CharIsSigned)
100 0: return Importer.getToContext().UnsignedCharTy;
101 :
102 0: return Importer.getToContext().CharTy;
103 :
104 0: case BuiltinType::UChar: return Importer.getToContext().UnsignedCharTy;
105 :
106 : case BuiltinType::Char16:
107 : // FIXME: Make sure that the "to" context supports C++!
108 0: return Importer.getToContext().Char16Ty;
109 :
110 : case BuiltinType::Char32:
111 : // FIXME: Make sure that the "to" context supports C++!
112 0: return Importer.getToContext().Char32Ty;
113 :
114 0: case BuiltinType::UShort: return Importer.getToContext().UnsignedShortTy;
115 0: case BuiltinType::UInt: return Importer.getToContext().UnsignedIntTy;
116 0: case BuiltinType::ULong: return Importer.getToContext().UnsignedLongTy;
117 : case BuiltinType::ULongLong:
118 0: return Importer.getToContext().UnsignedLongLongTy;
119 0: case BuiltinType::UInt128: return Importer.getToContext().UnsignedInt128Ty;
120 :
121 : case BuiltinType::Char_S:
122 : // The context we're importing from has an unsigned 'char'. If we're
123 : // importing into a context with a signed 'char', translate to
124 : // 'unsigned char' instead.
0: branch 2 not taken
0: branch 3 not taken
125 0: if (!Importer.getToContext().getLangOptions().CharIsSigned)
126 0: return Importer.getToContext().SignedCharTy;
127 :
128 0: return Importer.getToContext().CharTy;
129 :
130 0: case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
131 : case BuiltinType::WChar:
132 : // FIXME: If not in C++, shall we translate to the C equivalent of
133 : // wchar_t?
134 0: return Importer.getToContext().WCharTy;
135 :
136 0: case BuiltinType::Short : return Importer.getToContext().ShortTy;
137 2: case BuiltinType::Int : return Importer.getToContext().IntTy;
138 0: case BuiltinType::Long : return Importer.getToContext().LongTy;
139 0: case BuiltinType::LongLong : return Importer.getToContext().LongLongTy;
140 0: case BuiltinType::Int128 : return Importer.getToContext().Int128Ty;
141 1: case BuiltinType::Float: return Importer.getToContext().FloatTy;
142 2: case BuiltinType::Double: return Importer.getToContext().DoubleTy;
143 0: case BuiltinType::LongDouble: return Importer.getToContext().LongDoubleTy;
144 :
145 : case BuiltinType::NullPtr:
146 : // FIXME: Make sure that the "to" context supports C++0x!
147 0: return Importer.getToContext().NullPtrTy;
148 :
149 0: case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
150 0: case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
151 : case BuiltinType::UndeducedAuto:
152 : // FIXME: Make sure that the "to" context supports C++0x!
153 0: return Importer.getToContext().UndeducedAutoTy;
154 :
155 : case BuiltinType::ObjCId:
156 : // FIXME: Make sure that the "to" context supports Objective-C!
157 0: return Importer.getToContext().ObjCBuiltinIdTy;
158 :
159 : case BuiltinType::ObjCClass:
160 0: return Importer.getToContext().ObjCBuiltinClassTy;
161 :
162 : case BuiltinType::ObjCSel:
163 0: return Importer.getToContext().ObjCBuiltinSelTy;
164 : }
165 :
166 0: return QualType();
167 : }
168 :
169 0: QualType ASTNodeImporter::VisitComplexType(ComplexType *T) {
170 0: QualType ToElementType = Importer.Import(T->getElementType());
0: branch 1 not taken
0: branch 2 not taken
171 0: if (ToElementType.isNull())
172 0: return QualType();
173 :
174 0: return Importer.getToContext().getComplexType(ToElementType);
175 : }
176 :
177 5: QualType ASTNodeImporter::VisitPointerType(PointerType *T) {
178 5: QualType ToPointeeType = Importer.Import(T->getPointeeType());
0: branch 1 not taken
5: branch 2 taken
179 5: if (ToPointeeType.isNull())
180 0: return QualType();
181 :
182 5: return Importer.getToContext().getPointerType(ToPointeeType);
183 : }
184 :
185 0: QualType ASTNodeImporter::VisitBlockPointerType(BlockPointerType *T) {
186 : // FIXME: Check for blocks support in "to" context.
187 0: QualType ToPointeeType = Importer.Import(T->getPointeeType());
0: branch 1 not taken
0: branch 2 not taken
188 0: if (ToPointeeType.isNull())
189 0: return QualType();
190 :
191 0: return Importer.getToContext().getBlockPointerType(ToPointeeType);
192 : }
193 :
194 0: QualType ASTNodeImporter::VisitLValueReferenceType(LValueReferenceType *T) {
195 : // FIXME: Check for C++ support in "to" context.
196 0: QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
0: branch 1 not taken
0: branch 2 not taken
197 0: if (ToPointeeType.isNull())
198 0: return QualType();
199 :
200 0: return Importer.getToContext().getLValueReferenceType(ToPointeeType);
201 : }
202 :
203 0: QualType ASTNodeImporter::VisitRValueReferenceType(RValueReferenceType *T) {
204 : // FIXME: Check for C++0x support in "to" context.
205 0: QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
0: branch 1 not taken
0: branch 2 not taken
206 0: if (ToPointeeType.isNull())
207 0: return QualType();
208 :
209 0: return Importer.getToContext().getRValueReferenceType(ToPointeeType);
210 : }
211 :
212 0: QualType ASTNodeImporter::VisitMemberPointerType(MemberPointerType *T) {
213 : // FIXME: Check for C++ support in "to" context.
214 0: QualType ToPointeeType = Importer.Import(T->getPointeeType());
0: branch 1 not taken
0: branch 2 not taken
215 0: if (ToPointeeType.isNull())
216 0: return QualType();
217 :
218 0: QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
219 : return Importer.getToContext().getMemberPointerType(ToPointeeType,
220 0: ClassType.getTypePtr());
221 : }
222 :
223 0: QualType ASTNodeImporter::VisitConstantArrayType(ConstantArrayType *T) {
224 0: QualType ToElementType = Importer.Import(T->getElementType());
0: branch 1 not taken
0: branch 2 not taken
225 0: if (ToElementType.isNull())
226 0: return QualType();
227 :
228 : return Importer.getToContext().getConstantArrayType(ToElementType,
229 : T->getSize(),
230 : T->getSizeModifier(),
231 0: T->getIndexTypeCVRQualifiers());
232 : }
233 :
234 0: QualType ASTNodeImporter::VisitIncompleteArrayType(IncompleteArrayType *T) {
235 0: QualType ToElementType = Importer.Import(T->getElementType());
0: branch 1 not taken
0: branch 2 not taken
236 0: if (ToElementType.isNull())
237 0: return QualType();
238 :
239 : return Importer.getToContext().getIncompleteArrayType(ToElementType,
240 : T->getSizeModifier(),
241 0: T->getIndexTypeCVRQualifiers());
242 : }
243 :
244 0: QualType ASTNodeImporter::VisitVariableArrayType(VariableArrayType *T) {
245 0: QualType ToElementType = Importer.Import(T->getElementType());
0: branch 1 not taken
0: branch 2 not taken
246 0: if (ToElementType.isNull())
247 0: return QualType();
248 :
249 0: Expr *Size = Importer.Import(T->getSizeExpr());
0: branch 0 not taken
0: branch 1 not taken
250 0: if (!Size)
251 0: return QualType();
252 :
253 0: SourceRange Brackets = Importer.Import(T->getBracketsRange());
254 : return Importer.getToContext().getVariableArrayType(ToElementType, Size,
255 : T->getSizeModifier(),
256 : T->getIndexTypeCVRQualifiers(),
257 0: Brackets);
258 : }
259 :
260 0: QualType ASTNodeImporter::VisitVectorType(VectorType *T) {
261 0: QualType ToElementType = Importer.Import(T->getElementType());
0: branch 1 not taken
0: branch 2 not taken
262 0: if (ToElementType.isNull())
263 0: return QualType();
264 :
265 : return Importer.getToContext().getVectorType(ToElementType,
266 : T->getNumElements(),
267 : T->isAltiVec(),
268 0: T->isPixel());
269 : }
270 :
271 0: QualType ASTNodeImporter::VisitExtVectorType(ExtVectorType *T) {
272 0: QualType ToElementType = Importer.Import(T->getElementType());
0: branch 1 not taken
0: branch 2 not taken
273 0: if (ToElementType.isNull())
274 0: return QualType();
275 :
276 : return Importer.getToContext().getExtVectorType(ToElementType,
277 0: T->getNumElements());
278 : }
279 :
280 0: QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) {
281 : // FIXME: What happens if we're importing a function without a prototype
282 : // into C++? Should we make it variadic?
283 0: QualType ToResultType = Importer.Import(T->getResultType());
0: branch 1 not taken
0: branch 2 not taken
284 0: if (ToResultType.isNull())
285 0: return QualType();
286 :
287 : return Importer.getToContext().getFunctionNoProtoType(ToResultType,
288 : T->getNoReturnAttr(),
289 0: T->getCallConv());
290 : }
291 :
292 0: QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) {
293 0: QualType ToResultType = Importer.Import(T->getResultType());
0: branch 1 not taken
0: branch 2 not taken
294 0: if (ToResultType.isNull())
295 0: return QualType();
296 :
297 : // Import argument types
298 0: llvm::SmallVector<QualType, 4> ArgTypes;
0: branch 1 not taken
0: branch 2 not taken
299 0: for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
300 0: AEnd = T->arg_type_end();
301 : A != AEnd; ++A) {
302 0: QualType ArgType = Importer.Import(*A);
0: branch 1 not taken
0: branch 2 not taken
303 0: if (ArgType.isNull())
304 0: return QualType();
305 0: ArgTypes.push_back(ArgType);
306 : }
307 :
308 : // Import exception types
309 0: llvm::SmallVector<QualType, 4> ExceptionTypes;
0: branch 1 not taken
0: branch 2 not taken
310 0: for (FunctionProtoType::exception_iterator E = T->exception_begin(),
311 0: EEnd = T->exception_end();
312 : E != EEnd; ++E) {
313 0: QualType ExceptionType = Importer.Import(*E);
0: branch 1 not taken
0: branch 2 not taken
314 0: if (ExceptionType.isNull())
315 0: return QualType();
316 0: ExceptionTypes.push_back(ExceptionType);
317 : }
318 :
319 : return Importer.getToContext().getFunctionType(ToResultType, ArgTypes.data(),
320 : ArgTypes.size(),
321 : T->isVariadic(),
322 : T->getTypeQuals(),
323 : T->hasExceptionSpec(),
324 : T->hasAnyExceptionSpec(),
325 : ExceptionTypes.size(),
326 : ExceptionTypes.data(),
327 : T->getNoReturnAttr(),
328 0: T->getCallConv());
329 : }
330 :
331 0: QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) {
332 : TypedefDecl *ToDecl
333 0: = dyn_cast_or_null<TypedefDecl>(Importer.Import(T->getDecl()));
0: branch 0 not taken
0: branch 1 not taken
334 0: if (!ToDecl)
335 0: return QualType();
336 :
337 0: return Importer.getToContext().getTypeDeclType(ToDecl);
338 : }
339 :
340 0: QualType ASTNodeImporter::VisitTypeOfExprType(TypeOfExprType *T) {
341 0: Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
0: branch 0 not taken
0: branch 1 not taken
342 0: if (!ToExpr)
343 0: return QualType();
344 :
345 0: return Importer.getToContext().getTypeOfExprType(ToExpr);
346 : }
347 :
348 0: QualType ASTNodeImporter::VisitTypeOfType(TypeOfType *T) {
349 0: QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
0: branch 1 not taken
0: branch 2 not taken
350 0: if (ToUnderlyingType.isNull())
351 0: return QualType();
352 :
353 0: return Importer.getToContext().getTypeOfType(ToUnderlyingType);
354 : }
355 :
356 0: QualType ASTNodeImporter::VisitDecltypeType(DecltypeType *T) {
357 0: Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
0: branch 0 not taken
0: branch 1 not taken
358 0: if (!ToExpr)
359 0: return QualType();
360 :
361 0: return Importer.getToContext().getDecltypeType(ToExpr);
362 : }
363 :
364 0: QualType ASTNodeImporter::VisitRecordType(RecordType *T) {
365 : RecordDecl *ToDecl
366 0: = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
0: branch 0 not taken
0: branch 1 not taken
367 0: if (!ToDecl)
368 0: return QualType();
369 :
370 0: return Importer.getToContext().getTagDeclType(ToDecl);
371 : }
372 :
373 0: QualType ASTNodeImporter::VisitEnumType(EnumType *T) {
374 : EnumDecl *ToDecl
375 0: = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
0: branch 0 not taken
0: branch 1 not taken
376 0: if (!ToDecl)
377 0: return QualType();
378 :
379 0: return Importer.getToContext().getTagDeclType(ToDecl);
380 : }
381 :
382 0: QualType ASTNodeImporter::VisitElaboratedType(ElaboratedType *T) {
383 0: QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
0: branch 1 not taken
0: branch 2 not taken
384 0: if (ToUnderlyingType.isNull())
385 0: return QualType();
386 :
387 : return Importer.getToContext().getElaboratedType(ToUnderlyingType,
388 0: T->getTagKind());
389 : }
390 :
391 0: QualType ASTNodeImporter::VisitQualifiedNameType(QualifiedNameType *T) {
392 0: NestedNameSpecifier *ToQualifier = Importer.Import(T->getQualifier());
0: branch 0 not taken
0: branch 1 not taken
393 0: if (!ToQualifier)
394 0: return QualType();
395 :
396 0: QualType ToNamedType = Importer.Import(T->getNamedType());
0: branch 1 not taken
0: branch 2 not taken
397 0: if (ToNamedType.isNull())
398 0: return QualType();
399 :
400 0: return Importer.getToContext().getQualifiedNameType(ToQualifier, ToNamedType);
401 : }
402 :
403 0: QualType ASTNodeImporter::VisitObjCInterfaceType(ObjCInterfaceType *T) {
404 : ObjCInterfaceDecl *Class
405 0: = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
0: branch 0 not taken
0: branch 1 not taken
406 0: if (!Class)
407 0: return QualType();
408 :
409 0: llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
0: branch 1 not taken
0: branch 2 not taken
410 0: for (ObjCInterfaceType::qual_iterator P = T->qual_begin(),
411 0: PEnd = T->qual_end();
412 : P != PEnd; ++P) {
413 : ObjCProtocolDecl *Protocol
414 0: = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
0: branch 0 not taken
0: branch 1 not taken
415 0: if (!Protocol)
416 0: return QualType();
417 0: Protocols.push_back(Protocol);
418 : }
419 :
420 : return Importer.getToContext().getObjCInterfaceType(Class,
421 : Protocols.data(),
422 0: Protocols.size());
423 : }
424 :
425 0: QualType ASTNodeImporter::VisitObjCObjectPointerType(ObjCObjectPointerType *T) {
426 0: QualType ToPointeeType = Importer.Import(T->getPointeeType());
0: branch 1 not taken
0: branch 2 not taken
427 0: if (ToPointeeType.isNull())
428 0: return QualType();
429 :
430 0: llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
0: branch 1 not taken
0: branch 2 not taken
431 0: for (ObjCObjectPointerType::qual_iterator P = T->qual_begin(),
432 0: PEnd = T->qual_end();
433 : P != PEnd; ++P) {
434 : ObjCProtocolDecl *Protocol
435 0: = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
0: branch 0 not taken
0: branch 1 not taken
436 0: if (!Protocol)
437 0: return QualType();
438 0: Protocols.push_back(Protocol);
439 : }
440 :
441 : return Importer.getToContext().getObjCObjectPointerType(ToPointeeType,
442 : Protocols.data(),
443 0: Protocols.size());
444 : }
445 :
446 : //----------------------------------------------------------------------------
447 : // Import Declarations
448 : //----------------------------------------------------------------------------
449 0: Decl *ASTNodeImporter::VisitDecl(Decl *D) {
450 : Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
451 0: << D->getDeclKindName();
452 0: return 0;
453 : }
454 :
455 6: Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
456 : // Import the context of this declaration.
457 6: DeclContext *DC = Importer.ImportContext(D->getDeclContext());
0: branch 0 not taken
6: branch 1 taken
458 6: if (!DC)
459 0: return 0;
460 :
461 6: DeclContext *LexicalDC = DC;
0: branch 2 not taken
6: branch 3 taken
462 6: if (D->getDeclContext() != D->getLexicalDeclContext()) {
463 0: LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
0: branch 0 not taken
0: branch 1 not taken
464 0: if (!LexicalDC)
465 0: return 0;
466 : }
467 :
468 : // Import the name of this declaration.
469 6: DeclarationName Name = Importer.Import(D->getDeclName());
6: branch 2 taken
0: branch 3 not taken
0: branch 5 not taken
6: branch 6 taken
0: branch 7 not taken
6: branch 8 taken
470 6: if (D->getDeclName() && !Name)
471 0: return 0;
472 :
473 : // Import the type of this declaration.
474 6: QualType T = Importer.Import(D->getType());
0: branch 1 not taken
6: branch 2 taken
475 6: if (T.isNull())
476 0: return 0;
477 :
478 : // Import the location of this declaration.
479 6: SourceLocation Loc = Importer.Import(D->getLocation());
480 :
481 : // Try to find a variable in our own ("to") context with the same name and
482 : // in the same context as the variable we're importing.
6: branch 1 taken
0: branch 2 not taken
483 6: if (D->isFileVarDecl()) {
484 6: VarDecl *MergeWithVar = 0;
485 6: llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
486 6: unsigned IDNS = Decl::IDNS_Ordinary;
3: branch 1 taken
5: branch 2 taken
487 8: for (DeclContext::lookup_result Lookup = DC->lookup(Name);
488 : Lookup.first != Lookup.second;
489 : ++Lookup.first) {
0: branch 1 not taken
3: branch 2 taken
490 3: if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
491 0: continue;
492 :
3: branch 1 taken
0: branch 2 not taken
493 3: if (VarDecl *FoundVar = dyn_cast<VarDecl>(*Lookup.first)) {
494 : // We have found a variable that we may need to merge with. Check it.
3: branch 2 taken
0: branch 3 not taken
3: branch 6 taken
0: branch 7 not taken
3: branch 8 taken
0: branch 9 not taken
495 3: if (isExternalLinkage(FoundVar->getLinkage()) &&
496 : isExternalLinkage(D->getLinkage())) {
1: branch 3 taken
2: branch 4 taken
497 3: if (Importer.getToContext().typesAreCompatible(T,
498 : FoundVar->getType())) {
499 1: MergeWithVar = FoundVar;
500 1: break;
501 : }
502 :
503 : Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
504 2: << Name << T << FoundVar->getType();
505 : Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
506 2: << FoundVar->getType();
507 : }
508 : }
509 :
510 2: ConflictingDecls.push_back(*Lookup.first);
511 : }
512 :
1: branch 0 taken
5: branch 1 taken
513 6: if (MergeWithVar) {
514 : // An equivalent variable with external linkage has been found. Link
515 : // the two declarations, then merge them.
516 1: Importer.getImportedDecls()[D] = MergeWithVar;
517 :
0: branch 1 not taken
1: branch 2 taken
518 1: if (VarDecl *DDef = D->getDefinition()) {
0: branch 1 not taken
0: branch 2 not taken
519 0: if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
520 : Importer.ToDiag(ExistingDef->getLocation(),
521 : diag::err_odr_variable_multiple_def)
522 0: << Name;
523 0: Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
524 : } else {
525 0: Expr *Init = Importer.Import(DDef->getInit());
526 0: MergeWithVar->setInit(Importer.getToContext(), Init);
527 : }
528 : }
529 :
530 2: return MergeWithVar;
531 : }
532 :
2: branch 1 taken
3: branch 2 taken
533 5: if (!ConflictingDecls.empty()) {
534 : Name = Importer.HandleNameConflict(Name, DC, IDNS,
535 : ConflictingDecls.data(),
536 2: ConflictingDecls.size());
0: branch 1 not taken
2: branch 2 taken
537 2: if (!Name)
538 0: return 0;
5: branch 1 taken
1: branch 2 taken
539 6: }
540 : }
541 :
542 5: TypeSourceInfo *TInfo = 0;
5: branch 1 taken
0: branch 2 not taken
543 5: if (TypeSourceInfo *FromTInfo = D->getTypeSourceInfo()) {
544 5: TInfo = Importer.Import(FromTInfo);
545 : #if 0
546 : // FIXME: Tolerate failures in translation type source
547 : // information, at least until it is implemented.
548 : if (!TInfo)
549 : return 0;
550 : #endif
551 : }
552 :
553 : // Create the imported variable.
554 : VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc,
555 : Name.getAsIdentifierInfo(), T, TInfo,
556 5: D->getStorageClass());
557 5: ToVar->setLexicalDeclContext(LexicalDC);
558 5: Importer.getImportedDecls()[D] = ToVar;
559 5: LexicalDC->addDecl(ToVar);
560 :
561 : // Merge the initializer.
562 : // FIXME: Can we really import any initializer? Alternatively, we could force
563 : // ourselves to import every declaration of a variable and then only use
564 : // getInit() here.
565 : ToVar->setInit(Importer.getToContext(),
566 5: Importer.Import(const_cast<Expr *>(D->getAnyInitializer())));
567 :
568 : // FIXME: Other bits to merge?
569 :
570 5: return ToVar;
571 : }
572 :
573 : ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
574 : Diagnostic &ToDiags,
575 : ASTContext &FromContext, FileManager &FromFileManager,
576 2: Diagnostic &FromDiags)
577 : : ToContext(ToContext), FromContext(FromContext),
578 : ToFileManager(ToFileManager), FromFileManager(FromFileManager),
579 2: ToDiags(ToDiags), FromDiags(FromDiags) {
580 : ImportedDecls[FromContext.getTranslationUnitDecl()]
581 2: = ToContext.getTranslationUnitDecl();
582 2: }
583 :
0: branch 3 not taken
0: branch 4 not taken
0: branch 9 not taken
2: branch 10 taken
0: branch 15 not taken
0: branch 16 not taken
584 2: ASTImporter::~ASTImporter() { }
585 :
586 11: QualType ASTImporter::Import(QualType FromT) {
0: branch 1 not taken
11: branch 2 taken
587 11: if (FromT.isNull())
588 0: return QualType();
589 :
590 : // Check whether we've already imported this type.
591 : llvm::DenseMap<Type *, Type *>::iterator Pos
592 11: = ImportedTypes.find(FromT.getTypePtr());
1: branch 3 taken
10: branch 4 taken
593 11: if (Pos != ImportedTypes.end())
594 1: return ToContext.getQualifiedType(Pos->second, FromT.getQualifiers());
595 :
596 : // Import the type
597 10: ASTNodeImporter Importer(*this);
598 10: QualType ToT = Importer.Visit(FromT.getTypePtr());
0: branch 1 not taken
10: branch 2 taken
599 10: if (ToT.isNull())
600 0: return ToT;
601 :
602 : // Record the imported type.
603 10: ImportedTypes[FromT.getTypePtr()] = ToT.getTypePtr();
604 :
605 10: return ToContext.getQualifiedType(ToT, FromT.getQualifiers());
606 : }
607 :
608 5: TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
609 : // FIXME: Implement!
610 5: return 0;
611 : }
612 :
613 12: Decl *ASTImporter::Import(Decl *FromD) {
0: branch 0 not taken
12: branch 1 taken
614 12: if (!FromD)
615 0: return 0;
616 :
617 : // Check whether we've already imported this declaration.
618 12: llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
6: branch 3 taken
6: branch 4 taken
619 12: if (Pos != ImportedDecls.end())
620 6: return Pos->second;
621 :
622 : // Import the type
623 6: ASTNodeImporter Importer(*this);
624 6: Decl *ToD = Importer.Visit(FromD);
0: branch 0 not taken
6: branch 1 taken
625 6: if (!ToD)
626 0: return 0;
627 :
628 : // Record the imported declaration.
629 6: ImportedDecls[FromD] = ToD;
630 6: return ToD;
631 : }
632 :
633 6: DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
0: branch 0 not taken
6: branch 1 taken
634 6: if (!FromDC)
635 0: return FromDC;
636 :
637 6: return cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
638 : }
639 :
640 5: Expr *ASTImporter::Import(Expr *FromE) {
5: branch 0 taken
0: branch 1 not taken
641 5: if (!FromE)
642 5: return 0;
643 :
644 0: return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
645 : }
646 :
647 0: Stmt *ASTImporter::Import(Stmt *FromS) {
0: branch 0 not taken
0: branch 1 not taken
648 0: if (!FromS)
649 0: return 0;
650 :
651 : // FIXME: Implement!
652 0: return 0;
653 : }
654 :
655 0: NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
0: branch 0 not taken
0: branch 1 not taken
656 0: if (!FromNNS)
657 0: return 0;
658 :
659 : // FIXME: Implement!
660 0: return 0;
661 : }
662 :
663 9: SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
2: branch 1 taken
7: branch 2 taken
664 9: if (FromLoc.isInvalid())
665 2: return SourceLocation();
666 :
667 7: SourceManager &FromSM = FromContext.getSourceManager();
668 :
669 : // For now, map everything down to its spelling location, so that we
670 : // don't have to import macro instantiations.
671 : // FIXME: Import macro instantiations!
672 7: FromLoc = FromSM.getSpellingLoc(FromLoc);
673 7: std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
674 7: SourceManager &ToSM = ToContext.getSourceManager();
675 : return ToSM.getLocForStartOfFile(Import(Decomposed.first))
676 7: .getFileLocWithOffset(Decomposed.second);
677 : }
678 :
679 0: SourceRange ASTImporter::Import(SourceRange FromRange) {
680 0: return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
681 : }
682 :
683 7: FileID ASTImporter::Import(FileID FromID) {
684 : llvm::DenseMap<unsigned, FileID>::iterator Pos
685 7: = ImportedFileIDs.find(FromID.getHashValue());
4: branch 3 taken
3: branch 4 taken
686 7: if (Pos != ImportedFileIDs.end())
687 4: return Pos->second;
688 :
689 3: SourceManager &FromSM = FromContext.getSourceManager();
690 3: SourceManager &ToSM = ToContext.getSourceManager();
691 3: const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
3: branch 1 taken
0: branch 2 not taken
692 3: assert(FromSLoc.isFile() && "Cannot handle macro instantiations yet");
693 :
694 : // Include location of this file.
695 3: SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
696 :
697 : // Map the FileID for to the "to" source manager.
698 3: FileID ToID;
699 3: const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
3: branch 0 taken
0: branch 1 not taken
700 3: if (Cache->Entry) {
701 : // FIXME: We probably want to use getVirtualFile(), so we don't hit the
702 : // disk again
703 : // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
704 : // than mmap the files several times.
705 3: const FileEntry *Entry = ToFileManager.getFile(Cache->Entry->getName());
706 : ToID = ToSM.createFileID(Entry, ToIncludeLoc,
707 3: FromSLoc.getFile().getFileCharacteristic());
708 : } else {
709 : // FIXME: We want to re-use the existing MemoryBuffer!
710 0: const llvm::MemoryBuffer *FromBuf = Cache->getBuffer();
711 : llvm::MemoryBuffer *ToBuf
712 : = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBufferStart(),
713 : FromBuf->getBufferEnd(),
714 0: FromBuf->getBufferIdentifier());
715 0: ToID = ToSM.createFileIDForMemBuffer(ToBuf);
716 : }
717 :
718 :
719 3: ImportedFileIDs[FromID.getHashValue()] = ToID;
720 3: return ToID;
721 : }
722 :
723 6: DeclarationName ASTImporter::Import(DeclarationName FromName) {
0: branch 1 not taken
6: branch 2 taken
724 6: if (!FromName)
725 0: return DeclarationName();
726 :
6: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
727 6: switch (FromName.getNameKind()) {
728 : case DeclarationName::Identifier:
729 6: return Import(FromName.getAsIdentifierInfo());
730 :
731 : case DeclarationName::ObjCZeroArgSelector:
732 : case DeclarationName::ObjCOneArgSelector:
733 : case DeclarationName::ObjCMultiArgSelector:
734 0: return Import(FromName.getObjCSelector());
735 :
736 : case DeclarationName::CXXConstructorName: {
737 0: QualType T = Import(FromName.getCXXNameType());
0: branch 1 not taken
0: branch 2 not taken
738 0: if (T.isNull())
739 0: return DeclarationName();
740 :
741 : return ToContext.DeclarationNames.getCXXConstructorName(
742 0: ToContext.getCanonicalType(T));
743 : }
744 :
745 : case DeclarationName::CXXDestructorName: {
746 0: QualType T = Import(FromName.getCXXNameType());
0: branch 1 not taken
0: branch 2 not taken
747 0: if (T.isNull())
748 0: return DeclarationName();
749 :
750 : return ToContext.DeclarationNames.getCXXDestructorName(
751 0: ToContext.getCanonicalType(T));
752 : }
753 :
754 : case DeclarationName::CXXConversionFunctionName: {
755 0: QualType T = Import(FromName.getCXXNameType());
0: branch 1 not taken
0: branch 2 not taken
756 0: if (T.isNull())
757 0: return DeclarationName();
758 :
759 : return ToContext.DeclarationNames.getCXXConversionFunctionName(
760 0: ToContext.getCanonicalType(T));
761 : }
762 :
763 : case DeclarationName::CXXOperatorName:
764 : return ToContext.DeclarationNames.getCXXOperatorName(
765 0: FromName.getCXXOverloadedOperator());
766 :
767 : case DeclarationName::CXXLiteralOperatorName:
768 : return ToContext.DeclarationNames.getCXXLiteralOperatorName(
769 0: Import(FromName.getCXXLiteralIdentifier()));
770 :
771 : case DeclarationName::CXXUsingDirective:
772 : // FIXME: STATICS!
773 0: return DeclarationName::getUsingDirectiveName();
774 : }
775 :
776 : // Silence bogus GCC warning
777 0: return DeclarationName();
778 : }
779 :
780 6: IdentifierInfo *ASTImporter::Import(IdentifierInfo *FromId) {
0: branch 0 not taken
6: branch 1 taken
781 6: if (!FromId)
782 0: return 0;
783 :
784 6: return &ToContext.Idents.get(FromId->getName());
785 : }
786 :
787 : DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
788 : DeclContext *DC,
789 : unsigned IDNS,
790 : NamedDecl **Decls,
791 2: unsigned NumDecls) {
792 2: return Name;
793 : }
794 :
795 4: DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
796 : return ToDiags.Report(FullSourceLoc(Loc, ToContext.getSourceManager()),
797 4: DiagID);
798 : }
799 :
800 0: DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
801 : return FromDiags.Report(FullSourceLoc(Loc, FromContext.getSourceManager()),
802 0: DiagID);
803 : }
Generated: 2010-02-10 01:31 by zcov