zcov: / lib/AST/ASTImporter.cpp


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


Programs: 1 Runs 2897


       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