1203955Srdivacky//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===// 2203955Srdivacky// 3203955Srdivacky// The LLVM Compiler Infrastructure 4203955Srdivacky// 5203955Srdivacky// This file is distributed under the University of Illinois Open Source 6203955Srdivacky// License. See LICENSE.TXT for details. 7203955Srdivacky// 8203955Srdivacky//===----------------------------------------------------------------------===// 9203955Srdivacky// 10203955Srdivacky// This file defines the ASTImporter class which imports AST nodes from one 11203955Srdivacky// context into another context. 12203955Srdivacky// 13203955Srdivacky//===----------------------------------------------------------------------===// 14203955Srdivacky#include "clang/AST/ASTImporter.h" 15203955Srdivacky#include "clang/AST/ASTContext.h" 16203955Srdivacky#include "clang/AST/ASTDiagnostic.h" 17203955Srdivacky#include "clang/AST/DeclCXX.h" 18203955Srdivacky#include "clang/AST/DeclObjC.h" 19203955Srdivacky#include "clang/AST/DeclVisitor.h" 20203955Srdivacky#include "clang/AST/StmtVisitor.h" 21203955Srdivacky#include "clang/AST/TypeVisitor.h" 22203955Srdivacky#include "clang/Basic/FileManager.h" 23203955Srdivacky#include "clang/Basic/SourceManager.h" 24203955Srdivacky#include "llvm/Support/MemoryBuffer.h" 25203955Srdivacky#include <deque> 26203955Srdivacky 27235633Sdimnamespace clang { 28203955Srdivacky class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>, 29203955Srdivacky public DeclVisitor<ASTNodeImporter, Decl *>, 30203955Srdivacky public StmtVisitor<ASTNodeImporter, Stmt *> { 31203955Srdivacky ASTImporter &Importer; 32203955Srdivacky 33203955Srdivacky public: 34203955Srdivacky explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { } 35203955Srdivacky 36203955Srdivacky using TypeVisitor<ASTNodeImporter, QualType>::Visit; 37203955Srdivacky using DeclVisitor<ASTNodeImporter, Decl *>::Visit; 38203955Srdivacky using StmtVisitor<ASTNodeImporter, Stmt *>::Visit; 39203955Srdivacky 40203955Srdivacky // Importing types 41218893Sdim QualType VisitType(const Type *T); 42218893Sdim QualType VisitBuiltinType(const BuiltinType *T); 43218893Sdim QualType VisitComplexType(const ComplexType *T); 44218893Sdim QualType VisitPointerType(const PointerType *T); 45218893Sdim QualType VisitBlockPointerType(const BlockPointerType *T); 46218893Sdim QualType VisitLValueReferenceType(const LValueReferenceType *T); 47218893Sdim QualType VisitRValueReferenceType(const RValueReferenceType *T); 48218893Sdim QualType VisitMemberPointerType(const MemberPointerType *T); 49218893Sdim QualType VisitConstantArrayType(const ConstantArrayType *T); 50218893Sdim QualType VisitIncompleteArrayType(const IncompleteArrayType *T); 51218893Sdim QualType VisitVariableArrayType(const VariableArrayType *T); 52203955Srdivacky // FIXME: DependentSizedArrayType 53203955Srdivacky // FIXME: DependentSizedExtVectorType 54218893Sdim QualType VisitVectorType(const VectorType *T); 55218893Sdim QualType VisitExtVectorType(const ExtVectorType *T); 56218893Sdim QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T); 57218893Sdim QualType VisitFunctionProtoType(const FunctionProtoType *T); 58203955Srdivacky // FIXME: UnresolvedUsingType 59226890Sdim QualType VisitParenType(const ParenType *T); 60218893Sdim QualType VisitTypedefType(const TypedefType *T); 61218893Sdim QualType VisitTypeOfExprType(const TypeOfExprType *T); 62203955Srdivacky // FIXME: DependentTypeOfExprType 63218893Sdim QualType VisitTypeOfType(const TypeOfType *T); 64218893Sdim QualType VisitDecltypeType(const DecltypeType *T); 65223017Sdim QualType VisitUnaryTransformType(const UnaryTransformType *T); 66218893Sdim QualType VisitAutoType(const AutoType *T); 67203955Srdivacky // FIXME: DependentDecltypeType 68218893Sdim QualType VisitRecordType(const RecordType *T); 69218893Sdim QualType VisitEnumType(const EnumType *T); 70203955Srdivacky // FIXME: TemplateTypeParmType 71203955Srdivacky // FIXME: SubstTemplateTypeParmType 72218893Sdim QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); 73218893Sdim QualType VisitElaboratedType(const ElaboratedType *T); 74206084Srdivacky // FIXME: DependentNameType 75210299Sed // FIXME: DependentTemplateSpecializationType 76218893Sdim QualType VisitObjCInterfaceType(const ObjCInterfaceType *T); 77218893Sdim QualType VisitObjCObjectType(const ObjCObjectType *T); 78218893Sdim QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T); 79203955Srdivacky 80235633Sdim // Importing declarations 81203955Srdivacky bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, 82203955Srdivacky DeclContext *&LexicalDC, DeclarationName &Name, 83204643Srdivacky SourceLocation &Loc); 84226890Sdim void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0); 85212904Sdim void ImportDeclarationNameLoc(const DeclarationNameInfo &From, 86212904Sdim DeclarationNameInfo& To); 87218893Sdim void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); 88235633Sdim 89235633Sdim /// \brief What we should import from the definition. 90235633Sdim enum ImportDefinitionKind { 91235633Sdim /// \brief Import the default subset of the definition, which might be 92235633Sdim /// nothing (if minimal import is set) or might be everything (if minimal 93235633Sdim /// import is not set). 94235633Sdim IDK_Default, 95235633Sdim /// \brief Import everything. 96235633Sdim IDK_Everything, 97235633Sdim /// \brief Import only the bare bones needed to establish a valid 98235633Sdim /// DeclContext. 99235633Sdim IDK_Basic 100235633Sdim }; 101235633Sdim 102235633Sdim bool shouldForceImportDeclContext(ImportDefinitionKind IDK) { 103235633Sdim return IDK == IDK_Everything || 104235633Sdim (IDK == IDK_Default && !Importer.isMinimalImport()); 105235633Sdim } 106235633Sdim 107226890Sdim bool ImportDefinition(RecordDecl *From, RecordDecl *To, 108235633Sdim ImportDefinitionKind Kind = IDK_Default); 109263509Sdim bool ImportDefinition(VarDecl *From, VarDecl *To, 110263509Sdim ImportDefinitionKind Kind = IDK_Default); 111226890Sdim bool ImportDefinition(EnumDecl *From, EnumDecl *To, 112235633Sdim ImportDefinitionKind Kind = IDK_Default); 113235633Sdim bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To, 114235633Sdim ImportDefinitionKind Kind = IDK_Default); 115235633Sdim bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To, 116235633Sdim ImportDefinitionKind Kind = IDK_Default); 117218893Sdim TemplateParameterList *ImportTemplateParameterList( 118218893Sdim TemplateParameterList *Params); 119218893Sdim TemplateArgument ImportTemplateArgument(const TemplateArgument &From); 120218893Sdim bool ImportTemplateArguments(const TemplateArgument *FromArgs, 121218893Sdim unsigned NumFromArgs, 122226890Sdim SmallVectorImpl<TemplateArgument> &ToArgs); 123245431Sdim bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, 124245431Sdim bool Complain = true); 125263509Sdim bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, 126263509Sdim bool Complain = true); 127203955Srdivacky bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); 128252723Sdim bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); 129218893Sdim bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); 130263509Sdim bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); 131203955Srdivacky Decl *VisitDecl(Decl *D); 132235633Sdim Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); 133204643Srdivacky Decl *VisitNamespaceDecl(NamespaceDecl *D); 134221345Sdim Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); 135203955Srdivacky Decl *VisitTypedefDecl(TypedefDecl *D); 136221345Sdim Decl *VisitTypeAliasDecl(TypeAliasDecl *D); 137203955Srdivacky Decl *VisitEnumDecl(EnumDecl *D); 138203955Srdivacky Decl *VisitRecordDecl(RecordDecl *D); 139203955Srdivacky Decl *VisitEnumConstantDecl(EnumConstantDecl *D); 140203955Srdivacky Decl *VisitFunctionDecl(FunctionDecl *D); 141204643Srdivacky Decl *VisitCXXMethodDecl(CXXMethodDecl *D); 142204643Srdivacky Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); 143204643Srdivacky Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); 144204643Srdivacky Decl *VisitCXXConversionDecl(CXXConversionDecl *D); 145203955Srdivacky Decl *VisitFieldDecl(FieldDecl *D); 146218893Sdim Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); 147204643Srdivacky Decl *VisitObjCIvarDecl(ObjCIvarDecl *D); 148203955Srdivacky Decl *VisitVarDecl(VarDecl *D); 149204643Srdivacky Decl *VisitImplicitParamDecl(ImplicitParamDecl *D); 150203955Srdivacky Decl *VisitParmVarDecl(ParmVarDecl *D); 151204643Srdivacky Decl *VisitObjCMethodDecl(ObjCMethodDecl *D); 152204643Srdivacky Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D); 153204643Srdivacky Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D); 154203955Srdivacky Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 155218893Sdim Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 156218893Sdim Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D); 157204643Srdivacky Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D); 158218893Sdim Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); 159218893Sdim Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 160218893Sdim Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); 161218893Sdim Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); 162218893Sdim Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); 163218893Sdim Decl *VisitClassTemplateSpecializationDecl( 164218893Sdim ClassTemplateSpecializationDecl *D); 165263509Sdim Decl *VisitVarTemplateDecl(VarTemplateDecl *D); 166263509Sdim Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); 167263509Sdim 168203955Srdivacky // Importing statements 169203955Srdivacky Stmt *VisitStmt(Stmt *S); 170203955Srdivacky 171203955Srdivacky // Importing expressions 172203955Srdivacky Expr *VisitExpr(Expr *E); 173204643Srdivacky Expr *VisitDeclRefExpr(DeclRefExpr *E); 174203955Srdivacky Expr *VisitIntegerLiteral(IntegerLiteral *E); 175204643Srdivacky Expr *VisitCharacterLiteral(CharacterLiteral *E); 176204643Srdivacky Expr *VisitParenExpr(ParenExpr *E); 177204643Srdivacky Expr *VisitUnaryOperator(UnaryOperator *E); 178221345Sdim Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); 179204643Srdivacky Expr *VisitBinaryOperator(BinaryOperator *E); 180204643Srdivacky Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); 181203955Srdivacky Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); 182204643Srdivacky Expr *VisitCStyleCastExpr(CStyleCastExpr *E); 183203955Srdivacky }; 184203955Srdivacky} 185235633Sdimusing namespace clang; 186203955Srdivacky 187203955Srdivacky//---------------------------------------------------------------------------- 188203955Srdivacky// Structural Equivalence 189203955Srdivacky//---------------------------------------------------------------------------- 190203955Srdivacky 191203955Srdivackynamespace { 192203955Srdivacky struct StructuralEquivalenceContext { 193203955Srdivacky /// \brief AST contexts for which we are checking structural equivalence. 194203955Srdivacky ASTContext &C1, &C2; 195203955Srdivacky 196203955Srdivacky /// \brief The set of "tentative" equivalences between two canonical 197203955Srdivacky /// declarations, mapping from a declaration in the first context to the 198203955Srdivacky /// declaration in the second context that we believe to be equivalent. 199203955Srdivacky llvm::DenseMap<Decl *, Decl *> TentativeEquivalences; 200203955Srdivacky 201203955Srdivacky /// \brief Queue of declarations in the first context whose equivalence 202203955Srdivacky /// with a declaration in the second context still needs to be verified. 203203955Srdivacky std::deque<Decl *> DeclsToCheck; 204203955Srdivacky 205203955Srdivacky /// \brief Declaration (from, to) pairs that are known not to be equivalent 206203955Srdivacky /// (which we have already complained about). 207203955Srdivacky llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls; 208203955Srdivacky 209203955Srdivacky /// \brief Whether we're being strict about the spelling of types when 210203955Srdivacky /// unifying two types. 211203955Srdivacky bool StrictTypeSpelling; 212245431Sdim 213245431Sdim /// \brief Whether to complain about failures. 214245431Sdim bool Complain; 215245431Sdim 216252723Sdim /// \brief \c true if the last diagnostic came from C2. 217252723Sdim bool LastDiagFromC2; 218252723Sdim 219203955Srdivacky StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2, 220203955Srdivacky llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls, 221245431Sdim bool StrictTypeSpelling = false, 222245431Sdim bool Complain = true) 223218893Sdim : C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls), 224252723Sdim StrictTypeSpelling(StrictTypeSpelling), Complain(Complain), 225252723Sdim LastDiagFromC2(false) {} 226203955Srdivacky 227203955Srdivacky /// \brief Determine whether the two declarations are structurally 228203955Srdivacky /// equivalent. 229203955Srdivacky bool IsStructurallyEquivalent(Decl *D1, Decl *D2); 230203955Srdivacky 231203955Srdivacky /// \brief Determine whether the two types are structurally equivalent. 232203955Srdivacky bool IsStructurallyEquivalent(QualType T1, QualType T2); 233203955Srdivacky 234203955Srdivacky private: 235203955Srdivacky /// \brief Finish checking all of the structural equivalences. 236203955Srdivacky /// 237203955Srdivacky /// \returns true if an error occurred, false otherwise. 238203955Srdivacky bool Finish(); 239203955Srdivacky 240203955Srdivacky public: 241203955Srdivacky DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) { 242245431Sdim assert(Complain && "Not allowed to complain"); 243252723Sdim if (LastDiagFromC2) 244252723Sdim C1.getDiagnostics().notePriorDiagnosticFrom(C2.getDiagnostics()); 245252723Sdim LastDiagFromC2 = false; 246218893Sdim return C1.getDiagnostics().Report(Loc, DiagID); 247203955Srdivacky } 248203955Srdivacky 249203955Srdivacky DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) { 250245431Sdim assert(Complain && "Not allowed to complain"); 251252723Sdim if (!LastDiagFromC2) 252252723Sdim C2.getDiagnostics().notePriorDiagnosticFrom(C1.getDiagnostics()); 253252723Sdim LastDiagFromC2 = true; 254218893Sdim return C2.getDiagnostics().Report(Loc, DiagID); 255203955Srdivacky } 256203955Srdivacky }; 257203955Srdivacky} 258203955Srdivacky 259203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 260203955Srdivacky QualType T1, QualType T2); 261203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 262203955Srdivacky Decl *D1, Decl *D2); 263203955Srdivacky 264203955Srdivacky/// \brief Determine structural equivalence of two expressions. 265203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 266203955Srdivacky Expr *E1, Expr *E2) { 267203955Srdivacky if (!E1 || !E2) 268203955Srdivacky return E1 == E2; 269203955Srdivacky 270203955Srdivacky // FIXME: Actually perform a structural comparison! 271203955Srdivacky return true; 272203955Srdivacky} 273203955Srdivacky 274203955Srdivacky/// \brief Determine whether two identifiers are equivalent. 275203955Srdivackystatic bool IsStructurallyEquivalent(const IdentifierInfo *Name1, 276203955Srdivacky const IdentifierInfo *Name2) { 277203955Srdivacky if (!Name1 || !Name2) 278203955Srdivacky return Name1 == Name2; 279203955Srdivacky 280203955Srdivacky return Name1->getName() == Name2->getName(); 281203955Srdivacky} 282203955Srdivacky 283203955Srdivacky/// \brief Determine whether two nested-name-specifiers are equivalent. 284203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 285203955Srdivacky NestedNameSpecifier *NNS1, 286203955Srdivacky NestedNameSpecifier *NNS2) { 287203955Srdivacky // FIXME: Implement! 288203955Srdivacky return true; 289203955Srdivacky} 290203955Srdivacky 291203955Srdivacky/// \brief Determine whether two template arguments are equivalent. 292203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 293203955Srdivacky const TemplateArgument &Arg1, 294203955Srdivacky const TemplateArgument &Arg2) { 295218893Sdim if (Arg1.getKind() != Arg2.getKind()) 296218893Sdim return false; 297218893Sdim 298218893Sdim switch (Arg1.getKind()) { 299218893Sdim case TemplateArgument::Null: 300218893Sdim return true; 301218893Sdim 302218893Sdim case TemplateArgument::Type: 303218893Sdim return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType()); 304245431Sdim 305218893Sdim case TemplateArgument::Integral: 306218893Sdim if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(), 307218893Sdim Arg2.getIntegralType())) 308218893Sdim return false; 309218893Sdim 310245431Sdim return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral()); 311218893Sdim 312218893Sdim case TemplateArgument::Declaration: 313218893Sdim return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl()); 314245431Sdim 315245431Sdim case TemplateArgument::NullPtr: 316245431Sdim return true; // FIXME: Is this correct? 317245431Sdim 318218893Sdim case TemplateArgument::Template: 319218893Sdim return IsStructurallyEquivalent(Context, 320218893Sdim Arg1.getAsTemplate(), 321218893Sdim Arg2.getAsTemplate()); 322218893Sdim 323218893Sdim case TemplateArgument::TemplateExpansion: 324218893Sdim return IsStructurallyEquivalent(Context, 325218893Sdim Arg1.getAsTemplateOrTemplatePattern(), 326218893Sdim Arg2.getAsTemplateOrTemplatePattern()); 327218893Sdim 328218893Sdim case TemplateArgument::Expression: 329218893Sdim return IsStructurallyEquivalent(Context, 330218893Sdim Arg1.getAsExpr(), Arg2.getAsExpr()); 331218893Sdim 332218893Sdim case TemplateArgument::Pack: 333218893Sdim if (Arg1.pack_size() != Arg2.pack_size()) 334218893Sdim return false; 335218893Sdim 336218893Sdim for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I) 337218893Sdim if (!IsStructurallyEquivalent(Context, 338218893Sdim Arg1.pack_begin()[I], 339218893Sdim Arg2.pack_begin()[I])) 340218893Sdim return false; 341218893Sdim 342218893Sdim return true; 343218893Sdim } 344218893Sdim 345218893Sdim llvm_unreachable("Invalid template argument kind"); 346203955Srdivacky} 347203955Srdivacky 348203955Srdivacky/// \brief Determine structural equivalence for the common part of array 349203955Srdivacky/// types. 350203955Srdivackystatic bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context, 351203955Srdivacky const ArrayType *Array1, 352203955Srdivacky const ArrayType *Array2) { 353203955Srdivacky if (!IsStructurallyEquivalent(Context, 354203955Srdivacky Array1->getElementType(), 355203955Srdivacky Array2->getElementType())) 356203955Srdivacky return false; 357203955Srdivacky if (Array1->getSizeModifier() != Array2->getSizeModifier()) 358203955Srdivacky return false; 359203955Srdivacky if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers()) 360203955Srdivacky return false; 361203955Srdivacky 362203955Srdivacky return true; 363203955Srdivacky} 364203955Srdivacky 365203955Srdivacky/// \brief Determine structural equivalence of two types. 366203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 367203955Srdivacky QualType T1, QualType T2) { 368203955Srdivacky if (T1.isNull() || T2.isNull()) 369203955Srdivacky return T1.isNull() && T2.isNull(); 370203955Srdivacky 371203955Srdivacky if (!Context.StrictTypeSpelling) { 372203955Srdivacky // We aren't being strict about token-to-token equivalence of types, 373203955Srdivacky // so map down to the canonical type. 374203955Srdivacky T1 = Context.C1.getCanonicalType(T1); 375203955Srdivacky T2 = Context.C2.getCanonicalType(T2); 376203955Srdivacky } 377203955Srdivacky 378203955Srdivacky if (T1.getQualifiers() != T2.getQualifiers()) 379203955Srdivacky return false; 380203955Srdivacky 381203955Srdivacky Type::TypeClass TC = T1->getTypeClass(); 382203955Srdivacky 383203955Srdivacky if (T1->getTypeClass() != T2->getTypeClass()) { 384203955Srdivacky // Compare function types with prototypes vs. without prototypes as if 385203955Srdivacky // both did not have prototypes. 386203955Srdivacky if (T1->getTypeClass() == Type::FunctionProto && 387203955Srdivacky T2->getTypeClass() == Type::FunctionNoProto) 388203955Srdivacky TC = Type::FunctionNoProto; 389203955Srdivacky else if (T1->getTypeClass() == Type::FunctionNoProto && 390203955Srdivacky T2->getTypeClass() == Type::FunctionProto) 391203955Srdivacky TC = Type::FunctionNoProto; 392203955Srdivacky else 393203955Srdivacky return false; 394203955Srdivacky } 395203955Srdivacky 396203955Srdivacky switch (TC) { 397203955Srdivacky case Type::Builtin: 398203955Srdivacky // FIXME: Deal with Char_S/Char_U. 399203955Srdivacky if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind()) 400203955Srdivacky return false; 401203955Srdivacky break; 402203955Srdivacky 403203955Srdivacky case Type::Complex: 404203955Srdivacky if (!IsStructurallyEquivalent(Context, 405203955Srdivacky cast<ComplexType>(T1)->getElementType(), 406203955Srdivacky cast<ComplexType>(T2)->getElementType())) 407203955Srdivacky return false; 408203955Srdivacky break; 409203955Srdivacky 410263509Sdim case Type::Decayed: 411263509Sdim if (!IsStructurallyEquivalent(Context, 412263509Sdim cast<DecayedType>(T1)->getPointeeType(), 413263509Sdim cast<DecayedType>(T2)->getPointeeType())) 414263509Sdim return false; 415263509Sdim break; 416263509Sdim 417203955Srdivacky case Type::Pointer: 418203955Srdivacky if (!IsStructurallyEquivalent(Context, 419203955Srdivacky cast<PointerType>(T1)->getPointeeType(), 420203955Srdivacky cast<PointerType>(T2)->getPointeeType())) 421203955Srdivacky return false; 422203955Srdivacky break; 423203955Srdivacky 424203955Srdivacky case Type::BlockPointer: 425203955Srdivacky if (!IsStructurallyEquivalent(Context, 426203955Srdivacky cast<BlockPointerType>(T1)->getPointeeType(), 427203955Srdivacky cast<BlockPointerType>(T2)->getPointeeType())) 428203955Srdivacky return false; 429203955Srdivacky break; 430203955Srdivacky 431203955Srdivacky case Type::LValueReference: 432203955Srdivacky case Type::RValueReference: { 433203955Srdivacky const ReferenceType *Ref1 = cast<ReferenceType>(T1); 434203955Srdivacky const ReferenceType *Ref2 = cast<ReferenceType>(T2); 435203955Srdivacky if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue()) 436203955Srdivacky return false; 437203955Srdivacky if (Ref1->isInnerRef() != Ref2->isInnerRef()) 438203955Srdivacky return false; 439203955Srdivacky if (!IsStructurallyEquivalent(Context, 440203955Srdivacky Ref1->getPointeeTypeAsWritten(), 441203955Srdivacky Ref2->getPointeeTypeAsWritten())) 442203955Srdivacky return false; 443203955Srdivacky break; 444203955Srdivacky } 445203955Srdivacky 446203955Srdivacky case Type::MemberPointer: { 447203955Srdivacky const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1); 448203955Srdivacky const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2); 449203955Srdivacky if (!IsStructurallyEquivalent(Context, 450203955Srdivacky MemPtr1->getPointeeType(), 451203955Srdivacky MemPtr2->getPointeeType())) 452203955Srdivacky return false; 453203955Srdivacky if (!IsStructurallyEquivalent(Context, 454203955Srdivacky QualType(MemPtr1->getClass(), 0), 455203955Srdivacky QualType(MemPtr2->getClass(), 0))) 456203955Srdivacky return false; 457203955Srdivacky break; 458203955Srdivacky } 459203955Srdivacky 460203955Srdivacky case Type::ConstantArray: { 461203955Srdivacky const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1); 462203955Srdivacky const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2); 463245431Sdim if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize())) 464203955Srdivacky return false; 465203955Srdivacky 466203955Srdivacky if (!IsArrayStructurallyEquivalent(Context, Array1, Array2)) 467203955Srdivacky return false; 468203955Srdivacky break; 469203955Srdivacky } 470203955Srdivacky 471203955Srdivacky case Type::IncompleteArray: 472203955Srdivacky if (!IsArrayStructurallyEquivalent(Context, 473203955Srdivacky cast<ArrayType>(T1), 474203955Srdivacky cast<ArrayType>(T2))) 475203955Srdivacky return false; 476203955Srdivacky break; 477203955Srdivacky 478203955Srdivacky case Type::VariableArray: { 479203955Srdivacky const VariableArrayType *Array1 = cast<VariableArrayType>(T1); 480203955Srdivacky const VariableArrayType *Array2 = cast<VariableArrayType>(T2); 481203955Srdivacky if (!IsStructurallyEquivalent(Context, 482203955Srdivacky Array1->getSizeExpr(), Array2->getSizeExpr())) 483203955Srdivacky return false; 484203955Srdivacky 485203955Srdivacky if (!IsArrayStructurallyEquivalent(Context, Array1, Array2)) 486203955Srdivacky return false; 487203955Srdivacky 488203955Srdivacky break; 489203955Srdivacky } 490203955Srdivacky 491203955Srdivacky case Type::DependentSizedArray: { 492203955Srdivacky const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1); 493203955Srdivacky const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2); 494203955Srdivacky if (!IsStructurallyEquivalent(Context, 495203955Srdivacky Array1->getSizeExpr(), Array2->getSizeExpr())) 496203955Srdivacky return false; 497203955Srdivacky 498203955Srdivacky if (!IsArrayStructurallyEquivalent(Context, Array1, Array2)) 499203955Srdivacky return false; 500203955Srdivacky 501203955Srdivacky break; 502203955Srdivacky } 503203955Srdivacky 504203955Srdivacky case Type::DependentSizedExtVector: { 505203955Srdivacky const DependentSizedExtVectorType *Vec1 506203955Srdivacky = cast<DependentSizedExtVectorType>(T1); 507203955Srdivacky const DependentSizedExtVectorType *Vec2 508203955Srdivacky = cast<DependentSizedExtVectorType>(T2); 509203955Srdivacky if (!IsStructurallyEquivalent(Context, 510203955Srdivacky Vec1->getSizeExpr(), Vec2->getSizeExpr())) 511203955Srdivacky return false; 512203955Srdivacky if (!IsStructurallyEquivalent(Context, 513203955Srdivacky Vec1->getElementType(), 514203955Srdivacky Vec2->getElementType())) 515203955Srdivacky return false; 516203955Srdivacky break; 517203955Srdivacky } 518203955Srdivacky 519203955Srdivacky case Type::Vector: 520203955Srdivacky case Type::ExtVector: { 521203955Srdivacky const VectorType *Vec1 = cast<VectorType>(T1); 522203955Srdivacky const VectorType *Vec2 = cast<VectorType>(T2); 523203955Srdivacky if (!IsStructurallyEquivalent(Context, 524203955Srdivacky Vec1->getElementType(), 525203955Srdivacky Vec2->getElementType())) 526203955Srdivacky return false; 527203955Srdivacky if (Vec1->getNumElements() != Vec2->getNumElements()) 528203955Srdivacky return false; 529218893Sdim if (Vec1->getVectorKind() != Vec2->getVectorKind()) 530203955Srdivacky return false; 531204643Srdivacky break; 532203955Srdivacky } 533203955Srdivacky 534203955Srdivacky case Type::FunctionProto: { 535203955Srdivacky const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1); 536203955Srdivacky const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2); 537203955Srdivacky if (Proto1->getNumArgs() != Proto2->getNumArgs()) 538203955Srdivacky return false; 539203955Srdivacky for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) { 540203955Srdivacky if (!IsStructurallyEquivalent(Context, 541203955Srdivacky Proto1->getArgType(I), 542203955Srdivacky Proto2->getArgType(I))) 543203955Srdivacky return false; 544203955Srdivacky } 545203955Srdivacky if (Proto1->isVariadic() != Proto2->isVariadic()) 546203955Srdivacky return false; 547221345Sdim if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType()) 548203955Srdivacky return false; 549221345Sdim if (Proto1->getExceptionSpecType() == EST_Dynamic) { 550221345Sdim if (Proto1->getNumExceptions() != Proto2->getNumExceptions()) 551221345Sdim return false; 552221345Sdim for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) { 553221345Sdim if (!IsStructurallyEquivalent(Context, 554221345Sdim Proto1->getExceptionType(I), 555221345Sdim Proto2->getExceptionType(I))) 556221345Sdim return false; 557221345Sdim } 558221345Sdim } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) { 559203955Srdivacky if (!IsStructurallyEquivalent(Context, 560221345Sdim Proto1->getNoexceptExpr(), 561221345Sdim Proto2->getNoexceptExpr())) 562203955Srdivacky return false; 563203955Srdivacky } 564203955Srdivacky if (Proto1->getTypeQuals() != Proto2->getTypeQuals()) 565203955Srdivacky return false; 566203955Srdivacky 567203955Srdivacky // Fall through to check the bits common with FunctionNoProtoType. 568203955Srdivacky } 569203955Srdivacky 570203955Srdivacky case Type::FunctionNoProto: { 571203955Srdivacky const FunctionType *Function1 = cast<FunctionType>(T1); 572203955Srdivacky const FunctionType *Function2 = cast<FunctionType>(T2); 573203955Srdivacky if (!IsStructurallyEquivalent(Context, 574203955Srdivacky Function1->getResultType(), 575203955Srdivacky Function2->getResultType())) 576203955Srdivacky return false; 577206084Srdivacky if (Function1->getExtInfo() != Function2->getExtInfo()) 578206084Srdivacky return false; 579203955Srdivacky break; 580203955Srdivacky } 581203955Srdivacky 582203955Srdivacky case Type::UnresolvedUsing: 583203955Srdivacky if (!IsStructurallyEquivalent(Context, 584203955Srdivacky cast<UnresolvedUsingType>(T1)->getDecl(), 585203955Srdivacky cast<UnresolvedUsingType>(T2)->getDecl())) 586203955Srdivacky return false; 587203955Srdivacky 588203955Srdivacky break; 589218893Sdim 590218893Sdim case Type::Attributed: 591218893Sdim if (!IsStructurallyEquivalent(Context, 592218893Sdim cast<AttributedType>(T1)->getModifiedType(), 593218893Sdim cast<AttributedType>(T2)->getModifiedType())) 594218893Sdim return false; 595218893Sdim if (!IsStructurallyEquivalent(Context, 596218893Sdim cast<AttributedType>(T1)->getEquivalentType(), 597218893Sdim cast<AttributedType>(T2)->getEquivalentType())) 598218893Sdim return false; 599218893Sdim break; 600203955Srdivacky 601218893Sdim case Type::Paren: 602218893Sdim if (!IsStructurallyEquivalent(Context, 603218893Sdim cast<ParenType>(T1)->getInnerType(), 604218893Sdim cast<ParenType>(T2)->getInnerType())) 605218893Sdim return false; 606218893Sdim break; 607218893Sdim 608203955Srdivacky case Type::Typedef: 609203955Srdivacky if (!IsStructurallyEquivalent(Context, 610203955Srdivacky cast<TypedefType>(T1)->getDecl(), 611203955Srdivacky cast<TypedefType>(T2)->getDecl())) 612203955Srdivacky return false; 613203955Srdivacky break; 614203955Srdivacky 615203955Srdivacky case Type::TypeOfExpr: 616203955Srdivacky if (!IsStructurallyEquivalent(Context, 617203955Srdivacky cast<TypeOfExprType>(T1)->getUnderlyingExpr(), 618203955Srdivacky cast<TypeOfExprType>(T2)->getUnderlyingExpr())) 619203955Srdivacky return false; 620203955Srdivacky break; 621203955Srdivacky 622203955Srdivacky case Type::TypeOf: 623203955Srdivacky if (!IsStructurallyEquivalent(Context, 624203955Srdivacky cast<TypeOfType>(T1)->getUnderlyingType(), 625203955Srdivacky cast<TypeOfType>(T2)->getUnderlyingType())) 626203955Srdivacky return false; 627203955Srdivacky break; 628223017Sdim 629223017Sdim case Type::UnaryTransform: 630223017Sdim if (!IsStructurallyEquivalent(Context, 631223017Sdim cast<UnaryTransformType>(T1)->getUnderlyingType(), 632223017Sdim cast<UnaryTransformType>(T1)->getUnderlyingType())) 633223017Sdim return false; 634223017Sdim break; 635223017Sdim 636203955Srdivacky case Type::Decltype: 637203955Srdivacky if (!IsStructurallyEquivalent(Context, 638203955Srdivacky cast<DecltypeType>(T1)->getUnderlyingExpr(), 639203955Srdivacky cast<DecltypeType>(T2)->getUnderlyingExpr())) 640203955Srdivacky return false; 641203955Srdivacky break; 642203955Srdivacky 643218893Sdim case Type::Auto: 644218893Sdim if (!IsStructurallyEquivalent(Context, 645218893Sdim cast<AutoType>(T1)->getDeducedType(), 646218893Sdim cast<AutoType>(T2)->getDeducedType())) 647218893Sdim return false; 648218893Sdim break; 649218893Sdim 650203955Srdivacky case Type::Record: 651203955Srdivacky case Type::Enum: 652203955Srdivacky if (!IsStructurallyEquivalent(Context, 653203955Srdivacky cast<TagType>(T1)->getDecl(), 654203955Srdivacky cast<TagType>(T2)->getDecl())) 655203955Srdivacky return false; 656203955Srdivacky break; 657208600Srdivacky 658203955Srdivacky case Type::TemplateTypeParm: { 659203955Srdivacky const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1); 660203955Srdivacky const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2); 661203955Srdivacky if (Parm1->getDepth() != Parm2->getDepth()) 662203955Srdivacky return false; 663203955Srdivacky if (Parm1->getIndex() != Parm2->getIndex()) 664203955Srdivacky return false; 665203955Srdivacky if (Parm1->isParameterPack() != Parm2->isParameterPack()) 666203955Srdivacky return false; 667203955Srdivacky 668203955Srdivacky // Names of template type parameters are never significant. 669203955Srdivacky break; 670203955Srdivacky } 671203955Srdivacky 672203955Srdivacky case Type::SubstTemplateTypeParm: { 673203955Srdivacky const SubstTemplateTypeParmType *Subst1 674203955Srdivacky = cast<SubstTemplateTypeParmType>(T1); 675203955Srdivacky const SubstTemplateTypeParmType *Subst2 676203955Srdivacky = cast<SubstTemplateTypeParmType>(T2); 677203955Srdivacky if (!IsStructurallyEquivalent(Context, 678203955Srdivacky QualType(Subst1->getReplacedParameter(), 0), 679203955Srdivacky QualType(Subst2->getReplacedParameter(), 0))) 680203955Srdivacky return false; 681203955Srdivacky if (!IsStructurallyEquivalent(Context, 682203955Srdivacky Subst1->getReplacementType(), 683203955Srdivacky Subst2->getReplacementType())) 684203955Srdivacky return false; 685203955Srdivacky break; 686203955Srdivacky } 687203955Srdivacky 688218893Sdim case Type::SubstTemplateTypeParmPack: { 689218893Sdim const SubstTemplateTypeParmPackType *Subst1 690218893Sdim = cast<SubstTemplateTypeParmPackType>(T1); 691218893Sdim const SubstTemplateTypeParmPackType *Subst2 692218893Sdim = cast<SubstTemplateTypeParmPackType>(T2); 693218893Sdim if (!IsStructurallyEquivalent(Context, 694218893Sdim QualType(Subst1->getReplacedParameter(), 0), 695218893Sdim QualType(Subst2->getReplacedParameter(), 0))) 696218893Sdim return false; 697218893Sdim if (!IsStructurallyEquivalent(Context, 698218893Sdim Subst1->getArgumentPack(), 699218893Sdim Subst2->getArgumentPack())) 700218893Sdim return false; 701218893Sdim break; 702218893Sdim } 703203955Srdivacky case Type::TemplateSpecialization: { 704203955Srdivacky const TemplateSpecializationType *Spec1 705203955Srdivacky = cast<TemplateSpecializationType>(T1); 706203955Srdivacky const TemplateSpecializationType *Spec2 707203955Srdivacky = cast<TemplateSpecializationType>(T2); 708203955Srdivacky if (!IsStructurallyEquivalent(Context, 709203955Srdivacky Spec1->getTemplateName(), 710203955Srdivacky Spec2->getTemplateName())) 711203955Srdivacky return false; 712203955Srdivacky if (Spec1->getNumArgs() != Spec2->getNumArgs()) 713203955Srdivacky return false; 714203955Srdivacky for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) { 715203955Srdivacky if (!IsStructurallyEquivalent(Context, 716203955Srdivacky Spec1->getArg(I), Spec2->getArg(I))) 717203955Srdivacky return false; 718203955Srdivacky } 719203955Srdivacky break; 720203955Srdivacky } 721203955Srdivacky 722208600Srdivacky case Type::Elaborated: { 723208600Srdivacky const ElaboratedType *Elab1 = cast<ElaboratedType>(T1); 724208600Srdivacky const ElaboratedType *Elab2 = cast<ElaboratedType>(T2); 725208600Srdivacky // CHECKME: what if a keyword is ETK_None or ETK_typename ? 726208600Srdivacky if (Elab1->getKeyword() != Elab2->getKeyword()) 727208600Srdivacky return false; 728203955Srdivacky if (!IsStructurallyEquivalent(Context, 729208600Srdivacky Elab1->getQualifier(), 730208600Srdivacky Elab2->getQualifier())) 731203955Srdivacky return false; 732203955Srdivacky if (!IsStructurallyEquivalent(Context, 733208600Srdivacky Elab1->getNamedType(), 734208600Srdivacky Elab2->getNamedType())) 735203955Srdivacky return false; 736203955Srdivacky break; 737203955Srdivacky } 738203955Srdivacky 739204962Srdivacky case Type::InjectedClassName: { 740204962Srdivacky const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1); 741204962Srdivacky const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2); 742204962Srdivacky if (!IsStructurallyEquivalent(Context, 743207619Srdivacky Inj1->getInjectedSpecializationType(), 744207619Srdivacky Inj2->getInjectedSpecializationType())) 745204962Srdivacky return false; 746204962Srdivacky break; 747204962Srdivacky } 748204962Srdivacky 749206084Srdivacky case Type::DependentName: { 750206084Srdivacky const DependentNameType *Typename1 = cast<DependentNameType>(T1); 751206084Srdivacky const DependentNameType *Typename2 = cast<DependentNameType>(T2); 752203955Srdivacky if (!IsStructurallyEquivalent(Context, 753203955Srdivacky Typename1->getQualifier(), 754203955Srdivacky Typename2->getQualifier())) 755203955Srdivacky return false; 756203955Srdivacky if (!IsStructurallyEquivalent(Typename1->getIdentifier(), 757203955Srdivacky Typename2->getIdentifier())) 758203955Srdivacky return false; 759203955Srdivacky 760203955Srdivacky break; 761203955Srdivacky } 762203955Srdivacky 763210299Sed case Type::DependentTemplateSpecialization: { 764210299Sed const DependentTemplateSpecializationType *Spec1 = 765210299Sed cast<DependentTemplateSpecializationType>(T1); 766210299Sed const DependentTemplateSpecializationType *Spec2 = 767210299Sed cast<DependentTemplateSpecializationType>(T2); 768210299Sed if (!IsStructurallyEquivalent(Context, 769210299Sed Spec1->getQualifier(), 770210299Sed Spec2->getQualifier())) 771210299Sed return false; 772210299Sed if (!IsStructurallyEquivalent(Spec1->getIdentifier(), 773210299Sed Spec2->getIdentifier())) 774210299Sed return false; 775210299Sed if (Spec1->getNumArgs() != Spec2->getNumArgs()) 776210299Sed return false; 777210299Sed for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) { 778210299Sed if (!IsStructurallyEquivalent(Context, 779210299Sed Spec1->getArg(I), Spec2->getArg(I))) 780210299Sed return false; 781210299Sed } 782210299Sed break; 783210299Sed } 784218893Sdim 785218893Sdim case Type::PackExpansion: 786218893Sdim if (!IsStructurallyEquivalent(Context, 787218893Sdim cast<PackExpansionType>(T1)->getPattern(), 788218893Sdim cast<PackExpansionType>(T2)->getPattern())) 789218893Sdim return false; 790218893Sdim break; 791218893Sdim 792203955Srdivacky case Type::ObjCInterface: { 793203955Srdivacky const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1); 794203955Srdivacky const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2); 795203955Srdivacky if (!IsStructurallyEquivalent(Context, 796203955Srdivacky Iface1->getDecl(), Iface2->getDecl())) 797203955Srdivacky return false; 798208600Srdivacky break; 799208600Srdivacky } 800208600Srdivacky 801208600Srdivacky case Type::ObjCObject: { 802208600Srdivacky const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1); 803208600Srdivacky const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2); 804208600Srdivacky if (!IsStructurallyEquivalent(Context, 805208600Srdivacky Obj1->getBaseType(), 806208600Srdivacky Obj2->getBaseType())) 807203955Srdivacky return false; 808208600Srdivacky if (Obj1->getNumProtocols() != Obj2->getNumProtocols()) 809208600Srdivacky return false; 810208600Srdivacky for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) { 811203955Srdivacky if (!IsStructurallyEquivalent(Context, 812208600Srdivacky Obj1->getProtocol(I), 813208600Srdivacky Obj2->getProtocol(I))) 814203955Srdivacky return false; 815203955Srdivacky } 816203955Srdivacky break; 817203955Srdivacky } 818203955Srdivacky 819203955Srdivacky case Type::ObjCObjectPointer: { 820203955Srdivacky const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1); 821203955Srdivacky const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2); 822203955Srdivacky if (!IsStructurallyEquivalent(Context, 823203955Srdivacky Ptr1->getPointeeType(), 824203955Srdivacky Ptr2->getPointeeType())) 825203955Srdivacky return false; 826203955Srdivacky break; 827203955Srdivacky } 828226890Sdim 829226890Sdim case Type::Atomic: { 830226890Sdim if (!IsStructurallyEquivalent(Context, 831226890Sdim cast<AtomicType>(T1)->getValueType(), 832226890Sdim cast<AtomicType>(T2)->getValueType())) 833226890Sdim return false; 834226890Sdim break; 835226890Sdim } 836226890Sdim 837203955Srdivacky } // end switch 838203955Srdivacky 839203955Srdivacky return true; 840203955Srdivacky} 841203955Srdivacky 842226890Sdim/// \brief Determine structural equivalence of two fields. 843226890Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 844226890Sdim FieldDecl *Field1, FieldDecl *Field2) { 845226890Sdim RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext()); 846245431Sdim 847245431Sdim // For anonymous structs/unions, match up the anonymous struct/union type 848245431Sdim // declarations directly, so that we don't go off searching for anonymous 849245431Sdim // types 850245431Sdim if (Field1->isAnonymousStructOrUnion() && 851245431Sdim Field2->isAnonymousStructOrUnion()) { 852245431Sdim RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl(); 853245431Sdim RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl(); 854245431Sdim return IsStructurallyEquivalent(Context, D1, D2); 855245431Sdim } 856252723Sdim 857252723Sdim // Check for equivalent field names. 858252723Sdim IdentifierInfo *Name1 = Field1->getIdentifier(); 859252723Sdim IdentifierInfo *Name2 = Field2->getIdentifier(); 860252723Sdim if (!::IsStructurallyEquivalent(Name1, Name2)) 861252723Sdim return false; 862245431Sdim 863245431Sdim if (!IsStructurallyEquivalent(Context, 864226890Sdim Field1->getType(), Field2->getType())) { 865245431Sdim if (Context.Complain) { 866245431Sdim Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent) 867245431Sdim << Context.C2.getTypeDeclType(Owner2); 868245431Sdim Context.Diag2(Field2->getLocation(), diag::note_odr_field) 869245431Sdim << Field2->getDeclName() << Field2->getType(); 870245431Sdim Context.Diag1(Field1->getLocation(), diag::note_odr_field) 871245431Sdim << Field1->getDeclName() << Field1->getType(); 872245431Sdim } 873226890Sdim return false; 874226890Sdim } 875226890Sdim 876226890Sdim if (Field1->isBitField() != Field2->isBitField()) { 877245431Sdim if (Context.Complain) { 878245431Sdim Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent) 879245431Sdim << Context.C2.getTypeDeclType(Owner2); 880245431Sdim if (Field1->isBitField()) { 881245431Sdim Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field) 882245431Sdim << Field1->getDeclName() << Field1->getType() 883245431Sdim << Field1->getBitWidthValue(Context.C1); 884245431Sdim Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field) 885245431Sdim << Field2->getDeclName(); 886245431Sdim } else { 887245431Sdim Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field) 888245431Sdim << Field2->getDeclName() << Field2->getType() 889245431Sdim << Field2->getBitWidthValue(Context.C2); 890245431Sdim Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field) 891245431Sdim << Field1->getDeclName(); 892245431Sdim } 893226890Sdim } 894226890Sdim return false; 895226890Sdim } 896226890Sdim 897226890Sdim if (Field1->isBitField()) { 898226890Sdim // Make sure that the bit-fields are the same length. 899226890Sdim unsigned Bits1 = Field1->getBitWidthValue(Context.C1); 900226890Sdim unsigned Bits2 = Field2->getBitWidthValue(Context.C2); 901226890Sdim 902226890Sdim if (Bits1 != Bits2) { 903245431Sdim if (Context.Complain) { 904245431Sdim Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent) 905245431Sdim << Context.C2.getTypeDeclType(Owner2); 906245431Sdim Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field) 907245431Sdim << Field2->getDeclName() << Field2->getType() << Bits2; 908245431Sdim Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field) 909245431Sdim << Field1->getDeclName() << Field1->getType() << Bits1; 910245431Sdim } 911226890Sdim return false; 912226890Sdim } 913226890Sdim } 914226890Sdim 915226890Sdim return true; 916226890Sdim} 917226890Sdim 918245431Sdim/// \brief Find the index of the given anonymous struct/union within its 919245431Sdim/// context. 920245431Sdim/// 921245431Sdim/// \returns Returns the index of this anonymous struct/union in its context, 922245431Sdim/// including the next assigned index (if none of them match). Returns an 923245431Sdim/// empty option if the context is not a record, i.e.. if the anonymous 924245431Sdim/// struct/union is at namespace or block scope. 925252723Sdimstatic Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) { 926245431Sdim ASTContext &Context = Anon->getASTContext(); 927245431Sdim QualType AnonTy = Context.getRecordType(Anon); 928245431Sdim 929245431Sdim RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext()); 930245431Sdim if (!Owner) 931252723Sdim return None; 932245431Sdim 933245431Sdim unsigned Index = 0; 934245431Sdim for (DeclContext::decl_iterator D = Owner->noload_decls_begin(), 935245431Sdim DEnd = Owner->noload_decls_end(); 936245431Sdim D != DEnd; ++D) { 937245431Sdim FieldDecl *F = dyn_cast<FieldDecl>(*D); 938245431Sdim if (!F || !F->isAnonymousStructOrUnion()) 939245431Sdim continue; 940245431Sdim 941245431Sdim if (Context.hasSameType(F->getType(), AnonTy)) 942245431Sdim break; 943245431Sdim 944245431Sdim ++Index; 945245431Sdim } 946245431Sdim 947245431Sdim return Index; 948245431Sdim} 949245431Sdim 950203955Srdivacky/// \brief Determine structural equivalence of two records. 951203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 952203955Srdivacky RecordDecl *D1, RecordDecl *D2) { 953203955Srdivacky if (D1->isUnion() != D2->isUnion()) { 954245431Sdim if (Context.Complain) { 955245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 956245431Sdim << Context.C2.getTypeDeclType(D2); 957245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here) 958245431Sdim << D1->getDeclName() << (unsigned)D1->getTagKind(); 959245431Sdim } 960203955Srdivacky return false; 961203955Srdivacky } 962245431Sdim 963245431Sdim if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) { 964245431Sdim // If both anonymous structs/unions are in a record context, make sure 965245431Sdim // they occur in the same location in the context records. 966252723Sdim if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) { 967252723Sdim if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) { 968245431Sdim if (*Index1 != *Index2) 969245431Sdim return false; 970245431Sdim } 971245431Sdim } 972245431Sdim } 973245431Sdim 974218893Sdim // If both declarations are class template specializations, we know 975218893Sdim // the ODR applies, so check the template and template arguments. 976218893Sdim ClassTemplateSpecializationDecl *Spec1 977218893Sdim = dyn_cast<ClassTemplateSpecializationDecl>(D1); 978218893Sdim ClassTemplateSpecializationDecl *Spec2 979218893Sdim = dyn_cast<ClassTemplateSpecializationDecl>(D2); 980218893Sdim if (Spec1 && Spec2) { 981218893Sdim // Check that the specialized templates are the same. 982218893Sdim if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(), 983218893Sdim Spec2->getSpecializedTemplate())) 984218893Sdim return false; 985218893Sdim 986218893Sdim // Check that the template arguments are the same. 987218893Sdim if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size()) 988218893Sdim return false; 989218893Sdim 990218893Sdim for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I) 991218893Sdim if (!IsStructurallyEquivalent(Context, 992218893Sdim Spec1->getTemplateArgs().get(I), 993218893Sdim Spec2->getTemplateArgs().get(I))) 994218893Sdim return false; 995218893Sdim } 996218893Sdim // If one is a class template specialization and the other is not, these 997221345Sdim // structures are different. 998218893Sdim else if (Spec1 || Spec2) 999218893Sdim return false; 1000218893Sdim 1001203955Srdivacky // Compare the definitions of these two records. If either or both are 1002203955Srdivacky // incomplete, we assume that they are equivalent. 1003203955Srdivacky D1 = D1->getDefinition(); 1004203955Srdivacky D2 = D2->getDefinition(); 1005203955Srdivacky if (!D1 || !D2) 1006203955Srdivacky return true; 1007203955Srdivacky 1008203955Srdivacky if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) { 1009203955Srdivacky if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) { 1010203955Srdivacky if (D1CXX->getNumBases() != D2CXX->getNumBases()) { 1011245431Sdim if (Context.Complain) { 1012245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1013245431Sdim << Context.C2.getTypeDeclType(D2); 1014245431Sdim Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases) 1015245431Sdim << D2CXX->getNumBases(); 1016245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases) 1017245431Sdim << D1CXX->getNumBases(); 1018245431Sdim } 1019203955Srdivacky return false; 1020203955Srdivacky } 1021203955Srdivacky 1022203955Srdivacky // Check the base classes. 1023203955Srdivacky for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(), 1024203955Srdivacky BaseEnd1 = D1CXX->bases_end(), 1025203955Srdivacky Base2 = D2CXX->bases_begin(); 1026203955Srdivacky Base1 != BaseEnd1; 1027203955Srdivacky ++Base1, ++Base2) { 1028203955Srdivacky if (!IsStructurallyEquivalent(Context, 1029203955Srdivacky Base1->getType(), Base2->getType())) { 1030245431Sdim if (Context.Complain) { 1031245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1032245431Sdim << Context.C2.getTypeDeclType(D2); 1033245431Sdim Context.Diag2(Base2->getLocStart(), diag::note_odr_base) 1034245431Sdim << Base2->getType() 1035245431Sdim << Base2->getSourceRange(); 1036245431Sdim Context.Diag1(Base1->getLocStart(), diag::note_odr_base) 1037245431Sdim << Base1->getType() 1038245431Sdim << Base1->getSourceRange(); 1039245431Sdim } 1040203955Srdivacky return false; 1041203955Srdivacky } 1042203955Srdivacky 1043203955Srdivacky // Check virtual vs. non-virtual inheritance mismatch. 1044203955Srdivacky if (Base1->isVirtual() != Base2->isVirtual()) { 1045245431Sdim if (Context.Complain) { 1046245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1047245431Sdim << Context.C2.getTypeDeclType(D2); 1048245431Sdim Context.Diag2(Base2->getLocStart(), 1049245431Sdim diag::note_odr_virtual_base) 1050245431Sdim << Base2->isVirtual() << Base2->getSourceRange(); 1051245431Sdim Context.Diag1(Base1->getLocStart(), diag::note_odr_base) 1052245431Sdim << Base1->isVirtual() 1053245431Sdim << Base1->getSourceRange(); 1054245431Sdim } 1055203955Srdivacky return false; 1056203955Srdivacky } 1057203955Srdivacky } 1058203955Srdivacky } else if (D1CXX->getNumBases() > 0) { 1059245431Sdim if (Context.Complain) { 1060245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1061245431Sdim << Context.C2.getTypeDeclType(D2); 1062245431Sdim const CXXBaseSpecifier *Base1 = D1CXX->bases_begin(); 1063245431Sdim Context.Diag1(Base1->getLocStart(), diag::note_odr_base) 1064245431Sdim << Base1->getType() 1065245431Sdim << Base1->getSourceRange(); 1066245431Sdim Context.Diag2(D2->getLocation(), diag::note_odr_missing_base); 1067245431Sdim } 1068203955Srdivacky return false; 1069203955Srdivacky } 1070203955Srdivacky } 1071203955Srdivacky 1072203955Srdivacky // Check the fields for consistency. 1073245431Sdim RecordDecl::field_iterator Field2 = D2->field_begin(), 1074203955Srdivacky Field2End = D2->field_end(); 1075245431Sdim for (RecordDecl::field_iterator Field1 = D1->field_begin(), 1076203955Srdivacky Field1End = D1->field_end(); 1077203955Srdivacky Field1 != Field1End; 1078203955Srdivacky ++Field1, ++Field2) { 1079203955Srdivacky if (Field2 == Field2End) { 1080245431Sdim if (Context.Complain) { 1081245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1082245431Sdim << Context.C2.getTypeDeclType(D2); 1083245431Sdim Context.Diag1(Field1->getLocation(), diag::note_odr_field) 1084245431Sdim << Field1->getDeclName() << Field1->getType(); 1085245431Sdim Context.Diag2(D2->getLocation(), diag::note_odr_missing_field); 1086245431Sdim } 1087203955Srdivacky return false; 1088203955Srdivacky } 1089203955Srdivacky 1090226890Sdim if (!IsStructurallyEquivalent(Context, *Field1, *Field2)) 1091226890Sdim return false; 1092203955Srdivacky } 1093203955Srdivacky 1094203955Srdivacky if (Field2 != Field2End) { 1095245431Sdim if (Context.Complain) { 1096245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1097245431Sdim << Context.C2.getTypeDeclType(D2); 1098245431Sdim Context.Diag2(Field2->getLocation(), diag::note_odr_field) 1099245431Sdim << Field2->getDeclName() << Field2->getType(); 1100245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_missing_field); 1101245431Sdim } 1102203955Srdivacky return false; 1103203955Srdivacky } 1104203955Srdivacky 1105203955Srdivacky return true; 1106203955Srdivacky} 1107203955Srdivacky 1108203955Srdivacky/// \brief Determine structural equivalence of two enums. 1109203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1110203955Srdivacky EnumDecl *D1, EnumDecl *D2) { 1111203955Srdivacky EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(), 1112203955Srdivacky EC2End = D2->enumerator_end(); 1113203955Srdivacky for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(), 1114203955Srdivacky EC1End = D1->enumerator_end(); 1115203955Srdivacky EC1 != EC1End; ++EC1, ++EC2) { 1116203955Srdivacky if (EC2 == EC2End) { 1117245431Sdim if (Context.Complain) { 1118245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1119245431Sdim << Context.C2.getTypeDeclType(D2); 1120245431Sdim Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator) 1121245431Sdim << EC1->getDeclName() 1122245431Sdim << EC1->getInitVal().toString(10); 1123245431Sdim Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator); 1124245431Sdim } 1125203955Srdivacky return false; 1126203955Srdivacky } 1127203955Srdivacky 1128203955Srdivacky llvm::APSInt Val1 = EC1->getInitVal(); 1129203955Srdivacky llvm::APSInt Val2 = EC2->getInitVal(); 1130245431Sdim if (!llvm::APSInt::isSameValue(Val1, Val2) || 1131203955Srdivacky !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) { 1132245431Sdim if (Context.Complain) { 1133245431Sdim Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1134245431Sdim << Context.C2.getTypeDeclType(D2); 1135245431Sdim Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator) 1136245431Sdim << EC2->getDeclName() 1137245431Sdim << EC2->getInitVal().toString(10); 1138245431Sdim Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator) 1139245431Sdim << EC1->getDeclName() 1140245431Sdim << EC1->getInitVal().toString(10); 1141245431Sdim } 1142245431Sdim return false; 1143245431Sdim } 1144245431Sdim } 1145245431Sdim 1146245431Sdim if (EC2 != EC2End) { 1147245431Sdim if (Context.Complain) { 1148203955Srdivacky Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent) 1149203955Srdivacky << Context.C2.getTypeDeclType(D2); 1150203955Srdivacky Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator) 1151203955Srdivacky << EC2->getDeclName() 1152203955Srdivacky << EC2->getInitVal().toString(10); 1153245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator); 1154203955Srdivacky } 1155203955Srdivacky return false; 1156203955Srdivacky } 1157203955Srdivacky 1158203955Srdivacky return true; 1159203955Srdivacky} 1160218893Sdim 1161218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1162218893Sdim TemplateParameterList *Params1, 1163218893Sdim TemplateParameterList *Params2) { 1164218893Sdim if (Params1->size() != Params2->size()) { 1165245431Sdim if (Context.Complain) { 1166245431Sdim Context.Diag2(Params2->getTemplateLoc(), 1167245431Sdim diag::err_odr_different_num_template_parameters) 1168245431Sdim << Params1->size() << Params2->size(); 1169245431Sdim Context.Diag1(Params1->getTemplateLoc(), 1170245431Sdim diag::note_odr_template_parameter_list); 1171245431Sdim } 1172218893Sdim return false; 1173218893Sdim } 1174203955Srdivacky 1175218893Sdim for (unsigned I = 0, N = Params1->size(); I != N; ++I) { 1176218893Sdim if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) { 1177245431Sdim if (Context.Complain) { 1178245431Sdim Context.Diag2(Params2->getParam(I)->getLocation(), 1179245431Sdim diag::err_odr_different_template_parameter_kind); 1180245431Sdim Context.Diag1(Params1->getParam(I)->getLocation(), 1181245431Sdim diag::note_odr_template_parameter_here); 1182245431Sdim } 1183218893Sdim return false; 1184218893Sdim } 1185218893Sdim 1186218893Sdim if (!Context.IsStructurallyEquivalent(Params1->getParam(I), 1187218893Sdim Params2->getParam(I))) { 1188218893Sdim 1189218893Sdim return false; 1190218893Sdim } 1191218893Sdim } 1192218893Sdim 1193218893Sdim return true; 1194218893Sdim} 1195218893Sdim 1196218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1197218893Sdim TemplateTypeParmDecl *D1, 1198218893Sdim TemplateTypeParmDecl *D2) { 1199218893Sdim if (D1->isParameterPack() != D2->isParameterPack()) { 1200245431Sdim if (Context.Complain) { 1201245431Sdim Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack) 1202245431Sdim << D2->isParameterPack(); 1203245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack) 1204245431Sdim << D1->isParameterPack(); 1205245431Sdim } 1206218893Sdim return false; 1207218893Sdim } 1208218893Sdim 1209218893Sdim return true; 1210218893Sdim} 1211218893Sdim 1212218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1213218893Sdim NonTypeTemplateParmDecl *D1, 1214218893Sdim NonTypeTemplateParmDecl *D2) { 1215218893Sdim if (D1->isParameterPack() != D2->isParameterPack()) { 1216245431Sdim if (Context.Complain) { 1217245431Sdim Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack) 1218245431Sdim << D2->isParameterPack(); 1219245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack) 1220245431Sdim << D1->isParameterPack(); 1221245431Sdim } 1222218893Sdim return false; 1223218893Sdim } 1224218893Sdim 1225218893Sdim // Check types. 1226218893Sdim if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) { 1227245431Sdim if (Context.Complain) { 1228245431Sdim Context.Diag2(D2->getLocation(), 1229245431Sdim diag::err_odr_non_type_parameter_type_inconsistent) 1230245431Sdim << D2->getType() << D1->getType(); 1231245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_value_here) 1232245431Sdim << D1->getType(); 1233245431Sdim } 1234218893Sdim return false; 1235218893Sdim } 1236218893Sdim 1237218893Sdim return true; 1238218893Sdim} 1239218893Sdim 1240218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1241218893Sdim TemplateTemplateParmDecl *D1, 1242218893Sdim TemplateTemplateParmDecl *D2) { 1243218893Sdim if (D1->isParameterPack() != D2->isParameterPack()) { 1244245431Sdim if (Context.Complain) { 1245245431Sdim Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack) 1246245431Sdim << D2->isParameterPack(); 1247245431Sdim Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack) 1248245431Sdim << D1->isParameterPack(); 1249245431Sdim } 1250218893Sdim return false; 1251218893Sdim } 1252245431Sdim 1253218893Sdim // Check template parameter lists. 1254218893Sdim return IsStructurallyEquivalent(Context, D1->getTemplateParameters(), 1255218893Sdim D2->getTemplateParameters()); 1256218893Sdim} 1257218893Sdim 1258218893Sdimstatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1259218893Sdim ClassTemplateDecl *D1, 1260218893Sdim ClassTemplateDecl *D2) { 1261218893Sdim // Check template parameters. 1262218893Sdim if (!IsStructurallyEquivalent(Context, 1263218893Sdim D1->getTemplateParameters(), 1264218893Sdim D2->getTemplateParameters())) 1265218893Sdim return false; 1266218893Sdim 1267218893Sdim // Check the templated declaration. 1268218893Sdim return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(), 1269218893Sdim D2->getTemplatedDecl()); 1270218893Sdim} 1271218893Sdim 1272203955Srdivacky/// \brief Determine structural equivalence of two declarations. 1273203955Srdivackystatic bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, 1274203955Srdivacky Decl *D1, Decl *D2) { 1275203955Srdivacky // FIXME: Check for known structural equivalences via a callback of some sort. 1276203955Srdivacky 1277203955Srdivacky // Check whether we already know that these two declarations are not 1278203955Srdivacky // structurally equivalent. 1279203955Srdivacky if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(), 1280203955Srdivacky D2->getCanonicalDecl()))) 1281203955Srdivacky return false; 1282203955Srdivacky 1283203955Srdivacky // Determine whether we've already produced a tentative equivalence for D1. 1284203955Srdivacky Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()]; 1285203955Srdivacky if (EquivToD1) 1286203955Srdivacky return EquivToD1 == D2->getCanonicalDecl(); 1287203955Srdivacky 1288203955Srdivacky // Produce a tentative equivalence D1 <-> D2, which will be checked later. 1289203955Srdivacky EquivToD1 = D2->getCanonicalDecl(); 1290203955Srdivacky Context.DeclsToCheck.push_back(D1->getCanonicalDecl()); 1291203955Srdivacky return true; 1292203955Srdivacky} 1293203955Srdivacky 1294203955Srdivackybool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1, 1295203955Srdivacky Decl *D2) { 1296203955Srdivacky if (!::IsStructurallyEquivalent(*this, D1, D2)) 1297203955Srdivacky return false; 1298203955Srdivacky 1299203955Srdivacky return !Finish(); 1300203955Srdivacky} 1301203955Srdivacky 1302203955Srdivackybool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1, 1303203955Srdivacky QualType T2) { 1304203955Srdivacky if (!::IsStructurallyEquivalent(*this, T1, T2)) 1305203955Srdivacky return false; 1306203955Srdivacky 1307203955Srdivacky return !Finish(); 1308203955Srdivacky} 1309203955Srdivacky 1310203955Srdivackybool StructuralEquivalenceContext::Finish() { 1311203955Srdivacky while (!DeclsToCheck.empty()) { 1312203955Srdivacky // Check the next declaration. 1313203955Srdivacky Decl *D1 = DeclsToCheck.front(); 1314203955Srdivacky DeclsToCheck.pop_front(); 1315203955Srdivacky 1316203955Srdivacky Decl *D2 = TentativeEquivalences[D1]; 1317203955Srdivacky assert(D2 && "Unrecorded tentative equivalence?"); 1318203955Srdivacky 1319203955Srdivacky bool Equivalent = true; 1320203955Srdivacky 1321203955Srdivacky // FIXME: Switch on all declaration kinds. For now, we're just going to 1322203955Srdivacky // check the obvious ones. 1323203955Srdivacky if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) { 1324203955Srdivacky if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) { 1325203955Srdivacky // Check for equivalent structure names. 1326203955Srdivacky IdentifierInfo *Name1 = Record1->getIdentifier(); 1327221345Sdim if (!Name1 && Record1->getTypedefNameForAnonDecl()) 1328221345Sdim Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier(); 1329203955Srdivacky IdentifierInfo *Name2 = Record2->getIdentifier(); 1330221345Sdim if (!Name2 && Record2->getTypedefNameForAnonDecl()) 1331221345Sdim Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier(); 1332203955Srdivacky if (!::IsStructurallyEquivalent(Name1, Name2) || 1333203955Srdivacky !::IsStructurallyEquivalent(*this, Record1, Record2)) 1334203955Srdivacky Equivalent = false; 1335203955Srdivacky } else { 1336203955Srdivacky // Record/non-record mismatch. 1337203955Srdivacky Equivalent = false; 1338203955Srdivacky } 1339203955Srdivacky } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) { 1340203955Srdivacky if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) { 1341203955Srdivacky // Check for equivalent enum names. 1342203955Srdivacky IdentifierInfo *Name1 = Enum1->getIdentifier(); 1343221345Sdim if (!Name1 && Enum1->getTypedefNameForAnonDecl()) 1344221345Sdim Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier(); 1345203955Srdivacky IdentifierInfo *Name2 = Enum2->getIdentifier(); 1346221345Sdim if (!Name2 && Enum2->getTypedefNameForAnonDecl()) 1347221345Sdim Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier(); 1348203955Srdivacky if (!::IsStructurallyEquivalent(Name1, Name2) || 1349203955Srdivacky !::IsStructurallyEquivalent(*this, Enum1, Enum2)) 1350203955Srdivacky Equivalent = false; 1351203955Srdivacky } else { 1352203955Srdivacky // Enum/non-enum mismatch 1353203955Srdivacky Equivalent = false; 1354203955Srdivacky } 1355221345Sdim } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) { 1356221345Sdim if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) { 1357203955Srdivacky if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(), 1358203955Srdivacky Typedef2->getIdentifier()) || 1359203955Srdivacky !::IsStructurallyEquivalent(*this, 1360203955Srdivacky Typedef1->getUnderlyingType(), 1361203955Srdivacky Typedef2->getUnderlyingType())) 1362203955Srdivacky Equivalent = false; 1363203955Srdivacky } else { 1364203955Srdivacky // Typedef/non-typedef mismatch. 1365203955Srdivacky Equivalent = false; 1366203955Srdivacky } 1367218893Sdim } else if (ClassTemplateDecl *ClassTemplate1 1368218893Sdim = dyn_cast<ClassTemplateDecl>(D1)) { 1369218893Sdim if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) { 1370218893Sdim if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(), 1371218893Sdim ClassTemplate2->getIdentifier()) || 1372218893Sdim !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2)) 1373218893Sdim Equivalent = false; 1374218893Sdim } else { 1375218893Sdim // Class template/non-class-template mismatch. 1376218893Sdim Equivalent = false; 1377218893Sdim } 1378218893Sdim } else if (TemplateTypeParmDecl *TTP1= dyn_cast<TemplateTypeParmDecl>(D1)) { 1379218893Sdim if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) { 1380218893Sdim if (!::IsStructurallyEquivalent(*this, TTP1, TTP2)) 1381218893Sdim Equivalent = false; 1382218893Sdim } else { 1383218893Sdim // Kind mismatch. 1384218893Sdim Equivalent = false; 1385218893Sdim } 1386218893Sdim } else if (NonTypeTemplateParmDecl *NTTP1 1387218893Sdim = dyn_cast<NonTypeTemplateParmDecl>(D1)) { 1388218893Sdim if (NonTypeTemplateParmDecl *NTTP2 1389218893Sdim = dyn_cast<NonTypeTemplateParmDecl>(D2)) { 1390218893Sdim if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2)) 1391218893Sdim Equivalent = false; 1392218893Sdim } else { 1393218893Sdim // Kind mismatch. 1394218893Sdim Equivalent = false; 1395218893Sdim } 1396218893Sdim } else if (TemplateTemplateParmDecl *TTP1 1397218893Sdim = dyn_cast<TemplateTemplateParmDecl>(D1)) { 1398218893Sdim if (TemplateTemplateParmDecl *TTP2 1399218893Sdim = dyn_cast<TemplateTemplateParmDecl>(D2)) { 1400218893Sdim if (!::IsStructurallyEquivalent(*this, TTP1, TTP2)) 1401218893Sdim Equivalent = false; 1402218893Sdim } else { 1403218893Sdim // Kind mismatch. 1404218893Sdim Equivalent = false; 1405218893Sdim } 1406218893Sdim } 1407218893Sdim 1408203955Srdivacky if (!Equivalent) { 1409203955Srdivacky // Note that these two declarations are not equivalent (and we already 1410203955Srdivacky // know about it). 1411203955Srdivacky NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(), 1412203955Srdivacky D2->getCanonicalDecl())); 1413203955Srdivacky return true; 1414203955Srdivacky } 1415203955Srdivacky // FIXME: Check other declaration kinds! 1416203955Srdivacky } 1417203955Srdivacky 1418203955Srdivacky return false; 1419203955Srdivacky} 1420203955Srdivacky 1421203955Srdivacky//---------------------------------------------------------------------------- 1422203955Srdivacky// Import Types 1423203955Srdivacky//---------------------------------------------------------------------------- 1424203955Srdivacky 1425218893SdimQualType ASTNodeImporter::VisitType(const Type *T) { 1426203955Srdivacky Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node) 1427203955Srdivacky << T->getTypeClassName(); 1428203955Srdivacky return QualType(); 1429203955Srdivacky} 1430203955Srdivacky 1431218893SdimQualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) { 1432203955Srdivacky switch (T->getKind()) { 1433235633Sdim#define SHARED_SINGLETON_TYPE(Expansion) 1434235633Sdim#define BUILTIN_TYPE(Id, SingletonId) \ 1435235633Sdim case BuiltinType::Id: return Importer.getToContext().SingletonId; 1436235633Sdim#include "clang/AST/BuiltinTypes.def" 1437235633Sdim 1438235633Sdim // FIXME: for Char16, Char32, and NullPtr, make sure that the "to" 1439235633Sdim // context supports C++. 1440235633Sdim 1441235633Sdim // FIXME: for ObjCId, ObjCClass, and ObjCSel, make sure that the "to" 1442235633Sdim // context supports ObjC. 1443235633Sdim 1444203955Srdivacky case BuiltinType::Char_U: 1445203955Srdivacky // The context we're importing from has an unsigned 'char'. If we're 1446203955Srdivacky // importing into a context with a signed 'char', translate to 1447203955Srdivacky // 'unsigned char' instead. 1448235633Sdim if (Importer.getToContext().getLangOpts().CharIsSigned) 1449203955Srdivacky return Importer.getToContext().UnsignedCharTy; 1450203955Srdivacky 1451203955Srdivacky return Importer.getToContext().CharTy; 1452203955Srdivacky 1453203955Srdivacky case BuiltinType::Char_S: 1454203955Srdivacky // The context we're importing from has an unsigned 'char'. If we're 1455203955Srdivacky // importing into a context with a signed 'char', translate to 1456203955Srdivacky // 'unsigned char' instead. 1457235633Sdim if (!Importer.getToContext().getLangOpts().CharIsSigned) 1458203955Srdivacky return Importer.getToContext().SignedCharTy; 1459203955Srdivacky 1460203955Srdivacky return Importer.getToContext().CharTy; 1461203955Srdivacky 1462218893Sdim case BuiltinType::WChar_S: 1463218893Sdim case BuiltinType::WChar_U: 1464203955Srdivacky // FIXME: If not in C++, shall we translate to the C equivalent of 1465203955Srdivacky // wchar_t? 1466203955Srdivacky return Importer.getToContext().WCharTy; 1467235633Sdim } 1468203955Srdivacky 1469235633Sdim llvm_unreachable("Invalid BuiltinType Kind!"); 1470203955Srdivacky} 1471203955Srdivacky 1472218893SdimQualType ASTNodeImporter::VisitComplexType(const ComplexType *T) { 1473203955Srdivacky QualType ToElementType = Importer.Import(T->getElementType()); 1474203955Srdivacky if (ToElementType.isNull()) 1475203955Srdivacky return QualType(); 1476203955Srdivacky 1477203955Srdivacky return Importer.getToContext().getComplexType(ToElementType); 1478203955Srdivacky} 1479203955Srdivacky 1480218893SdimQualType ASTNodeImporter::VisitPointerType(const PointerType *T) { 1481203955Srdivacky QualType ToPointeeType = Importer.Import(T->getPointeeType()); 1482203955Srdivacky if (ToPointeeType.isNull()) 1483203955Srdivacky return QualType(); 1484203955Srdivacky 1485203955Srdivacky return Importer.getToContext().getPointerType(ToPointeeType); 1486203955Srdivacky} 1487203955Srdivacky 1488218893SdimQualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) { 1489203955Srdivacky // FIXME: Check for blocks support in "to" context. 1490203955Srdivacky QualType ToPointeeType = Importer.Import(T->getPointeeType()); 1491203955Srdivacky if (ToPointeeType.isNull()) 1492203955Srdivacky return QualType(); 1493203955Srdivacky 1494203955Srdivacky return Importer.getToContext().getBlockPointerType(ToPointeeType); 1495203955Srdivacky} 1496203955Srdivacky 1497218893SdimQualType 1498218893SdimASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) { 1499203955Srdivacky // FIXME: Check for C++ support in "to" context. 1500203955Srdivacky QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten()); 1501203955Srdivacky if (ToPointeeType.isNull()) 1502203955Srdivacky return QualType(); 1503203955Srdivacky 1504203955Srdivacky return Importer.getToContext().getLValueReferenceType(ToPointeeType); 1505203955Srdivacky} 1506203955Srdivacky 1507218893SdimQualType 1508218893SdimASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) { 1509203955Srdivacky // FIXME: Check for C++0x support in "to" context. 1510203955Srdivacky QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten()); 1511203955Srdivacky if (ToPointeeType.isNull()) 1512203955Srdivacky return QualType(); 1513203955Srdivacky 1514203955Srdivacky return Importer.getToContext().getRValueReferenceType(ToPointeeType); 1515203955Srdivacky} 1516203955Srdivacky 1517218893SdimQualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) { 1518203955Srdivacky // FIXME: Check for C++ support in "to" context. 1519203955Srdivacky QualType ToPointeeType = Importer.Import(T->getPointeeType()); 1520203955Srdivacky if (ToPointeeType.isNull()) 1521203955Srdivacky return QualType(); 1522203955Srdivacky 1523203955Srdivacky QualType ClassType = Importer.Import(QualType(T->getClass(), 0)); 1524203955Srdivacky return Importer.getToContext().getMemberPointerType(ToPointeeType, 1525203955Srdivacky ClassType.getTypePtr()); 1526203955Srdivacky} 1527203955Srdivacky 1528218893SdimQualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) { 1529203955Srdivacky QualType ToElementType = Importer.Import(T->getElementType()); 1530203955Srdivacky if (ToElementType.isNull()) 1531203955Srdivacky return QualType(); 1532203955Srdivacky 1533203955Srdivacky return Importer.getToContext().getConstantArrayType(ToElementType, 1534203955Srdivacky T->getSize(), 1535203955Srdivacky T->getSizeModifier(), 1536203955Srdivacky T->getIndexTypeCVRQualifiers()); 1537203955Srdivacky} 1538203955Srdivacky 1539218893SdimQualType 1540218893SdimASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) { 1541203955Srdivacky QualType ToElementType = Importer.Import(T->getElementType()); 1542203955Srdivacky if (ToElementType.isNull()) 1543203955Srdivacky return QualType(); 1544203955Srdivacky 1545203955Srdivacky return Importer.getToContext().getIncompleteArrayType(ToElementType, 1546203955Srdivacky T->getSizeModifier(), 1547203955Srdivacky T->getIndexTypeCVRQualifiers()); 1548203955Srdivacky} 1549203955Srdivacky 1550218893SdimQualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) { 1551203955Srdivacky QualType ToElementType = Importer.Import(T->getElementType()); 1552203955Srdivacky if (ToElementType.isNull()) 1553203955Srdivacky return QualType(); 1554203955Srdivacky 1555203955Srdivacky Expr *Size = Importer.Import(T->getSizeExpr()); 1556203955Srdivacky if (!Size) 1557203955Srdivacky return QualType(); 1558203955Srdivacky 1559203955Srdivacky SourceRange Brackets = Importer.Import(T->getBracketsRange()); 1560203955Srdivacky return Importer.getToContext().getVariableArrayType(ToElementType, Size, 1561203955Srdivacky T->getSizeModifier(), 1562203955Srdivacky T->getIndexTypeCVRQualifiers(), 1563203955Srdivacky Brackets); 1564203955Srdivacky} 1565203955Srdivacky 1566218893SdimQualType ASTNodeImporter::VisitVectorType(const VectorType *T) { 1567203955Srdivacky QualType ToElementType = Importer.Import(T->getElementType()); 1568203955Srdivacky if (ToElementType.isNull()) 1569203955Srdivacky return QualType(); 1570203955Srdivacky 1571203955Srdivacky return Importer.getToContext().getVectorType(ToElementType, 1572203955Srdivacky T->getNumElements(), 1573218893Sdim T->getVectorKind()); 1574203955Srdivacky} 1575203955Srdivacky 1576218893SdimQualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) { 1577203955Srdivacky QualType ToElementType = Importer.Import(T->getElementType()); 1578203955Srdivacky if (ToElementType.isNull()) 1579203955Srdivacky return QualType(); 1580203955Srdivacky 1581203955Srdivacky return Importer.getToContext().getExtVectorType(ToElementType, 1582203955Srdivacky T->getNumElements()); 1583203955Srdivacky} 1584203955Srdivacky 1585218893SdimQualType 1586218893SdimASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { 1587203955Srdivacky // FIXME: What happens if we're importing a function without a prototype 1588203955Srdivacky // into C++? Should we make it variadic? 1589203955Srdivacky QualType ToResultType = Importer.Import(T->getResultType()); 1590203955Srdivacky if (ToResultType.isNull()) 1591203955Srdivacky return QualType(); 1592206084Srdivacky 1593203955Srdivacky return Importer.getToContext().getFunctionNoProtoType(ToResultType, 1594206084Srdivacky T->getExtInfo()); 1595203955Srdivacky} 1596203955Srdivacky 1597218893SdimQualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) { 1598203955Srdivacky QualType ToResultType = Importer.Import(T->getResultType()); 1599203955Srdivacky if (ToResultType.isNull()) 1600203955Srdivacky return QualType(); 1601203955Srdivacky 1602203955Srdivacky // Import argument types 1603226890Sdim SmallVector<QualType, 4> ArgTypes; 1604203955Srdivacky for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(), 1605203955Srdivacky AEnd = T->arg_type_end(); 1606203955Srdivacky A != AEnd; ++A) { 1607203955Srdivacky QualType ArgType = Importer.Import(*A); 1608203955Srdivacky if (ArgType.isNull()) 1609203955Srdivacky return QualType(); 1610203955Srdivacky ArgTypes.push_back(ArgType); 1611203955Srdivacky } 1612203955Srdivacky 1613203955Srdivacky // Import exception types 1614226890Sdim SmallVector<QualType, 4> ExceptionTypes; 1615203955Srdivacky for (FunctionProtoType::exception_iterator E = T->exception_begin(), 1616203955Srdivacky EEnd = T->exception_end(); 1617203955Srdivacky E != EEnd; ++E) { 1618203955Srdivacky QualType ExceptionType = Importer.Import(*E); 1619203955Srdivacky if (ExceptionType.isNull()) 1620203955Srdivacky return QualType(); 1621203955Srdivacky ExceptionTypes.push_back(ExceptionType); 1622203955Srdivacky } 1623218893Sdim 1624245431Sdim FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo(); 1625245431Sdim FunctionProtoType::ExtProtoInfo ToEPI; 1626245431Sdim 1627245431Sdim ToEPI.ExtInfo = FromEPI.ExtInfo; 1628245431Sdim ToEPI.Variadic = FromEPI.Variadic; 1629245431Sdim ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn; 1630245431Sdim ToEPI.TypeQuals = FromEPI.TypeQuals; 1631245431Sdim ToEPI.RefQualifier = FromEPI.RefQualifier; 1632245431Sdim ToEPI.NumExceptions = ExceptionTypes.size(); 1633245431Sdim ToEPI.Exceptions = ExceptionTypes.data(); 1634245431Sdim ToEPI.ConsumedArguments = FromEPI.ConsumedArguments; 1635245431Sdim ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType; 1636245431Sdim ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr); 1637245431Sdim ToEPI.ExceptionSpecDecl = cast_or_null<FunctionDecl>( 1638245431Sdim Importer.Import(FromEPI.ExceptionSpecDecl)); 1639245431Sdim ToEPI.ExceptionSpecTemplate = cast_or_null<FunctionDecl>( 1640245431Sdim Importer.Import(FromEPI.ExceptionSpecTemplate)); 1641245431Sdim 1642252723Sdim return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI); 1643203955Srdivacky} 1644203955Srdivacky 1645226890SdimQualType ASTNodeImporter::VisitParenType(const ParenType *T) { 1646226890Sdim QualType ToInnerType = Importer.Import(T->getInnerType()); 1647226890Sdim if (ToInnerType.isNull()) 1648226890Sdim return QualType(); 1649226890Sdim 1650226890Sdim return Importer.getToContext().getParenType(ToInnerType); 1651226890Sdim} 1652226890Sdim 1653218893SdimQualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) { 1654221345Sdim TypedefNameDecl *ToDecl 1655221345Sdim = dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl())); 1656203955Srdivacky if (!ToDecl) 1657203955Srdivacky return QualType(); 1658203955Srdivacky 1659203955Srdivacky return Importer.getToContext().getTypeDeclType(ToDecl); 1660203955Srdivacky} 1661203955Srdivacky 1662218893SdimQualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) { 1663203955Srdivacky Expr *ToExpr = Importer.Import(T->getUnderlyingExpr()); 1664203955Srdivacky if (!ToExpr) 1665203955Srdivacky return QualType(); 1666203955Srdivacky 1667203955Srdivacky return Importer.getToContext().getTypeOfExprType(ToExpr); 1668203955Srdivacky} 1669203955Srdivacky 1670218893SdimQualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) { 1671203955Srdivacky QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType()); 1672203955Srdivacky if (ToUnderlyingType.isNull()) 1673203955Srdivacky return QualType(); 1674203955Srdivacky 1675203955Srdivacky return Importer.getToContext().getTypeOfType(ToUnderlyingType); 1676203955Srdivacky} 1677203955Srdivacky 1678218893SdimQualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) { 1679218893Sdim // FIXME: Make sure that the "to" context supports C++0x! 1680203955Srdivacky Expr *ToExpr = Importer.Import(T->getUnderlyingExpr()); 1681203955Srdivacky if (!ToExpr) 1682203955Srdivacky return QualType(); 1683203955Srdivacky 1684235633Sdim QualType UnderlyingType = Importer.Import(T->getUnderlyingType()); 1685235633Sdim if (UnderlyingType.isNull()) 1686235633Sdim return QualType(); 1687235633Sdim 1688235633Sdim return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType); 1689203955Srdivacky} 1690203955Srdivacky 1691223017SdimQualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) { 1692223017Sdim QualType ToBaseType = Importer.Import(T->getBaseType()); 1693223017Sdim QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType()); 1694223017Sdim if (ToBaseType.isNull() || ToUnderlyingType.isNull()) 1695223017Sdim return QualType(); 1696223017Sdim 1697223017Sdim return Importer.getToContext().getUnaryTransformType(ToBaseType, 1698223017Sdim ToUnderlyingType, 1699223017Sdim T->getUTTKind()); 1700223017Sdim} 1701223017Sdim 1702218893SdimQualType ASTNodeImporter::VisitAutoType(const AutoType *T) { 1703252723Sdim // FIXME: Make sure that the "to" context supports C++11! 1704218893Sdim QualType FromDeduced = T->getDeducedType(); 1705218893Sdim QualType ToDeduced; 1706218893Sdim if (!FromDeduced.isNull()) { 1707218893Sdim ToDeduced = Importer.Import(FromDeduced); 1708218893Sdim if (ToDeduced.isNull()) 1709218893Sdim return QualType(); 1710218893Sdim } 1711218893Sdim 1712263509Sdim return Importer.getToContext().getAutoType(ToDeduced, T->isDecltypeAuto(), 1713263509Sdim /*IsDependent*/false); 1714218893Sdim} 1715218893Sdim 1716218893SdimQualType ASTNodeImporter::VisitRecordType(const RecordType *T) { 1717203955Srdivacky RecordDecl *ToDecl 1718203955Srdivacky = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl())); 1719203955Srdivacky if (!ToDecl) 1720203955Srdivacky return QualType(); 1721203955Srdivacky 1722203955Srdivacky return Importer.getToContext().getTagDeclType(ToDecl); 1723203955Srdivacky} 1724203955Srdivacky 1725218893SdimQualType ASTNodeImporter::VisitEnumType(const EnumType *T) { 1726203955Srdivacky EnumDecl *ToDecl 1727203955Srdivacky = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl())); 1728203955Srdivacky if (!ToDecl) 1729203955Srdivacky return QualType(); 1730203955Srdivacky 1731203955Srdivacky return Importer.getToContext().getTagDeclType(ToDecl); 1732203955Srdivacky} 1733203955Srdivacky 1734218893SdimQualType ASTNodeImporter::VisitTemplateSpecializationType( 1735218893Sdim const TemplateSpecializationType *T) { 1736218893Sdim TemplateName ToTemplate = Importer.Import(T->getTemplateName()); 1737218893Sdim if (ToTemplate.isNull()) 1738218893Sdim return QualType(); 1739218893Sdim 1740226890Sdim SmallVector<TemplateArgument, 2> ToTemplateArgs; 1741218893Sdim if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs)) 1742218893Sdim return QualType(); 1743218893Sdim 1744218893Sdim QualType ToCanonType; 1745218893Sdim if (!QualType(T, 0).isCanonical()) { 1746218893Sdim QualType FromCanonType 1747218893Sdim = Importer.getFromContext().getCanonicalType(QualType(T, 0)); 1748218893Sdim ToCanonType =Importer.Import(FromCanonType); 1749218893Sdim if (ToCanonType.isNull()) 1750218893Sdim return QualType(); 1751218893Sdim } 1752218893Sdim return Importer.getToContext().getTemplateSpecializationType(ToTemplate, 1753218893Sdim ToTemplateArgs.data(), 1754218893Sdim ToTemplateArgs.size(), 1755218893Sdim ToCanonType); 1756218893Sdim} 1757218893Sdim 1758218893SdimQualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) { 1759208600Srdivacky NestedNameSpecifier *ToQualifier = 0; 1760208600Srdivacky // Note: the qualifier in an ElaboratedType is optional. 1761208600Srdivacky if (T->getQualifier()) { 1762208600Srdivacky ToQualifier = Importer.Import(T->getQualifier()); 1763208600Srdivacky if (!ToQualifier) 1764208600Srdivacky return QualType(); 1765208600Srdivacky } 1766203955Srdivacky 1767203955Srdivacky QualType ToNamedType = Importer.Import(T->getNamedType()); 1768203955Srdivacky if (ToNamedType.isNull()) 1769203955Srdivacky return QualType(); 1770203955Srdivacky 1771208600Srdivacky return Importer.getToContext().getElaboratedType(T->getKeyword(), 1772208600Srdivacky ToQualifier, ToNamedType); 1773203955Srdivacky} 1774203955Srdivacky 1775218893SdimQualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 1776203955Srdivacky ObjCInterfaceDecl *Class 1777203955Srdivacky = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl())); 1778203955Srdivacky if (!Class) 1779203955Srdivacky return QualType(); 1780203955Srdivacky 1781208600Srdivacky return Importer.getToContext().getObjCInterfaceType(Class); 1782208600Srdivacky} 1783208600Srdivacky 1784218893SdimQualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) { 1785208600Srdivacky QualType ToBaseType = Importer.Import(T->getBaseType()); 1786208600Srdivacky if (ToBaseType.isNull()) 1787208600Srdivacky return QualType(); 1788208600Srdivacky 1789226890Sdim SmallVector<ObjCProtocolDecl *, 4> Protocols; 1790208600Srdivacky for (ObjCObjectType::qual_iterator P = T->qual_begin(), 1791203955Srdivacky PEnd = T->qual_end(); 1792203955Srdivacky P != PEnd; ++P) { 1793203955Srdivacky ObjCProtocolDecl *Protocol 1794203955Srdivacky = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P)); 1795203955Srdivacky if (!Protocol) 1796203955Srdivacky return QualType(); 1797203955Srdivacky Protocols.push_back(Protocol); 1798203955Srdivacky } 1799203955Srdivacky 1800208600Srdivacky return Importer.getToContext().getObjCObjectType(ToBaseType, 1801208600Srdivacky Protocols.data(), 1802208600Srdivacky Protocols.size()); 1803203955Srdivacky} 1804203955Srdivacky 1805218893SdimQualType 1806218893SdimASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 1807203955Srdivacky QualType ToPointeeType = Importer.Import(T->getPointeeType()); 1808203955Srdivacky if (ToPointeeType.isNull()) 1809203955Srdivacky return QualType(); 1810203955Srdivacky 1811208600Srdivacky return Importer.getToContext().getObjCObjectPointerType(ToPointeeType); 1812203955Srdivacky} 1813203955Srdivacky 1814203955Srdivacky//---------------------------------------------------------------------------- 1815203955Srdivacky// Import Declarations 1816203955Srdivacky//---------------------------------------------------------------------------- 1817203955Srdivackybool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC, 1818203955Srdivacky DeclContext *&LexicalDC, 1819203955Srdivacky DeclarationName &Name, 1820203955Srdivacky SourceLocation &Loc) { 1821203955Srdivacky // Import the context of this declaration. 1822203955Srdivacky DC = Importer.ImportContext(D->getDeclContext()); 1823203955Srdivacky if (!DC) 1824203955Srdivacky return true; 1825203955Srdivacky 1826203955Srdivacky LexicalDC = DC; 1827203955Srdivacky if (D->getDeclContext() != D->getLexicalDeclContext()) { 1828203955Srdivacky LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); 1829203955Srdivacky if (!LexicalDC) 1830203955Srdivacky return true; 1831203955Srdivacky } 1832203955Srdivacky 1833203955Srdivacky // Import the name of this declaration. 1834203955Srdivacky Name = Importer.Import(D->getDeclName()); 1835203955Srdivacky if (D->getDeclName() && !Name) 1836203955Srdivacky return true; 1837203955Srdivacky 1838203955Srdivacky // Import the location of this declaration. 1839203955Srdivacky Loc = Importer.Import(D->getLocation()); 1840203955Srdivacky return false; 1841203955Srdivacky} 1842203955Srdivacky 1843226890Sdimvoid ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) { 1844226890Sdim if (!FromD) 1845226890Sdim return; 1846226890Sdim 1847226890Sdim if (!ToD) { 1848226890Sdim ToD = Importer.Import(FromD); 1849226890Sdim if (!ToD) 1850226890Sdim return; 1851226890Sdim } 1852226890Sdim 1853226890Sdim if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) { 1854226890Sdim if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) { 1855252723Sdim if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) { 1856226890Sdim ImportDefinition(FromRecord, ToRecord); 1857226890Sdim } 1858226890Sdim } 1859226890Sdim return; 1860226890Sdim } 1861226890Sdim 1862226890Sdim if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) { 1863226890Sdim if (EnumDecl *ToEnum = cast_or_null<EnumDecl>(ToD)) { 1864226890Sdim if (FromEnum->getDefinition() && !ToEnum->getDefinition()) { 1865226890Sdim ImportDefinition(FromEnum, ToEnum); 1866226890Sdim } 1867226890Sdim } 1868226890Sdim return; 1869226890Sdim } 1870226890Sdim} 1871226890Sdim 1872212904Sdimvoid 1873212904SdimASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From, 1874212904Sdim DeclarationNameInfo& To) { 1875212904Sdim // NOTE: To.Name and To.Loc are already imported. 1876212904Sdim // We only have to import To.LocInfo. 1877212904Sdim switch (To.getName().getNameKind()) { 1878212904Sdim case DeclarationName::Identifier: 1879212904Sdim case DeclarationName::ObjCZeroArgSelector: 1880212904Sdim case DeclarationName::ObjCOneArgSelector: 1881212904Sdim case DeclarationName::ObjCMultiArgSelector: 1882212904Sdim case DeclarationName::CXXUsingDirective: 1883212904Sdim return; 1884212904Sdim 1885212904Sdim case DeclarationName::CXXOperatorName: { 1886212904Sdim SourceRange Range = From.getCXXOperatorNameRange(); 1887212904Sdim To.setCXXOperatorNameRange(Importer.Import(Range)); 1888212904Sdim return; 1889212904Sdim } 1890212904Sdim case DeclarationName::CXXLiteralOperatorName: { 1891212904Sdim SourceLocation Loc = From.getCXXLiteralOperatorNameLoc(); 1892212904Sdim To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc)); 1893212904Sdim return; 1894212904Sdim } 1895212904Sdim case DeclarationName::CXXConstructorName: 1896212904Sdim case DeclarationName::CXXDestructorName: 1897212904Sdim case DeclarationName::CXXConversionFunctionName: { 1898212904Sdim TypeSourceInfo *FromTInfo = From.getNamedTypeInfo(); 1899212904Sdim To.setNamedTypeInfo(Importer.Import(FromTInfo)); 1900212904Sdim return; 1901212904Sdim } 1902212904Sdim } 1903235633Sdim llvm_unreachable("Unknown name kind."); 1904212904Sdim} 1905212904Sdim 1906235633Sdimvoid ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) { 1907218893Sdim if (Importer.isMinimalImport() && !ForceImport) { 1908226890Sdim Importer.ImportContext(FromDC); 1909218893Sdim return; 1910218893Sdim } 1911218893Sdim 1912204643Srdivacky for (DeclContext::decl_iterator From = FromDC->decls_begin(), 1913204643Srdivacky FromEnd = FromDC->decls_end(); 1914204643Srdivacky From != FromEnd; 1915204643Srdivacky ++From) 1916204643Srdivacky Importer.Import(*From); 1917204643Srdivacky} 1918204643Srdivacky 1919226890Sdimbool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, 1920235633Sdim ImportDefinitionKind Kind) { 1921235633Sdim if (To->getDefinition() || To->isBeingDefined()) { 1922235633Sdim if (Kind == IDK_Everything) 1923235633Sdim ImportDeclContext(From, /*ForceImport=*/true); 1924235633Sdim 1925218893Sdim return false; 1926235633Sdim } 1927218893Sdim 1928218893Sdim To->startDefinition(); 1929218893Sdim 1930218893Sdim // Add base classes. 1931218893Sdim if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(To)) { 1932218893Sdim CXXRecordDecl *FromCXX = cast<CXXRecordDecl>(From); 1933235633Sdim 1934235633Sdim struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data(); 1935235633Sdim struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data(); 1936235633Sdim ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor; 1937252723Sdim ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers; 1938235633Sdim ToData.Aggregate = FromData.Aggregate; 1939235633Sdim ToData.PlainOldData = FromData.PlainOldData; 1940235633Sdim ToData.Empty = FromData.Empty; 1941235633Sdim ToData.Polymorphic = FromData.Polymorphic; 1942235633Sdim ToData.Abstract = FromData.Abstract; 1943235633Sdim ToData.IsStandardLayout = FromData.IsStandardLayout; 1944235633Sdim ToData.HasNoNonEmptyBases = FromData.HasNoNonEmptyBases; 1945235633Sdim ToData.HasPrivateFields = FromData.HasPrivateFields; 1946235633Sdim ToData.HasProtectedFields = FromData.HasProtectedFields; 1947235633Sdim ToData.HasPublicFields = FromData.HasPublicFields; 1948235633Sdim ToData.HasMutableFields = FromData.HasMutableFields; 1949235633Sdim ToData.HasOnlyCMembers = FromData.HasOnlyCMembers; 1950245431Sdim ToData.HasInClassInitializer = FromData.HasInClassInitializer; 1951252723Sdim ToData.HasUninitializedReferenceMember 1952252723Sdim = FromData.HasUninitializedReferenceMember; 1953252723Sdim ToData.NeedOverloadResolutionForMoveConstructor 1954252723Sdim = FromData.NeedOverloadResolutionForMoveConstructor; 1955252723Sdim ToData.NeedOverloadResolutionForMoveAssignment 1956252723Sdim = FromData.NeedOverloadResolutionForMoveAssignment; 1957252723Sdim ToData.NeedOverloadResolutionForDestructor 1958252723Sdim = FromData.NeedOverloadResolutionForDestructor; 1959252723Sdim ToData.DefaultedMoveConstructorIsDeleted 1960252723Sdim = FromData.DefaultedMoveConstructorIsDeleted; 1961252723Sdim ToData.DefaultedMoveAssignmentIsDeleted 1962252723Sdim = FromData.DefaultedMoveAssignmentIsDeleted; 1963252723Sdim ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted; 1964252723Sdim ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers; 1965252723Sdim ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor; 1966235633Sdim ToData.HasConstexprNonCopyMoveConstructor 1967235633Sdim = FromData.HasConstexprNonCopyMoveConstructor; 1968235633Sdim ToData.DefaultedDefaultConstructorIsConstexpr 1969235633Sdim = FromData.DefaultedDefaultConstructorIsConstexpr; 1970235633Sdim ToData.HasConstexprDefaultConstructor 1971235633Sdim = FromData.HasConstexprDefaultConstructor; 1972235633Sdim ToData.HasNonLiteralTypeFieldsOrBases 1973235633Sdim = FromData.HasNonLiteralTypeFieldsOrBases; 1974235633Sdim // ComputedVisibleConversions not imported. 1975235633Sdim ToData.UserProvidedDefaultConstructor 1976235633Sdim = FromData.UserProvidedDefaultConstructor; 1977252723Sdim ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers; 1978252723Sdim ToData.ImplicitCopyConstructorHasConstParam 1979252723Sdim = FromData.ImplicitCopyConstructorHasConstParam; 1980252723Sdim ToData.ImplicitCopyAssignmentHasConstParam 1981252723Sdim = FromData.ImplicitCopyAssignmentHasConstParam; 1982252723Sdim ToData.HasDeclaredCopyConstructorWithConstParam 1983252723Sdim = FromData.HasDeclaredCopyConstructorWithConstParam; 1984252723Sdim ToData.HasDeclaredCopyAssignmentWithConstParam 1985252723Sdim = FromData.HasDeclaredCopyAssignmentWithConstParam; 1986235633Sdim ToData.IsLambda = FromData.IsLambda; 1987235633Sdim 1988226890Sdim SmallVector<CXXBaseSpecifier *, 4> Bases; 1989218893Sdim for (CXXRecordDecl::base_class_iterator 1990218893Sdim Base1 = FromCXX->bases_begin(), 1991218893Sdim FromBaseEnd = FromCXX->bases_end(); 1992218893Sdim Base1 != FromBaseEnd; 1993218893Sdim ++Base1) { 1994218893Sdim QualType T = Importer.Import(Base1->getType()); 1995218893Sdim if (T.isNull()) 1996218893Sdim return true; 1997218893Sdim 1998218893Sdim SourceLocation EllipsisLoc; 1999218893Sdim if (Base1->isPackExpansion()) 2000218893Sdim EllipsisLoc = Importer.Import(Base1->getEllipsisLoc()); 2001226890Sdim 2002226890Sdim // Ensure that we have a definition for the base. 2003226890Sdim ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl()); 2004226890Sdim 2005218893Sdim Bases.push_back( 2006218893Sdim new (Importer.getToContext()) 2007218893Sdim CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()), 2008218893Sdim Base1->isVirtual(), 2009218893Sdim Base1->isBaseOfClass(), 2010218893Sdim Base1->getAccessSpecifierAsWritten(), 2011218893Sdim Importer.Import(Base1->getTypeSourceInfo()), 2012218893Sdim EllipsisLoc)); 2013218893Sdim } 2014218893Sdim if (!Bases.empty()) 2015218893Sdim ToCXX->setBases(Bases.data(), Bases.size()); 2016218893Sdim } 2017218893Sdim 2018235633Sdim if (shouldForceImportDeclContext(Kind)) 2019235633Sdim ImportDeclContext(From, /*ForceImport=*/true); 2020235633Sdim 2021218893Sdim To->completeDefinition(); 2022218893Sdim return false; 2023218893Sdim} 2024218893Sdim 2025263509Sdimbool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To, 2026263509Sdim ImportDefinitionKind Kind) { 2027263509Sdim if (To->getDefinition()) 2028263509Sdim return false; 2029263509Sdim 2030263509Sdim // FIXME: Can we really import any initializer? Alternatively, we could force 2031263509Sdim // ourselves to import every declaration of a variable and then only use 2032263509Sdim // getInit() here. 2033263509Sdim To->setInit(Importer.Import(const_cast<Expr *>(From->getAnyInitializer()))); 2034263509Sdim 2035263509Sdim // FIXME: Other bits to merge? 2036263509Sdim 2037263509Sdim return false; 2038263509Sdim} 2039263509Sdim 2040226890Sdimbool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To, 2041235633Sdim ImportDefinitionKind Kind) { 2042235633Sdim if (To->getDefinition() || To->isBeingDefined()) { 2043235633Sdim if (Kind == IDK_Everything) 2044235633Sdim ImportDeclContext(From, /*ForceImport=*/true); 2045226890Sdim return false; 2046235633Sdim } 2047226890Sdim 2048226890Sdim To->startDefinition(); 2049226890Sdim 2050226890Sdim QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From)); 2051226890Sdim if (T.isNull()) 2052226890Sdim return true; 2053226890Sdim 2054226890Sdim QualType ToPromotionType = Importer.Import(From->getPromotionType()); 2055226890Sdim if (ToPromotionType.isNull()) 2056226890Sdim return true; 2057235633Sdim 2058235633Sdim if (shouldForceImportDeclContext(Kind)) 2059235633Sdim ImportDeclContext(From, /*ForceImport=*/true); 2060226890Sdim 2061226890Sdim // FIXME: we might need to merge the number of positive or negative bits 2062226890Sdim // if the enumerator lists don't match. 2063226890Sdim To->completeDefinition(T, ToPromotionType, 2064226890Sdim From->getNumPositiveBits(), 2065226890Sdim From->getNumNegativeBits()); 2066226890Sdim return false; 2067226890Sdim} 2068226890Sdim 2069218893SdimTemplateParameterList *ASTNodeImporter::ImportTemplateParameterList( 2070218893Sdim TemplateParameterList *Params) { 2071226890Sdim SmallVector<NamedDecl *, 4> ToParams; 2072218893Sdim ToParams.reserve(Params->size()); 2073218893Sdim for (TemplateParameterList::iterator P = Params->begin(), 2074218893Sdim PEnd = Params->end(); 2075218893Sdim P != PEnd; ++P) { 2076218893Sdim Decl *To = Importer.Import(*P); 2077218893Sdim if (!To) 2078218893Sdim return 0; 2079218893Sdim 2080218893Sdim ToParams.push_back(cast<NamedDecl>(To)); 2081218893Sdim } 2082218893Sdim 2083218893Sdim return TemplateParameterList::Create(Importer.getToContext(), 2084218893Sdim Importer.Import(Params->getTemplateLoc()), 2085218893Sdim Importer.Import(Params->getLAngleLoc()), 2086218893Sdim ToParams.data(), ToParams.size(), 2087218893Sdim Importer.Import(Params->getRAngleLoc())); 2088218893Sdim} 2089218893Sdim 2090218893SdimTemplateArgument 2091218893SdimASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) { 2092218893Sdim switch (From.getKind()) { 2093218893Sdim case TemplateArgument::Null: 2094218893Sdim return TemplateArgument(); 2095218893Sdim 2096218893Sdim case TemplateArgument::Type: { 2097218893Sdim QualType ToType = Importer.Import(From.getAsType()); 2098218893Sdim if (ToType.isNull()) 2099218893Sdim return TemplateArgument(); 2100218893Sdim return TemplateArgument(ToType); 2101218893Sdim } 2102218893Sdim 2103218893Sdim case TemplateArgument::Integral: { 2104218893Sdim QualType ToType = Importer.Import(From.getIntegralType()); 2105218893Sdim if (ToType.isNull()) 2106218893Sdim return TemplateArgument(); 2107245431Sdim return TemplateArgument(From, ToType); 2108218893Sdim } 2109218893Sdim 2110245431Sdim case TemplateArgument::Declaration: { 2111245431Sdim ValueDecl *FromD = From.getAsDecl(); 2112245431Sdim if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD))) 2113245431Sdim return TemplateArgument(To, From.isDeclForReferenceParam()); 2114218893Sdim return TemplateArgument(); 2115245431Sdim } 2116245431Sdim 2117245431Sdim case TemplateArgument::NullPtr: { 2118245431Sdim QualType ToType = Importer.Import(From.getNullPtrType()); 2119245431Sdim if (ToType.isNull()) 2120245431Sdim return TemplateArgument(); 2121245431Sdim return TemplateArgument(ToType, /*isNullPtr*/true); 2122245431Sdim } 2123245431Sdim 2124218893Sdim case TemplateArgument::Template: { 2125218893Sdim TemplateName ToTemplate = Importer.Import(From.getAsTemplate()); 2126218893Sdim if (ToTemplate.isNull()) 2127218893Sdim return TemplateArgument(); 2128218893Sdim 2129218893Sdim return TemplateArgument(ToTemplate); 2130218893Sdim } 2131218893Sdim 2132218893Sdim case TemplateArgument::TemplateExpansion: { 2133218893Sdim TemplateName ToTemplate 2134218893Sdim = Importer.Import(From.getAsTemplateOrTemplatePattern()); 2135218893Sdim if (ToTemplate.isNull()) 2136218893Sdim return TemplateArgument(); 2137218893Sdim 2138218893Sdim return TemplateArgument(ToTemplate, From.getNumTemplateExpansions()); 2139218893Sdim } 2140218893Sdim 2141218893Sdim case TemplateArgument::Expression: 2142218893Sdim if (Expr *ToExpr = Importer.Import(From.getAsExpr())) 2143218893Sdim return TemplateArgument(ToExpr); 2144218893Sdim return TemplateArgument(); 2145218893Sdim 2146218893Sdim case TemplateArgument::Pack: { 2147226890Sdim SmallVector<TemplateArgument, 2> ToPack; 2148218893Sdim ToPack.reserve(From.pack_size()); 2149218893Sdim if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack)) 2150218893Sdim return TemplateArgument(); 2151218893Sdim 2152218893Sdim TemplateArgument *ToArgs 2153218893Sdim = new (Importer.getToContext()) TemplateArgument[ToPack.size()]; 2154218893Sdim std::copy(ToPack.begin(), ToPack.end(), ToArgs); 2155218893Sdim return TemplateArgument(ToArgs, ToPack.size()); 2156218893Sdim } 2157218893Sdim } 2158218893Sdim 2159218893Sdim llvm_unreachable("Invalid template argument kind"); 2160218893Sdim} 2161218893Sdim 2162218893Sdimbool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs, 2163218893Sdim unsigned NumFromArgs, 2164226890Sdim SmallVectorImpl<TemplateArgument> &ToArgs) { 2165218893Sdim for (unsigned I = 0; I != NumFromArgs; ++I) { 2166218893Sdim TemplateArgument To = ImportTemplateArgument(FromArgs[I]); 2167218893Sdim if (To.isNull() && !FromArgs[I].isNull()) 2168218893Sdim return true; 2169218893Sdim 2170218893Sdim ToArgs.push_back(To); 2171218893Sdim } 2172218893Sdim 2173218893Sdim return false; 2174218893Sdim} 2175218893Sdim 2176203955Srdivackybool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, 2177245431Sdim RecordDecl *ToRecord, bool Complain) { 2178263509Sdim // Eliminate a potential failure point where we attempt to re-import 2179263509Sdim // something we're trying to import while completing ToRecord. 2180263509Sdim Decl *ToOrigin = Importer.GetOriginalDecl(ToRecord); 2181263509Sdim if (ToOrigin) { 2182263509Sdim RecordDecl *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin); 2183263509Sdim if (ToOriginRecord) 2184263509Sdim ToRecord = ToOriginRecord; 2185263509Sdim } 2186263509Sdim 2187204643Srdivacky StructuralEquivalenceContext Ctx(Importer.getFromContext(), 2188263509Sdim ToRecord->getASTContext(), 2189245431Sdim Importer.getNonEquivalentDecls(), 2190245431Sdim false, Complain); 2191204643Srdivacky return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord); 2192203955Srdivacky} 2193203955Srdivacky 2194263509Sdimbool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, 2195263509Sdim bool Complain) { 2196263509Sdim StructuralEquivalenceContext Ctx( 2197263509Sdim Importer.getFromContext(), Importer.getToContext(), 2198263509Sdim Importer.getNonEquivalentDecls(), false, Complain); 2199263509Sdim return Ctx.IsStructurallyEquivalent(FromVar, ToVar); 2200263509Sdim} 2201263509Sdim 2202203955Srdivackybool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) { 2203204643Srdivacky StructuralEquivalenceContext Ctx(Importer.getFromContext(), 2204203955Srdivacky Importer.getToContext(), 2205203955Srdivacky Importer.getNonEquivalentDecls()); 2206204643Srdivacky return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); 2207203955Srdivacky} 2208203955Srdivacky 2209252723Sdimbool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, 2210252723Sdim EnumConstantDecl *ToEC) 2211252723Sdim{ 2212252723Sdim const llvm::APSInt &FromVal = FromEC->getInitVal(); 2213252723Sdim const llvm::APSInt &ToVal = ToEC->getInitVal(); 2214252723Sdim 2215252723Sdim return FromVal.isSigned() == ToVal.isSigned() && 2216252723Sdim FromVal.getBitWidth() == ToVal.getBitWidth() && 2217252723Sdim FromVal == ToVal; 2218252723Sdim} 2219252723Sdim 2220252723Sdimbool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From, 2221218893Sdim ClassTemplateDecl *To) { 2222218893Sdim StructuralEquivalenceContext Ctx(Importer.getFromContext(), 2223218893Sdim Importer.getToContext(), 2224218893Sdim Importer.getNonEquivalentDecls()); 2225218893Sdim return Ctx.IsStructurallyEquivalent(From, To); 2226218893Sdim} 2227218893Sdim 2228263509Sdimbool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From, 2229263509Sdim VarTemplateDecl *To) { 2230263509Sdim StructuralEquivalenceContext Ctx(Importer.getFromContext(), 2231263509Sdim Importer.getToContext(), 2232263509Sdim Importer.getNonEquivalentDecls()); 2233263509Sdim return Ctx.IsStructurallyEquivalent(From, To); 2234263509Sdim} 2235263509Sdim 2236203955SrdivackyDecl *ASTNodeImporter::VisitDecl(Decl *D) { 2237203955Srdivacky Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node) 2238203955Srdivacky << D->getDeclKindName(); 2239203955Srdivacky return 0; 2240203955Srdivacky} 2241203955Srdivacky 2242235633SdimDecl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 2243235633Sdim TranslationUnitDecl *ToD = 2244235633Sdim Importer.getToContext().getTranslationUnitDecl(); 2245235633Sdim 2246235633Sdim Importer.Imported(D, ToD); 2247235633Sdim 2248235633Sdim return ToD; 2249235633Sdim} 2250235633Sdim 2251204643SrdivackyDecl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) { 2252204643Srdivacky // Import the major distinguishing characteristics of this namespace. 2253204643Srdivacky DeclContext *DC, *LexicalDC; 2254204643Srdivacky DeclarationName Name; 2255204643Srdivacky SourceLocation Loc; 2256204643Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2257204643Srdivacky return 0; 2258204643Srdivacky 2259204643Srdivacky NamespaceDecl *MergeWithNamespace = 0; 2260204643Srdivacky if (!Name) { 2261204643Srdivacky // This is an anonymous namespace. Adopt an existing anonymous 2262204643Srdivacky // namespace if we can. 2263204643Srdivacky // FIXME: Not testable. 2264204643Srdivacky if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC)) 2265204643Srdivacky MergeWithNamespace = TU->getAnonymousNamespace(); 2266204643Srdivacky else 2267204643Srdivacky MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace(); 2268204643Srdivacky } else { 2269226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 2270252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2271226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2272226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2273226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Namespace)) 2274204643Srdivacky continue; 2275204643Srdivacky 2276226890Sdim if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(FoundDecls[I])) { 2277204643Srdivacky MergeWithNamespace = FoundNS; 2278204643Srdivacky ConflictingDecls.clear(); 2279204643Srdivacky break; 2280204643Srdivacky } 2281204643Srdivacky 2282226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 2283204643Srdivacky } 2284204643Srdivacky 2285204643Srdivacky if (!ConflictingDecls.empty()) { 2286207619Srdivacky Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace, 2287204643Srdivacky ConflictingDecls.data(), 2288204643Srdivacky ConflictingDecls.size()); 2289204643Srdivacky } 2290204643Srdivacky } 2291204643Srdivacky 2292204643Srdivacky // Create the "to" namespace, if needed. 2293204643Srdivacky NamespaceDecl *ToNamespace = MergeWithNamespace; 2294204643Srdivacky if (!ToNamespace) { 2295221345Sdim ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC, 2296235633Sdim D->isInline(), 2297221345Sdim Importer.Import(D->getLocStart()), 2298235633Sdim Loc, Name.getAsIdentifierInfo(), 2299235633Sdim /*PrevDecl=*/0); 2300204643Srdivacky ToNamespace->setLexicalDeclContext(LexicalDC); 2301235633Sdim LexicalDC->addDeclInternal(ToNamespace); 2302204643Srdivacky 2303204643Srdivacky // If this is an anonymous namespace, register it as the anonymous 2304204643Srdivacky // namespace within its context. 2305204643Srdivacky if (!Name) { 2306204643Srdivacky if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC)) 2307204643Srdivacky TU->setAnonymousNamespace(ToNamespace); 2308204643Srdivacky else 2309204643Srdivacky cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace); 2310204643Srdivacky } 2311204643Srdivacky } 2312204643Srdivacky Importer.Imported(D, ToNamespace); 2313204643Srdivacky 2314204643Srdivacky ImportDeclContext(D); 2315204643Srdivacky 2316204643Srdivacky return ToNamespace; 2317204643Srdivacky} 2318204643Srdivacky 2319221345SdimDecl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) { 2320203955Srdivacky // Import the major distinguishing characteristics of this typedef. 2321203955Srdivacky DeclContext *DC, *LexicalDC; 2322203955Srdivacky DeclarationName Name; 2323203955Srdivacky SourceLocation Loc; 2324203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2325203955Srdivacky return 0; 2326203955Srdivacky 2327203955Srdivacky // If this typedef is not in block scope, determine whether we've 2328203955Srdivacky // seen a typedef with the same name (that we can merge with) or any 2329203955Srdivacky // other entity by that name (which name lookup could conflict with). 2330203955Srdivacky if (!DC->isFunctionOrMethod()) { 2331226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 2332203955Srdivacky unsigned IDNS = Decl::IDNS_Ordinary; 2333252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2334226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2335226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2336226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) 2337203955Srdivacky continue; 2338221345Sdim if (TypedefNameDecl *FoundTypedef = 2339226890Sdim dyn_cast<TypedefNameDecl>(FoundDecls[I])) { 2340203955Srdivacky if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(), 2341203955Srdivacky FoundTypedef->getUnderlyingType())) 2342203955Srdivacky return Importer.Imported(D, FoundTypedef); 2343203955Srdivacky } 2344203955Srdivacky 2345226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 2346203955Srdivacky } 2347203955Srdivacky 2348203955Srdivacky if (!ConflictingDecls.empty()) { 2349203955Srdivacky Name = Importer.HandleNameConflict(Name, DC, IDNS, 2350203955Srdivacky ConflictingDecls.data(), 2351203955Srdivacky ConflictingDecls.size()); 2352203955Srdivacky if (!Name) 2353203955Srdivacky return 0; 2354203955Srdivacky } 2355203955Srdivacky } 2356203955Srdivacky 2357203955Srdivacky // Import the underlying type of this typedef; 2358203955Srdivacky QualType T = Importer.Import(D->getUnderlyingType()); 2359203955Srdivacky if (T.isNull()) 2360203955Srdivacky return 0; 2361203955Srdivacky 2362203955Srdivacky // Create the new typedef node. 2363203955Srdivacky TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 2364221345Sdim SourceLocation StartL = Importer.Import(D->getLocStart()); 2365221345Sdim TypedefNameDecl *ToTypedef; 2366221345Sdim if (IsAlias) 2367226890Sdim ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC, 2368226890Sdim StartL, Loc, 2369226890Sdim Name.getAsIdentifierInfo(), 2370226890Sdim TInfo); 2371226890Sdim else 2372221345Sdim ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC, 2373221345Sdim StartL, Loc, 2374221345Sdim Name.getAsIdentifierInfo(), 2375221345Sdim TInfo); 2376226890Sdim 2377204643Srdivacky ToTypedef->setAccess(D->getAccess()); 2378203955Srdivacky ToTypedef->setLexicalDeclContext(LexicalDC); 2379203955Srdivacky Importer.Imported(D, ToTypedef); 2380235633Sdim LexicalDC->addDeclInternal(ToTypedef); 2381203955Srdivacky 2382203955Srdivacky return ToTypedef; 2383203955Srdivacky} 2384203955Srdivacky 2385221345SdimDecl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) { 2386221345Sdim return VisitTypedefNameDecl(D, /*IsAlias=*/false); 2387221345Sdim} 2388221345Sdim 2389221345SdimDecl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) { 2390221345Sdim return VisitTypedefNameDecl(D, /*IsAlias=*/true); 2391221345Sdim} 2392221345Sdim 2393203955SrdivackyDecl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { 2394203955Srdivacky // Import the major distinguishing characteristics of this enum. 2395203955Srdivacky DeclContext *DC, *LexicalDC; 2396203955Srdivacky DeclarationName Name; 2397203955Srdivacky SourceLocation Loc; 2398203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2399203955Srdivacky return 0; 2400203955Srdivacky 2401203955Srdivacky // Figure out what enum name we're looking for. 2402203955Srdivacky unsigned IDNS = Decl::IDNS_Tag; 2403203955Srdivacky DeclarationName SearchName = Name; 2404221345Sdim if (!SearchName && D->getTypedefNameForAnonDecl()) { 2405221345Sdim SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName()); 2406203955Srdivacky IDNS = Decl::IDNS_Ordinary; 2407235633Sdim } else if (Importer.getToContext().getLangOpts().CPlusPlus) 2408203955Srdivacky IDNS |= Decl::IDNS_Ordinary; 2409203955Srdivacky 2410203955Srdivacky // We may already have an enum of the same name; try to find and match it. 2411203955Srdivacky if (!DC->isFunctionOrMethod() && SearchName) { 2412226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 2413252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2414226890Sdim DC->localUncachedLookup(SearchName, FoundDecls); 2415226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2416226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) 2417203955Srdivacky continue; 2418203955Srdivacky 2419226890Sdim Decl *Found = FoundDecls[I]; 2420221345Sdim if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) { 2421203955Srdivacky if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) 2422203955Srdivacky Found = Tag->getDecl(); 2423203955Srdivacky } 2424203955Srdivacky 2425203955Srdivacky if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) { 2426203955Srdivacky if (IsStructuralMatch(D, FoundEnum)) 2427203955Srdivacky return Importer.Imported(D, FoundEnum); 2428203955Srdivacky } 2429203955Srdivacky 2430226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 2431203955Srdivacky } 2432203955Srdivacky 2433203955Srdivacky if (!ConflictingDecls.empty()) { 2434203955Srdivacky Name = Importer.HandleNameConflict(Name, DC, IDNS, 2435203955Srdivacky ConflictingDecls.data(), 2436203955Srdivacky ConflictingDecls.size()); 2437203955Srdivacky } 2438203955Srdivacky } 2439203955Srdivacky 2440203955Srdivacky // Create the enum declaration. 2441221345Sdim EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC, 2442221345Sdim Importer.Import(D->getLocStart()), 2443221345Sdim Loc, Name.getAsIdentifierInfo(), 0, 2444218893Sdim D->isScoped(), D->isScopedUsingClassTag(), 2445218893Sdim D->isFixed()); 2446205219Srdivacky // Import the qualifier, if any. 2447219077Sdim D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); 2448204643Srdivacky D2->setAccess(D->getAccess()); 2449203955Srdivacky D2->setLexicalDeclContext(LexicalDC); 2450203955Srdivacky Importer.Imported(D, D2); 2451235633Sdim LexicalDC->addDeclInternal(D2); 2452203955Srdivacky 2453203955Srdivacky // Import the integer type. 2454203955Srdivacky QualType ToIntegerType = Importer.Import(D->getIntegerType()); 2455203955Srdivacky if (ToIntegerType.isNull()) 2456203955Srdivacky return 0; 2457203955Srdivacky D2->setIntegerType(ToIntegerType); 2458203955Srdivacky 2459203955Srdivacky // Import the definition 2460226890Sdim if (D->isCompleteDefinition() && ImportDefinition(D, D2)) 2461226890Sdim return 0; 2462203955Srdivacky 2463203955Srdivacky return D2; 2464203955Srdivacky} 2465203955Srdivacky 2466203955SrdivackyDecl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { 2467203955Srdivacky // If this record has a definition in the translation unit we're coming from, 2468203955Srdivacky // but this particular declaration is not that definition, import the 2469203955Srdivacky // definition and map to that. 2470203955Srdivacky TagDecl *Definition = D->getDefinition(); 2471203955Srdivacky if (Definition && Definition != D) { 2472203955Srdivacky Decl *ImportedDef = Importer.Import(Definition); 2473203955Srdivacky if (!ImportedDef) 2474203955Srdivacky return 0; 2475203955Srdivacky 2476203955Srdivacky return Importer.Imported(D, ImportedDef); 2477203955Srdivacky } 2478203955Srdivacky 2479203955Srdivacky // Import the major distinguishing characteristics of this record. 2480203955Srdivacky DeclContext *DC, *LexicalDC; 2481203955Srdivacky DeclarationName Name; 2482203955Srdivacky SourceLocation Loc; 2483203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2484203955Srdivacky return 0; 2485203955Srdivacky 2486203955Srdivacky // Figure out what structure name we're looking for. 2487203955Srdivacky unsigned IDNS = Decl::IDNS_Tag; 2488203955Srdivacky DeclarationName SearchName = Name; 2489221345Sdim if (!SearchName && D->getTypedefNameForAnonDecl()) { 2490221345Sdim SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName()); 2491203955Srdivacky IDNS = Decl::IDNS_Ordinary; 2492235633Sdim } else if (Importer.getToContext().getLangOpts().CPlusPlus) 2493203955Srdivacky IDNS |= Decl::IDNS_Ordinary; 2494203955Srdivacky 2495203955Srdivacky // We may already have a record of the same name; try to find and match it. 2496203955Srdivacky RecordDecl *AdoptDecl = 0; 2497245431Sdim if (!DC->isFunctionOrMethod()) { 2498226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 2499252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2500226890Sdim DC->localUncachedLookup(SearchName, FoundDecls); 2501226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2502226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) 2503203955Srdivacky continue; 2504203955Srdivacky 2505226890Sdim Decl *Found = FoundDecls[I]; 2506221345Sdim if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) { 2507203955Srdivacky if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) 2508203955Srdivacky Found = Tag->getDecl(); 2509203955Srdivacky } 2510203955Srdivacky 2511203955Srdivacky if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) { 2512245431Sdim if (D->isAnonymousStructOrUnion() && 2513245431Sdim FoundRecord->isAnonymousStructOrUnion()) { 2514245431Sdim // If both anonymous structs/unions are in a record context, make sure 2515245431Sdim // they occur in the same location in the context records. 2516252723Sdim if (Optional<unsigned> Index1 2517245431Sdim = findAnonymousStructOrUnionIndex(D)) { 2518252723Sdim if (Optional<unsigned> Index2 = 2519252723Sdim findAnonymousStructOrUnionIndex(FoundRecord)) { 2520245431Sdim if (*Index1 != *Index2) 2521245431Sdim continue; 2522245431Sdim } 2523245431Sdim } 2524245431Sdim } 2525245431Sdim 2526203955Srdivacky if (RecordDecl *FoundDef = FoundRecord->getDefinition()) { 2527245431Sdim if ((SearchName && !D->isCompleteDefinition()) 2528245431Sdim || (D->isCompleteDefinition() && 2529245431Sdim D->isAnonymousStructOrUnion() 2530245431Sdim == FoundDef->isAnonymousStructOrUnion() && 2531245431Sdim IsStructuralMatch(D, FoundDef))) { 2532203955Srdivacky // The record types structurally match, or the "from" translation 2533203955Srdivacky // unit only had a forward declaration anyway; call it the same 2534203955Srdivacky // function. 2535203955Srdivacky // FIXME: For C++, we should also merge methods here. 2536203955Srdivacky return Importer.Imported(D, FoundDef); 2537203955Srdivacky } 2538245431Sdim } else if (!D->isCompleteDefinition()) { 2539203955Srdivacky // We have a forward declaration of this type, so adopt that forward 2540203955Srdivacky // declaration rather than building a new one. 2541203955Srdivacky AdoptDecl = FoundRecord; 2542203955Srdivacky continue; 2543245431Sdim } else if (!SearchName) { 2544245431Sdim continue; 2545245431Sdim } 2546203955Srdivacky } 2547203955Srdivacky 2548226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 2549203955Srdivacky } 2550203955Srdivacky 2551245431Sdim if (!ConflictingDecls.empty() && SearchName) { 2552203955Srdivacky Name = Importer.HandleNameConflict(Name, DC, IDNS, 2553203955Srdivacky ConflictingDecls.data(), 2554203955Srdivacky ConflictingDecls.size()); 2555203955Srdivacky } 2556203955Srdivacky } 2557203955Srdivacky 2558203955Srdivacky // Create the record declaration. 2559203955Srdivacky RecordDecl *D2 = AdoptDecl; 2560221345Sdim SourceLocation StartLoc = Importer.Import(D->getLocStart()); 2561203955Srdivacky if (!D2) { 2562210299Sed if (isa<CXXRecordDecl>(D)) { 2563203955Srdivacky CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(), 2564203955Srdivacky D->getTagKind(), 2565221345Sdim DC, StartLoc, Loc, 2566221345Sdim Name.getAsIdentifierInfo()); 2567203955Srdivacky D2 = D2CXX; 2568204643Srdivacky D2->setAccess(D->getAccess()); 2569203955Srdivacky } else { 2570203955Srdivacky D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(), 2571221345Sdim DC, StartLoc, Loc, Name.getAsIdentifierInfo()); 2572203955Srdivacky } 2573219077Sdim 2574219077Sdim D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); 2575203955Srdivacky D2->setLexicalDeclContext(LexicalDC); 2576235633Sdim LexicalDC->addDeclInternal(D2); 2577245431Sdim if (D->isAnonymousStructOrUnion()) 2578245431Sdim D2->setAnonymousStructOrUnion(true); 2579203955Srdivacky } 2580203955Srdivacky 2581203955Srdivacky Importer.Imported(D, D2); 2582203955Srdivacky 2583235633Sdim if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default)) 2584218893Sdim return 0; 2585203955Srdivacky 2586203955Srdivacky return D2; 2587203955Srdivacky} 2588203955Srdivacky 2589203955SrdivackyDecl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) { 2590203955Srdivacky // Import the major distinguishing characteristics of this enumerator. 2591203955Srdivacky DeclContext *DC, *LexicalDC; 2592203955Srdivacky DeclarationName Name; 2593203955Srdivacky SourceLocation Loc; 2594203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2595203955Srdivacky return 0; 2596203955Srdivacky 2597203955Srdivacky QualType T = Importer.Import(D->getType()); 2598203955Srdivacky if (T.isNull()) 2599203955Srdivacky return 0; 2600203955Srdivacky 2601203955Srdivacky // Determine whether there are any other declarations with the same name and 2602203955Srdivacky // in the same context. 2603203955Srdivacky if (!LexicalDC->isFunctionOrMethod()) { 2604226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 2605203955Srdivacky unsigned IDNS = Decl::IDNS_Ordinary; 2606252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2607226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2608226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2609226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) 2610203955Srdivacky continue; 2611252723Sdim 2612252723Sdim if (EnumConstantDecl *FoundEnumConstant 2613252723Sdim = dyn_cast<EnumConstantDecl>(FoundDecls[I])) { 2614252723Sdim if (IsStructuralMatch(D, FoundEnumConstant)) 2615252723Sdim return Importer.Imported(D, FoundEnumConstant); 2616252723Sdim } 2617252723Sdim 2618226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 2619203955Srdivacky } 2620203955Srdivacky 2621203955Srdivacky if (!ConflictingDecls.empty()) { 2622203955Srdivacky Name = Importer.HandleNameConflict(Name, DC, IDNS, 2623203955Srdivacky ConflictingDecls.data(), 2624203955Srdivacky ConflictingDecls.size()); 2625203955Srdivacky if (!Name) 2626203955Srdivacky return 0; 2627203955Srdivacky } 2628203955Srdivacky } 2629203955Srdivacky 2630203955Srdivacky Expr *Init = Importer.Import(D->getInitExpr()); 2631203955Srdivacky if (D->getInitExpr() && !Init) 2632203955Srdivacky return 0; 2633203955Srdivacky 2634203955Srdivacky EnumConstantDecl *ToEnumerator 2635203955Srdivacky = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc, 2636203955Srdivacky Name.getAsIdentifierInfo(), T, 2637203955Srdivacky Init, D->getInitVal()); 2638204643Srdivacky ToEnumerator->setAccess(D->getAccess()); 2639203955Srdivacky ToEnumerator->setLexicalDeclContext(LexicalDC); 2640203955Srdivacky Importer.Imported(D, ToEnumerator); 2641235633Sdim LexicalDC->addDeclInternal(ToEnumerator); 2642203955Srdivacky return ToEnumerator; 2643203955Srdivacky} 2644203955Srdivacky 2645203955SrdivackyDecl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { 2646203955Srdivacky // Import the major distinguishing characteristics of this function. 2647203955Srdivacky DeclContext *DC, *LexicalDC; 2648203955Srdivacky DeclarationName Name; 2649203955Srdivacky SourceLocation Loc; 2650203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2651203955Srdivacky return 0; 2652212904Sdim 2653203955Srdivacky // Try to find a function in our own ("to") context with the same name, same 2654203955Srdivacky // type, and in the same context as the function we're importing. 2655203955Srdivacky if (!LexicalDC->isFunctionOrMethod()) { 2656226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 2657203955Srdivacky unsigned IDNS = Decl::IDNS_Ordinary; 2658252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2659226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2660226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2661226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) 2662203955Srdivacky continue; 2663203955Srdivacky 2664226890Sdim if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) { 2665263509Sdim if (FoundFunction->hasExternalFormalLinkage() && 2666263509Sdim D->hasExternalFormalLinkage()) { 2667203955Srdivacky if (Importer.IsStructurallyEquivalent(D->getType(), 2668203955Srdivacky FoundFunction->getType())) { 2669203955Srdivacky // FIXME: Actually try to merge the body and other attributes. 2670203955Srdivacky return Importer.Imported(D, FoundFunction); 2671203955Srdivacky } 2672203955Srdivacky 2673203955Srdivacky // FIXME: Check for overloading more carefully, e.g., by boosting 2674203955Srdivacky // Sema::IsOverload out to the AST library. 2675203955Srdivacky 2676203955Srdivacky // Function overloading is okay in C++. 2677235633Sdim if (Importer.getToContext().getLangOpts().CPlusPlus) 2678203955Srdivacky continue; 2679203955Srdivacky 2680203955Srdivacky // Complain about inconsistent function types. 2681203955Srdivacky Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent) 2682203955Srdivacky << Name << D->getType() << FoundFunction->getType(); 2683203955Srdivacky Importer.ToDiag(FoundFunction->getLocation(), 2684203955Srdivacky diag::note_odr_value_here) 2685203955Srdivacky << FoundFunction->getType(); 2686203955Srdivacky } 2687203955Srdivacky } 2688203955Srdivacky 2689226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 2690203955Srdivacky } 2691203955Srdivacky 2692203955Srdivacky if (!ConflictingDecls.empty()) { 2693203955Srdivacky Name = Importer.HandleNameConflict(Name, DC, IDNS, 2694203955Srdivacky ConflictingDecls.data(), 2695203955Srdivacky ConflictingDecls.size()); 2696203955Srdivacky if (!Name) 2697203955Srdivacky return 0; 2698203955Srdivacky } 2699203955Srdivacky } 2700203955Srdivacky 2701212904Sdim DeclarationNameInfo NameInfo(Name, Loc); 2702212904Sdim // Import additional name location/type info. 2703212904Sdim ImportDeclarationNameLoc(D->getNameInfo(), NameInfo); 2704212904Sdim 2705245431Sdim QualType FromTy = D->getType(); 2706245431Sdim bool usedDifferentExceptionSpec = false; 2707245431Sdim 2708245431Sdim if (const FunctionProtoType * 2709245431Sdim FromFPT = D->getType()->getAs<FunctionProtoType>()) { 2710245431Sdim FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo(); 2711245431Sdim // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the 2712245431Sdim // FunctionDecl that we are importing the FunctionProtoType for. 2713245431Sdim // To avoid an infinite recursion when importing, create the FunctionDecl 2714245431Sdim // with a simplified function type and update it afterwards. 2715245431Sdim if (FromEPI.ExceptionSpecDecl || FromEPI.ExceptionSpecTemplate || 2716245431Sdim FromEPI.NoexceptExpr) { 2717245431Sdim FunctionProtoType::ExtProtoInfo DefaultEPI; 2718245431Sdim FromTy = Importer.getFromContext().getFunctionType( 2719263509Sdim FromFPT->getResultType(), FromFPT->getArgTypes(), DefaultEPI); 2720245431Sdim usedDifferentExceptionSpec = true; 2721245431Sdim } 2722245431Sdim } 2723245431Sdim 2724203955Srdivacky // Import the type. 2725245431Sdim QualType T = Importer.Import(FromTy); 2726203955Srdivacky if (T.isNull()) 2727203955Srdivacky return 0; 2728203955Srdivacky 2729203955Srdivacky // Import the function parameters. 2730226890Sdim SmallVector<ParmVarDecl *, 8> Parameters; 2731203955Srdivacky for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end(); 2732203955Srdivacky P != PEnd; ++P) { 2733203955Srdivacky ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P)); 2734203955Srdivacky if (!ToP) 2735203955Srdivacky return 0; 2736203955Srdivacky 2737203955Srdivacky Parameters.push_back(ToP); 2738203955Srdivacky } 2739203955Srdivacky 2740203955Srdivacky // Create the imported function. 2741203955Srdivacky TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 2742204643Srdivacky FunctionDecl *ToFunction = 0; 2743204643Srdivacky if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) { 2744204643Srdivacky ToFunction = CXXConstructorDecl::Create(Importer.getToContext(), 2745204643Srdivacky cast<CXXRecordDecl>(DC), 2746221345Sdim D->getInnerLocStart(), 2747212904Sdim NameInfo, T, TInfo, 2748204643Srdivacky FromConstructor->isExplicit(), 2749204643Srdivacky D->isInlineSpecified(), 2750226890Sdim D->isImplicit(), 2751226890Sdim D->isConstexpr()); 2752204643Srdivacky } else if (isa<CXXDestructorDecl>(D)) { 2753204643Srdivacky ToFunction = CXXDestructorDecl::Create(Importer.getToContext(), 2754204643Srdivacky cast<CXXRecordDecl>(DC), 2755221345Sdim D->getInnerLocStart(), 2756218893Sdim NameInfo, T, TInfo, 2757204643Srdivacky D->isInlineSpecified(), 2758204643Srdivacky D->isImplicit()); 2759204643Srdivacky } else if (CXXConversionDecl *FromConversion 2760204643Srdivacky = dyn_cast<CXXConversionDecl>(D)) { 2761204643Srdivacky ToFunction = CXXConversionDecl::Create(Importer.getToContext(), 2762204643Srdivacky cast<CXXRecordDecl>(DC), 2763221345Sdim D->getInnerLocStart(), 2764212904Sdim NameInfo, T, TInfo, 2765204643Srdivacky D->isInlineSpecified(), 2766221345Sdim FromConversion->isExplicit(), 2767226890Sdim D->isConstexpr(), 2768221345Sdim Importer.Import(D->getLocEnd())); 2769218893Sdim } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { 2770218893Sdim ToFunction = CXXMethodDecl::Create(Importer.getToContext(), 2771218893Sdim cast<CXXRecordDecl>(DC), 2772221345Sdim D->getInnerLocStart(), 2773218893Sdim NameInfo, T, TInfo, 2774252723Sdim Method->getStorageClass(), 2775221345Sdim Method->isInlineSpecified(), 2776226890Sdim D->isConstexpr(), 2777221345Sdim Importer.Import(D->getLocEnd())); 2778204643Srdivacky } else { 2779212904Sdim ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, 2780221345Sdim D->getInnerLocStart(), 2781212904Sdim NameInfo, T, TInfo, D->getStorageClass(), 2782204643Srdivacky D->isInlineSpecified(), 2783226890Sdim D->hasWrittenPrototype(), 2784226890Sdim D->isConstexpr()); 2785204643Srdivacky } 2786205219Srdivacky 2787205219Srdivacky // Import the qualifier, if any. 2788219077Sdim ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc())); 2789204643Srdivacky ToFunction->setAccess(D->getAccess()); 2790204643Srdivacky ToFunction->setLexicalDeclContext(LexicalDC); 2791218893Sdim ToFunction->setVirtualAsWritten(D->isVirtualAsWritten()); 2792218893Sdim ToFunction->setTrivial(D->isTrivial()); 2793218893Sdim ToFunction->setPure(D->isPure()); 2794204643Srdivacky Importer.Imported(D, ToFunction); 2795203955Srdivacky 2796203955Srdivacky // Set the parameters. 2797203955Srdivacky for (unsigned I = 0, N = Parameters.size(); I != N; ++I) { 2798204643Srdivacky Parameters[I]->setOwningFunction(ToFunction); 2799235633Sdim ToFunction->addDeclInternal(Parameters[I]); 2800203955Srdivacky } 2801226890Sdim ToFunction->setParams(Parameters); 2802203955Srdivacky 2803245431Sdim if (usedDifferentExceptionSpec) { 2804245431Sdim // Update FunctionProtoType::ExtProtoInfo. 2805245431Sdim QualType T = Importer.Import(D->getType()); 2806245431Sdim if (T.isNull()) 2807245431Sdim return 0; 2808245431Sdim ToFunction->setType(T); 2809245431Sdim } 2810245431Sdim 2811203955Srdivacky // FIXME: Other bits to merge? 2812218893Sdim 2813218893Sdim // Add this function to the lexical context. 2814235633Sdim LexicalDC->addDeclInternal(ToFunction); 2815218893Sdim 2816204643Srdivacky return ToFunction; 2817203955Srdivacky} 2818203955Srdivacky 2819204643SrdivackyDecl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) { 2820204643Srdivacky return VisitFunctionDecl(D); 2821204643Srdivacky} 2822204643Srdivacky 2823204643SrdivackyDecl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { 2824204643Srdivacky return VisitCXXMethodDecl(D); 2825204643Srdivacky} 2826204643Srdivacky 2827204643SrdivackyDecl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { 2828204643Srdivacky return VisitCXXMethodDecl(D); 2829204643Srdivacky} 2830204643Srdivacky 2831204643SrdivackyDecl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) { 2832204643Srdivacky return VisitCXXMethodDecl(D); 2833204643Srdivacky} 2834204643Srdivacky 2835245431Sdimstatic unsigned getFieldIndex(Decl *F) { 2836245431Sdim RecordDecl *Owner = dyn_cast<RecordDecl>(F->getDeclContext()); 2837245431Sdim if (!Owner) 2838245431Sdim return 0; 2839245431Sdim 2840245431Sdim unsigned Index = 1; 2841245431Sdim for (DeclContext::decl_iterator D = Owner->noload_decls_begin(), 2842245431Sdim DEnd = Owner->noload_decls_end(); 2843245431Sdim D != DEnd; ++D) { 2844245431Sdim if (*D == F) 2845245431Sdim return Index; 2846245431Sdim 2847245431Sdim if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) 2848245431Sdim ++Index; 2849245431Sdim } 2850245431Sdim 2851245431Sdim return Index; 2852245431Sdim} 2853245431Sdim 2854203955SrdivackyDecl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) { 2855203955Srdivacky // Import the major distinguishing characteristics of a variable. 2856203955Srdivacky DeclContext *DC, *LexicalDC; 2857203955Srdivacky DeclarationName Name; 2858203955Srdivacky SourceLocation Loc; 2859203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2860203955Srdivacky return 0; 2861203955Srdivacky 2862226890Sdim // Determine whether we've already imported this field. 2863252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2864226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2865226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2866226890Sdim if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) { 2867245431Sdim // For anonymous fields, match up by index. 2868245431Sdim if (!Name && getFieldIndex(D) != getFieldIndex(FoundField)) 2869245431Sdim continue; 2870245431Sdim 2871226890Sdim if (Importer.IsStructurallyEquivalent(D->getType(), 2872226890Sdim FoundField->getType())) { 2873226890Sdim Importer.Imported(D, FoundField); 2874226890Sdim return FoundField; 2875226890Sdim } 2876226890Sdim 2877226890Sdim Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent) 2878226890Sdim << Name << D->getType() << FoundField->getType(); 2879226890Sdim Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here) 2880226890Sdim << FoundField->getType(); 2881226890Sdim return 0; 2882226890Sdim } 2883226890Sdim } 2884226890Sdim 2885203955Srdivacky // Import the type. 2886203955Srdivacky QualType T = Importer.Import(D->getType()); 2887203955Srdivacky if (T.isNull()) 2888203955Srdivacky return 0; 2889203955Srdivacky 2890203955Srdivacky TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 2891203955Srdivacky Expr *BitWidth = Importer.Import(D->getBitWidth()); 2892203955Srdivacky if (!BitWidth && D->getBitWidth()) 2893203955Srdivacky return 0; 2894203955Srdivacky 2895221345Sdim FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC, 2896221345Sdim Importer.Import(D->getInnerLocStart()), 2897203955Srdivacky Loc, Name.getAsIdentifierInfo(), 2898223017Sdim T, TInfo, BitWidth, D->isMutable(), 2899245431Sdim D->getInClassInitStyle()); 2900204643Srdivacky ToField->setAccess(D->getAccess()); 2901203955Srdivacky ToField->setLexicalDeclContext(LexicalDC); 2902223017Sdim if (ToField->hasInClassInitializer()) 2903223017Sdim ToField->setInClassInitializer(D->getInClassInitializer()); 2904245431Sdim ToField->setImplicit(D->isImplicit()); 2905203955Srdivacky Importer.Imported(D, ToField); 2906235633Sdim LexicalDC->addDeclInternal(ToField); 2907203955Srdivacky return ToField; 2908203955Srdivacky} 2909203955Srdivacky 2910218893SdimDecl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { 2911218893Sdim // Import the major distinguishing characteristics of a variable. 2912218893Sdim DeclContext *DC, *LexicalDC; 2913218893Sdim DeclarationName Name; 2914218893Sdim SourceLocation Loc; 2915218893Sdim if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2916218893Sdim return 0; 2917218893Sdim 2918226890Sdim // Determine whether we've already imported this field. 2919252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2920226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2921226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2922226890Sdim if (IndirectFieldDecl *FoundField 2923226890Sdim = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) { 2924245431Sdim // For anonymous indirect fields, match up by index. 2925245431Sdim if (!Name && getFieldIndex(D) != getFieldIndex(FoundField)) 2926245431Sdim continue; 2927245431Sdim 2928226890Sdim if (Importer.IsStructurallyEquivalent(D->getType(), 2929245431Sdim FoundField->getType(), 2930263509Sdim !Name.isEmpty())) { 2931226890Sdim Importer.Imported(D, FoundField); 2932226890Sdim return FoundField; 2933226890Sdim } 2934245431Sdim 2935245431Sdim // If there are more anonymous fields to check, continue. 2936245431Sdim if (!Name && I < N-1) 2937245431Sdim continue; 2938245431Sdim 2939226890Sdim Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent) 2940226890Sdim << Name << D->getType() << FoundField->getType(); 2941226890Sdim Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here) 2942226890Sdim << FoundField->getType(); 2943226890Sdim return 0; 2944226890Sdim } 2945226890Sdim } 2946226890Sdim 2947218893Sdim // Import the type. 2948218893Sdim QualType T = Importer.Import(D->getType()); 2949218893Sdim if (T.isNull()) 2950218893Sdim return 0; 2951218893Sdim 2952218893Sdim NamedDecl **NamedChain = 2953218893Sdim new (Importer.getToContext())NamedDecl*[D->getChainingSize()]; 2954218893Sdim 2955218893Sdim unsigned i = 0; 2956218893Sdim for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(), 2957218893Sdim PE = D->chain_end(); PI != PE; ++PI) { 2958218893Sdim Decl* D = Importer.Import(*PI); 2959218893Sdim if (!D) 2960218893Sdim return 0; 2961218893Sdim NamedChain[i++] = cast<NamedDecl>(D); 2962218893Sdim } 2963218893Sdim 2964218893Sdim IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create( 2965218893Sdim Importer.getToContext(), DC, 2966218893Sdim Loc, Name.getAsIdentifierInfo(), T, 2967218893Sdim NamedChain, D->getChainingSize()); 2968218893Sdim ToIndirectField->setAccess(D->getAccess()); 2969218893Sdim ToIndirectField->setLexicalDeclContext(LexicalDC); 2970218893Sdim Importer.Imported(D, ToIndirectField); 2971235633Sdim LexicalDC->addDeclInternal(ToIndirectField); 2972218893Sdim return ToIndirectField; 2973218893Sdim} 2974218893Sdim 2975204643SrdivackyDecl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) { 2976204643Srdivacky // Import the major distinguishing characteristics of an ivar. 2977204643Srdivacky DeclContext *DC, *LexicalDC; 2978204643Srdivacky DeclarationName Name; 2979204643Srdivacky SourceLocation Loc; 2980204643Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 2981204643Srdivacky return 0; 2982204643Srdivacky 2983204643Srdivacky // Determine whether we've already imported this ivar 2984252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 2985226890Sdim DC->localUncachedLookup(Name, FoundDecls); 2986226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 2987226890Sdim if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) { 2988204643Srdivacky if (Importer.IsStructurallyEquivalent(D->getType(), 2989204643Srdivacky FoundIvar->getType())) { 2990204643Srdivacky Importer.Imported(D, FoundIvar); 2991204643Srdivacky return FoundIvar; 2992204643Srdivacky } 2993204643Srdivacky 2994204643Srdivacky Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent) 2995204643Srdivacky << Name << D->getType() << FoundIvar->getType(); 2996204643Srdivacky Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here) 2997204643Srdivacky << FoundIvar->getType(); 2998204643Srdivacky return 0; 2999204643Srdivacky } 3000204643Srdivacky } 3001204643Srdivacky 3002204643Srdivacky // Import the type. 3003204643Srdivacky QualType T = Importer.Import(D->getType()); 3004204643Srdivacky if (T.isNull()) 3005204643Srdivacky return 0; 3006204643Srdivacky 3007204643Srdivacky TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 3008204643Srdivacky Expr *BitWidth = Importer.Import(D->getBitWidth()); 3009204643Srdivacky if (!BitWidth && D->getBitWidth()) 3010204643Srdivacky return 0; 3011204643Srdivacky 3012206125Srdivacky ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(), 3013206125Srdivacky cast<ObjCContainerDecl>(DC), 3014221345Sdim Importer.Import(D->getInnerLocStart()), 3015204643Srdivacky Loc, Name.getAsIdentifierInfo(), 3016204643Srdivacky T, TInfo, D->getAccessControl(), 3017263509Sdim BitWidth, D->getSynthesize(), 3018263509Sdim D->getBackingIvarReferencedInAccessor()); 3019204643Srdivacky ToIvar->setLexicalDeclContext(LexicalDC); 3020204643Srdivacky Importer.Imported(D, ToIvar); 3021235633Sdim LexicalDC->addDeclInternal(ToIvar); 3022204643Srdivacky return ToIvar; 3023204643Srdivacky 3024204643Srdivacky} 3025204643Srdivacky 3026203955SrdivackyDecl *ASTNodeImporter::VisitVarDecl(VarDecl *D) { 3027203955Srdivacky // Import the major distinguishing characteristics of a variable. 3028203955Srdivacky DeclContext *DC, *LexicalDC; 3029203955Srdivacky DeclarationName Name; 3030203955Srdivacky SourceLocation Loc; 3031203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3032203955Srdivacky return 0; 3033203955Srdivacky 3034203955Srdivacky // Try to find a variable in our own ("to") context with the same name and 3035203955Srdivacky // in the same context as the variable we're importing. 3036203955Srdivacky if (D->isFileVarDecl()) { 3037203955Srdivacky VarDecl *MergeWithVar = 0; 3038226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 3039203955Srdivacky unsigned IDNS = Decl::IDNS_Ordinary; 3040252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 3041226890Sdim DC->localUncachedLookup(Name, FoundDecls); 3042226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 3043226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) 3044203955Srdivacky continue; 3045203955Srdivacky 3046226890Sdim if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) { 3047203955Srdivacky // We have found a variable that we may need to merge with. Check it. 3048263509Sdim if (FoundVar->hasExternalFormalLinkage() && 3049263509Sdim D->hasExternalFormalLinkage()) { 3050203955Srdivacky if (Importer.IsStructurallyEquivalent(D->getType(), 3051203955Srdivacky FoundVar->getType())) { 3052203955Srdivacky MergeWithVar = FoundVar; 3053203955Srdivacky break; 3054203955Srdivacky } 3055203955Srdivacky 3056203955Srdivacky const ArrayType *FoundArray 3057203955Srdivacky = Importer.getToContext().getAsArrayType(FoundVar->getType()); 3058203955Srdivacky const ArrayType *TArray 3059203955Srdivacky = Importer.getToContext().getAsArrayType(D->getType()); 3060203955Srdivacky if (FoundArray && TArray) { 3061203955Srdivacky if (isa<IncompleteArrayType>(FoundArray) && 3062203955Srdivacky isa<ConstantArrayType>(TArray)) { 3063203955Srdivacky // Import the type. 3064203955Srdivacky QualType T = Importer.Import(D->getType()); 3065203955Srdivacky if (T.isNull()) 3066203955Srdivacky return 0; 3067203955Srdivacky 3068203955Srdivacky FoundVar->setType(T); 3069203955Srdivacky MergeWithVar = FoundVar; 3070203955Srdivacky break; 3071203955Srdivacky } else if (isa<IncompleteArrayType>(TArray) && 3072203955Srdivacky isa<ConstantArrayType>(FoundArray)) { 3073203955Srdivacky MergeWithVar = FoundVar; 3074203955Srdivacky break; 3075203955Srdivacky } 3076203955Srdivacky } 3077203955Srdivacky 3078203955Srdivacky Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent) 3079203955Srdivacky << Name << D->getType() << FoundVar->getType(); 3080203955Srdivacky Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here) 3081203955Srdivacky << FoundVar->getType(); 3082203955Srdivacky } 3083203955Srdivacky } 3084203955Srdivacky 3085226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 3086203955Srdivacky } 3087203955Srdivacky 3088203955Srdivacky if (MergeWithVar) { 3089203955Srdivacky // An equivalent variable with external linkage has been found. Link 3090203955Srdivacky // the two declarations, then merge them. 3091203955Srdivacky Importer.Imported(D, MergeWithVar); 3092203955Srdivacky 3093203955Srdivacky if (VarDecl *DDef = D->getDefinition()) { 3094203955Srdivacky if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) { 3095203955Srdivacky Importer.ToDiag(ExistingDef->getLocation(), 3096203955Srdivacky diag::err_odr_variable_multiple_def) 3097203955Srdivacky << Name; 3098203955Srdivacky Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here); 3099203955Srdivacky } else { 3100203955Srdivacky Expr *Init = Importer.Import(DDef->getInit()); 3101203955Srdivacky MergeWithVar->setInit(Init); 3102235633Sdim if (DDef->isInitKnownICE()) { 3103235633Sdim EvaluatedStmt *Eval = MergeWithVar->ensureEvaluatedStmt(); 3104235633Sdim Eval->CheckedICE = true; 3105235633Sdim Eval->IsICE = DDef->isInitICE(); 3106235633Sdim } 3107203955Srdivacky } 3108203955Srdivacky } 3109203955Srdivacky 3110203955Srdivacky return MergeWithVar; 3111203955Srdivacky } 3112203955Srdivacky 3113203955Srdivacky if (!ConflictingDecls.empty()) { 3114203955Srdivacky Name = Importer.HandleNameConflict(Name, DC, IDNS, 3115203955Srdivacky ConflictingDecls.data(), 3116203955Srdivacky ConflictingDecls.size()); 3117203955Srdivacky if (!Name) 3118203955Srdivacky return 0; 3119203955Srdivacky } 3120203955Srdivacky } 3121203955Srdivacky 3122203955Srdivacky // Import the type. 3123203955Srdivacky QualType T = Importer.Import(D->getType()); 3124203955Srdivacky if (T.isNull()) 3125203955Srdivacky return 0; 3126203955Srdivacky 3127203955Srdivacky // Create the imported variable. 3128203955Srdivacky TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 3129221345Sdim VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, 3130221345Sdim Importer.Import(D->getInnerLocStart()), 3131221345Sdim Loc, Name.getAsIdentifierInfo(), 3132221345Sdim T, TInfo, 3133252723Sdim D->getStorageClass()); 3134219077Sdim ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc())); 3135204643Srdivacky ToVar->setAccess(D->getAccess()); 3136203955Srdivacky ToVar->setLexicalDeclContext(LexicalDC); 3137203955Srdivacky Importer.Imported(D, ToVar); 3138235633Sdim LexicalDC->addDeclInternal(ToVar); 3139203955Srdivacky 3140203955Srdivacky // Merge the initializer. 3141263509Sdim if (ImportDefinition(D, ToVar)) 3142263509Sdim return 0; 3143203955Srdivacky 3144203955Srdivacky return ToVar; 3145203955Srdivacky} 3146203955Srdivacky 3147204643SrdivackyDecl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) { 3148204643Srdivacky // Parameters are created in the translation unit's context, then moved 3149204643Srdivacky // into the function declaration's context afterward. 3150204643Srdivacky DeclContext *DC = Importer.getToContext().getTranslationUnitDecl(); 3151204643Srdivacky 3152204643Srdivacky // Import the name of this declaration. 3153204643Srdivacky DeclarationName Name = Importer.Import(D->getDeclName()); 3154204643Srdivacky if (D->getDeclName() && !Name) 3155204643Srdivacky return 0; 3156204643Srdivacky 3157204643Srdivacky // Import the location of this declaration. 3158204643Srdivacky SourceLocation Loc = Importer.Import(D->getLocation()); 3159204643Srdivacky 3160204643Srdivacky // Import the parameter's type. 3161204643Srdivacky QualType T = Importer.Import(D->getType()); 3162204643Srdivacky if (T.isNull()) 3163204643Srdivacky return 0; 3164204643Srdivacky 3165204643Srdivacky // Create the imported parameter. 3166204643Srdivacky ImplicitParamDecl *ToParm 3167204643Srdivacky = ImplicitParamDecl::Create(Importer.getToContext(), DC, 3168204643Srdivacky Loc, Name.getAsIdentifierInfo(), 3169204643Srdivacky T); 3170204643Srdivacky return Importer.Imported(D, ToParm); 3171204643Srdivacky} 3172204643Srdivacky 3173203955SrdivackyDecl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) { 3174203955Srdivacky // Parameters are created in the translation unit's context, then moved 3175203955Srdivacky // into the function declaration's context afterward. 3176203955Srdivacky DeclContext *DC = Importer.getToContext().getTranslationUnitDecl(); 3177203955Srdivacky 3178203955Srdivacky // Import the name of this declaration. 3179203955Srdivacky DeclarationName Name = Importer.Import(D->getDeclName()); 3180203955Srdivacky if (D->getDeclName() && !Name) 3181203955Srdivacky return 0; 3182203955Srdivacky 3183203955Srdivacky // Import the location of this declaration. 3184203955Srdivacky SourceLocation Loc = Importer.Import(D->getLocation()); 3185203955Srdivacky 3186203955Srdivacky // Import the parameter's type. 3187203955Srdivacky QualType T = Importer.Import(D->getType()); 3188203955Srdivacky if (T.isNull()) 3189203955Srdivacky return 0; 3190203955Srdivacky 3191203955Srdivacky // Create the imported parameter. 3192203955Srdivacky TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 3193203955Srdivacky ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC, 3194221345Sdim Importer.Import(D->getInnerLocStart()), 3195203955Srdivacky Loc, Name.getAsIdentifierInfo(), 3196203955Srdivacky T, TInfo, D->getStorageClass(), 3197203955Srdivacky /*FIXME: Default argument*/ 0); 3198205219Srdivacky ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg()); 3199203955Srdivacky return Importer.Imported(D, ToParm); 3200203955Srdivacky} 3201203955Srdivacky 3202204643SrdivackyDecl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) { 3203204643Srdivacky // Import the major distinguishing characteristics of a method. 3204204643Srdivacky DeclContext *DC, *LexicalDC; 3205204643Srdivacky DeclarationName Name; 3206204643Srdivacky SourceLocation Loc; 3207204643Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3208204643Srdivacky return 0; 3209204643Srdivacky 3210252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 3211226890Sdim DC->localUncachedLookup(Name, FoundDecls); 3212226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 3213226890Sdim if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecls[I])) { 3214204643Srdivacky if (FoundMethod->isInstanceMethod() != D->isInstanceMethod()) 3215204643Srdivacky continue; 3216204643Srdivacky 3217204643Srdivacky // Check return types. 3218204643Srdivacky if (!Importer.IsStructurallyEquivalent(D->getResultType(), 3219204643Srdivacky FoundMethod->getResultType())) { 3220204643Srdivacky Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent) 3221204643Srdivacky << D->isInstanceMethod() << Name 3222204643Srdivacky << D->getResultType() << FoundMethod->getResultType(); 3223204643Srdivacky Importer.ToDiag(FoundMethod->getLocation(), 3224204643Srdivacky diag::note_odr_objc_method_here) 3225204643Srdivacky << D->isInstanceMethod() << Name; 3226204643Srdivacky return 0; 3227204643Srdivacky } 3228204643Srdivacky 3229204643Srdivacky // Check the number of parameters. 3230204643Srdivacky if (D->param_size() != FoundMethod->param_size()) { 3231204643Srdivacky Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent) 3232204643Srdivacky << D->isInstanceMethod() << Name 3233204643Srdivacky << D->param_size() << FoundMethod->param_size(); 3234204643Srdivacky Importer.ToDiag(FoundMethod->getLocation(), 3235204643Srdivacky diag::note_odr_objc_method_here) 3236204643Srdivacky << D->isInstanceMethod() << Name; 3237204643Srdivacky return 0; 3238204643Srdivacky } 3239204643Srdivacky 3240204643Srdivacky // Check parameter types. 3241204643Srdivacky for (ObjCMethodDecl::param_iterator P = D->param_begin(), 3242204643Srdivacky PEnd = D->param_end(), FoundP = FoundMethod->param_begin(); 3243204643Srdivacky P != PEnd; ++P, ++FoundP) { 3244204643Srdivacky if (!Importer.IsStructurallyEquivalent((*P)->getType(), 3245204643Srdivacky (*FoundP)->getType())) { 3246204643Srdivacky Importer.FromDiag((*P)->getLocation(), 3247204643Srdivacky diag::err_odr_objc_method_param_type_inconsistent) 3248204643Srdivacky << D->isInstanceMethod() << Name 3249204643Srdivacky << (*P)->getType() << (*FoundP)->getType(); 3250204643Srdivacky Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here) 3251204643Srdivacky << (*FoundP)->getType(); 3252204643Srdivacky return 0; 3253204643Srdivacky } 3254204643Srdivacky } 3255204643Srdivacky 3256204643Srdivacky // Check variadic/non-variadic. 3257204643Srdivacky // Check the number of parameters. 3258204643Srdivacky if (D->isVariadic() != FoundMethod->isVariadic()) { 3259204643Srdivacky Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent) 3260204643Srdivacky << D->isInstanceMethod() << Name; 3261204643Srdivacky Importer.ToDiag(FoundMethod->getLocation(), 3262204643Srdivacky diag::note_odr_objc_method_here) 3263204643Srdivacky << D->isInstanceMethod() << Name; 3264204643Srdivacky return 0; 3265204643Srdivacky } 3266204643Srdivacky 3267204643Srdivacky // FIXME: Any other bits we need to merge? 3268204643Srdivacky return Importer.Imported(D, FoundMethod); 3269204643Srdivacky } 3270204643Srdivacky } 3271204643Srdivacky 3272204643Srdivacky // Import the result type. 3273204643Srdivacky QualType ResultTy = Importer.Import(D->getResultType()); 3274204643Srdivacky if (ResultTy.isNull()) 3275204643Srdivacky return 0; 3276204643Srdivacky 3277204962Srdivacky TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo()); 3278204962Srdivacky 3279204643Srdivacky ObjCMethodDecl *ToMethod 3280204643Srdivacky = ObjCMethodDecl::Create(Importer.getToContext(), 3281204643Srdivacky Loc, 3282204643Srdivacky Importer.Import(D->getLocEnd()), 3283204643Srdivacky Name.getObjCSelector(), 3284204962Srdivacky ResultTy, ResultTInfo, DC, 3285204643Srdivacky D->isInstanceMethod(), 3286204643Srdivacky D->isVariadic(), 3287245431Sdim D->isPropertyAccessor(), 3288226890Sdim D->isImplicit(), 3289212904Sdim D->isDefined(), 3290223017Sdim D->getImplementationControl(), 3291223017Sdim D->hasRelatedResultType()); 3292204643Srdivacky 3293204643Srdivacky // FIXME: When we decide to merge method definitions, we'll need to 3294204643Srdivacky // deal with implicit parameters. 3295204643Srdivacky 3296204643Srdivacky // Import the parameters 3297226890Sdim SmallVector<ParmVarDecl *, 5> ToParams; 3298204643Srdivacky for (ObjCMethodDecl::param_iterator FromP = D->param_begin(), 3299204643Srdivacky FromPEnd = D->param_end(); 3300204643Srdivacky FromP != FromPEnd; 3301204643Srdivacky ++FromP) { 3302204643Srdivacky ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP)); 3303204643Srdivacky if (!ToP) 3304204643Srdivacky return 0; 3305204643Srdivacky 3306204643Srdivacky ToParams.push_back(ToP); 3307204643Srdivacky } 3308204643Srdivacky 3309204643Srdivacky // Set the parameters. 3310204643Srdivacky for (unsigned I = 0, N = ToParams.size(); I != N; ++I) { 3311204643Srdivacky ToParams[I]->setOwningFunction(ToMethod); 3312235633Sdim ToMethod->addDeclInternal(ToParams[I]); 3313204643Srdivacky } 3314226890Sdim SmallVector<SourceLocation, 12> SelLocs; 3315226890Sdim D->getSelectorLocs(SelLocs); 3316226890Sdim ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs); 3317204643Srdivacky 3318204643Srdivacky ToMethod->setLexicalDeclContext(LexicalDC); 3319204643Srdivacky Importer.Imported(D, ToMethod); 3320235633Sdim LexicalDC->addDeclInternal(ToMethod); 3321204643Srdivacky return ToMethod; 3322204643Srdivacky} 3323204643Srdivacky 3324204643SrdivackyDecl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { 3325204643Srdivacky // Import the major distinguishing characteristics of a category. 3326204643Srdivacky DeclContext *DC, *LexicalDC; 3327204643Srdivacky DeclarationName Name; 3328204643Srdivacky SourceLocation Loc; 3329204643Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3330204643Srdivacky return 0; 3331204643Srdivacky 3332204643Srdivacky ObjCInterfaceDecl *ToInterface 3333204643Srdivacky = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface())); 3334204643Srdivacky if (!ToInterface) 3335204643Srdivacky return 0; 3336204643Srdivacky 3337204643Srdivacky // Determine if we've already encountered this category. 3338204643Srdivacky ObjCCategoryDecl *MergeWithCategory 3339204643Srdivacky = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo()); 3340204643Srdivacky ObjCCategoryDecl *ToCategory = MergeWithCategory; 3341204643Srdivacky if (!ToCategory) { 3342204643Srdivacky ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC, 3343226890Sdim Importer.Import(D->getAtStartLoc()), 3344204643Srdivacky Loc, 3345204643Srdivacky Importer.Import(D->getCategoryNameLoc()), 3346226890Sdim Name.getAsIdentifierInfo(), 3347235633Sdim ToInterface, 3348235633Sdim Importer.Import(D->getIvarLBraceLoc()), 3349235633Sdim Importer.Import(D->getIvarRBraceLoc())); 3350204643Srdivacky ToCategory->setLexicalDeclContext(LexicalDC); 3351235633Sdim LexicalDC->addDeclInternal(ToCategory); 3352204643Srdivacky Importer.Imported(D, ToCategory); 3353204643Srdivacky 3354204643Srdivacky // Import protocols 3355226890Sdim SmallVector<ObjCProtocolDecl *, 4> Protocols; 3356226890Sdim SmallVector<SourceLocation, 4> ProtocolLocs; 3357204643Srdivacky ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc 3358204643Srdivacky = D->protocol_loc_begin(); 3359204643Srdivacky for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(), 3360204643Srdivacky FromProtoEnd = D->protocol_end(); 3361204643Srdivacky FromProto != FromProtoEnd; 3362204643Srdivacky ++FromProto, ++FromProtoLoc) { 3363204643Srdivacky ObjCProtocolDecl *ToProto 3364204643Srdivacky = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto)); 3365204643Srdivacky if (!ToProto) 3366204643Srdivacky return 0; 3367204643Srdivacky Protocols.push_back(ToProto); 3368204643Srdivacky ProtocolLocs.push_back(Importer.Import(*FromProtoLoc)); 3369204643Srdivacky } 3370204643Srdivacky 3371204643Srdivacky // FIXME: If we're merging, make sure that the protocol list is the same. 3372204643Srdivacky ToCategory->setProtocolList(Protocols.data(), Protocols.size(), 3373204643Srdivacky ProtocolLocs.data(), Importer.getToContext()); 3374204643Srdivacky 3375204643Srdivacky } else { 3376204643Srdivacky Importer.Imported(D, ToCategory); 3377204643Srdivacky } 3378204643Srdivacky 3379204643Srdivacky // Import all of the members of this category. 3380204643Srdivacky ImportDeclContext(D); 3381204643Srdivacky 3382204643Srdivacky // If we have an implementation, import it as well. 3383204643Srdivacky if (D->getImplementation()) { 3384204643Srdivacky ObjCCategoryImplDecl *Impl 3385218893Sdim = cast_or_null<ObjCCategoryImplDecl>( 3386218893Sdim Importer.Import(D->getImplementation())); 3387204643Srdivacky if (!Impl) 3388204643Srdivacky return 0; 3389204643Srdivacky 3390204643Srdivacky ToCategory->setImplementation(Impl); 3391204643Srdivacky } 3392204643Srdivacky 3393204643Srdivacky return ToCategory; 3394204643Srdivacky} 3395204643Srdivacky 3396235633Sdimbool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From, 3397235633Sdim ObjCProtocolDecl *To, 3398235633Sdim ImportDefinitionKind Kind) { 3399235633Sdim if (To->getDefinition()) { 3400235633Sdim if (shouldForceImportDeclContext(Kind)) 3401235633Sdim ImportDeclContext(From); 3402235633Sdim return false; 3403235633Sdim } 3404235633Sdim 3405235633Sdim // Start the protocol definition 3406235633Sdim To->startDefinition(); 3407235633Sdim 3408235633Sdim // Import protocols 3409235633Sdim SmallVector<ObjCProtocolDecl *, 4> Protocols; 3410235633Sdim SmallVector<SourceLocation, 4> ProtocolLocs; 3411235633Sdim ObjCProtocolDecl::protocol_loc_iterator 3412235633Sdim FromProtoLoc = From->protocol_loc_begin(); 3413235633Sdim for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(), 3414235633Sdim FromProtoEnd = From->protocol_end(); 3415235633Sdim FromProto != FromProtoEnd; 3416235633Sdim ++FromProto, ++FromProtoLoc) { 3417235633Sdim ObjCProtocolDecl *ToProto 3418235633Sdim = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto)); 3419235633Sdim if (!ToProto) 3420235633Sdim return true; 3421235633Sdim Protocols.push_back(ToProto); 3422235633Sdim ProtocolLocs.push_back(Importer.Import(*FromProtoLoc)); 3423235633Sdim } 3424235633Sdim 3425235633Sdim // FIXME: If we're merging, make sure that the protocol list is the same. 3426235633Sdim To->setProtocolList(Protocols.data(), Protocols.size(), 3427235633Sdim ProtocolLocs.data(), Importer.getToContext()); 3428235633Sdim 3429235633Sdim if (shouldForceImportDeclContext(Kind)) { 3430235633Sdim // Import all of the members of this protocol. 3431235633Sdim ImportDeclContext(From, /*ForceImport=*/true); 3432235633Sdim } 3433235633Sdim return false; 3434235633Sdim} 3435235633Sdim 3436204643SrdivackyDecl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { 3437235633Sdim // If this protocol has a definition in the translation unit we're coming 3438235633Sdim // from, but this particular declaration is not that definition, import the 3439235633Sdim // definition and map to that. 3440235633Sdim ObjCProtocolDecl *Definition = D->getDefinition(); 3441235633Sdim if (Definition && Definition != D) { 3442235633Sdim Decl *ImportedDef = Importer.Import(Definition); 3443235633Sdim if (!ImportedDef) 3444235633Sdim return 0; 3445235633Sdim 3446235633Sdim return Importer.Imported(D, ImportedDef); 3447235633Sdim } 3448235633Sdim 3449204643Srdivacky // Import the major distinguishing characteristics of a protocol. 3450204643Srdivacky DeclContext *DC, *LexicalDC; 3451204643Srdivacky DeclarationName Name; 3452204643Srdivacky SourceLocation Loc; 3453204643Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3454204643Srdivacky return 0; 3455204643Srdivacky 3456204643Srdivacky ObjCProtocolDecl *MergeWithProtocol = 0; 3457252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 3458226890Sdim DC->localUncachedLookup(Name, FoundDecls); 3459226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 3460226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol)) 3461204643Srdivacky continue; 3462204643Srdivacky 3463226890Sdim if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecls[I]))) 3464204643Srdivacky break; 3465204643Srdivacky } 3466204643Srdivacky 3467204643Srdivacky ObjCProtocolDecl *ToProto = MergeWithProtocol; 3468235633Sdim if (!ToProto) { 3469235633Sdim ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, 3470235633Sdim Name.getAsIdentifierInfo(), Loc, 3471235633Sdim Importer.Import(D->getAtStartLoc()), 3472235633Sdim /*PrevDecl=*/0); 3473235633Sdim ToProto->setLexicalDeclContext(LexicalDC); 3474235633Sdim LexicalDC->addDeclInternal(ToProto); 3475235633Sdim } 3476235633Sdim 3477235633Sdim Importer.Imported(D, ToProto); 3478235633Sdim 3479235633Sdim if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto)) 3480235633Sdim return 0; 3481235633Sdim 3482235633Sdim return ToProto; 3483235633Sdim} 3484235633Sdim 3485235633Sdimbool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From, 3486235633Sdim ObjCInterfaceDecl *To, 3487235633Sdim ImportDefinitionKind Kind) { 3488235633Sdim if (To->getDefinition()) { 3489235633Sdim // Check consistency of superclass. 3490235633Sdim ObjCInterfaceDecl *FromSuper = From->getSuperClass(); 3491235633Sdim if (FromSuper) { 3492235633Sdim FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper)); 3493235633Sdim if (!FromSuper) 3494235633Sdim return true; 3495204643Srdivacky } 3496235633Sdim 3497235633Sdim ObjCInterfaceDecl *ToSuper = To->getSuperClass(); 3498235633Sdim if ((bool)FromSuper != (bool)ToSuper || 3499235633Sdim (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) { 3500235633Sdim Importer.ToDiag(To->getLocation(), 3501235633Sdim diag::err_odr_objc_superclass_inconsistent) 3502235633Sdim << To->getDeclName(); 3503235633Sdim if (ToSuper) 3504235633Sdim Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass) 3505235633Sdim << To->getSuperClass()->getDeclName(); 3506235633Sdim else 3507235633Sdim Importer.ToDiag(To->getLocation(), 3508235633Sdim diag::note_odr_objc_missing_superclass); 3509235633Sdim if (From->getSuperClass()) 3510235633Sdim Importer.FromDiag(From->getSuperClassLoc(), 3511235633Sdim diag::note_odr_objc_superclass) 3512235633Sdim << From->getSuperClass()->getDeclName(); 3513235633Sdim else 3514235633Sdim Importer.FromDiag(From->getLocation(), 3515235633Sdim diag::note_odr_objc_missing_superclass); 3516235633Sdim } 3517235633Sdim 3518235633Sdim if (shouldForceImportDeclContext(Kind)) 3519235633Sdim ImportDeclContext(From); 3520235633Sdim return false; 3521235633Sdim } 3522235633Sdim 3523235633Sdim // Start the definition. 3524235633Sdim To->startDefinition(); 3525235633Sdim 3526235633Sdim // If this class has a superclass, import it. 3527235633Sdim if (From->getSuperClass()) { 3528235633Sdim ObjCInterfaceDecl *Super = cast_or_null<ObjCInterfaceDecl>( 3529235633Sdim Importer.Import(From->getSuperClass())); 3530235633Sdim if (!Super) 3531235633Sdim return true; 3532235633Sdim 3533235633Sdim To->setSuperClass(Super); 3534235633Sdim To->setSuperClassLoc(Importer.Import(From->getSuperClassLoc())); 3535235633Sdim } 3536235633Sdim 3537235633Sdim // Import protocols 3538235633Sdim SmallVector<ObjCProtocolDecl *, 4> Protocols; 3539235633Sdim SmallVector<SourceLocation, 4> ProtocolLocs; 3540235633Sdim ObjCInterfaceDecl::protocol_loc_iterator 3541235633Sdim FromProtoLoc = From->protocol_loc_begin(); 3542235633Sdim 3543235633Sdim for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(), 3544235633Sdim FromProtoEnd = From->protocol_end(); 3545204643Srdivacky FromProto != FromProtoEnd; 3546204643Srdivacky ++FromProto, ++FromProtoLoc) { 3547235633Sdim ObjCProtocolDecl *ToProto 3548235633Sdim = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto)); 3549235633Sdim if (!ToProto) 3550235633Sdim return true; 3551235633Sdim Protocols.push_back(ToProto); 3552235633Sdim ProtocolLocs.push_back(Importer.Import(*FromProtoLoc)); 3553235633Sdim } 3554235633Sdim 3555235633Sdim // FIXME: If we're merging, make sure that the protocol list is the same. 3556235633Sdim To->setProtocolList(Protocols.data(), Protocols.size(), 3557235633Sdim ProtocolLocs.data(), Importer.getToContext()); 3558235633Sdim 3559235633Sdim // Import categories. When the categories themselves are imported, they'll 3560235633Sdim // hook themselves into this interface. 3561252723Sdim for (ObjCInterfaceDecl::known_categories_iterator 3562252723Sdim Cat = From->known_categories_begin(), 3563252723Sdim CatEnd = From->known_categories_end(); 3564252723Sdim Cat != CatEnd; ++Cat) { 3565252723Sdim Importer.Import(*Cat); 3566252723Sdim } 3567252723Sdim 3568235633Sdim // If we have an @implementation, import it as well. 3569235633Sdim if (From->getImplementation()) { 3570235633Sdim ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>( 3571235633Sdim Importer.Import(From->getImplementation())); 3572235633Sdim if (!Impl) 3573235633Sdim return true; 3574204643Srdivacky 3575235633Sdim To->setImplementation(Impl); 3576204643Srdivacky } 3577204643Srdivacky 3578235633Sdim if (shouldForceImportDeclContext(Kind)) { 3579235633Sdim // Import all of the members of this class. 3580235633Sdim ImportDeclContext(From, /*ForceImport=*/true); 3581235633Sdim } 3582235633Sdim return false; 3583204643Srdivacky} 3584204643Srdivacky 3585203955SrdivackyDecl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 3586235633Sdim // If this class has a definition in the translation unit we're coming from, 3587235633Sdim // but this particular declaration is not that definition, import the 3588235633Sdim // definition and map to that. 3589235633Sdim ObjCInterfaceDecl *Definition = D->getDefinition(); 3590235633Sdim if (Definition && Definition != D) { 3591235633Sdim Decl *ImportedDef = Importer.Import(Definition); 3592235633Sdim if (!ImportedDef) 3593235633Sdim return 0; 3594235633Sdim 3595235633Sdim return Importer.Imported(D, ImportedDef); 3596235633Sdim } 3597235633Sdim 3598203955Srdivacky // Import the major distinguishing characteristics of an @interface. 3599203955Srdivacky DeclContext *DC, *LexicalDC; 3600203955Srdivacky DeclarationName Name; 3601203955Srdivacky SourceLocation Loc; 3602203955Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3603203955Srdivacky return 0; 3604203955Srdivacky 3605235633Sdim // Look for an existing interface with the same name. 3606203955Srdivacky ObjCInterfaceDecl *MergeWithIface = 0; 3607252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 3608226890Sdim DC->localUncachedLookup(Name, FoundDecls); 3609226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 3610226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary)) 3611203955Srdivacky continue; 3612203955Srdivacky 3613226890Sdim if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecls[I]))) 3614203955Srdivacky break; 3615203955Srdivacky } 3616203955Srdivacky 3617235633Sdim // Create an interface declaration, if one does not already exist. 3618203955Srdivacky ObjCInterfaceDecl *ToIface = MergeWithIface; 3619235633Sdim if (!ToIface) { 3620235633Sdim ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC, 3621235633Sdim Importer.Import(D->getAtStartLoc()), 3622235633Sdim Name.getAsIdentifierInfo(), 3623235633Sdim /*PrevDecl=*/0,Loc, 3624235633Sdim D->isImplicitInterfaceDecl()); 3625235633Sdim ToIface->setLexicalDeclContext(LexicalDC); 3626235633Sdim LexicalDC->addDeclInternal(ToIface); 3627203955Srdivacky } 3628235633Sdim Importer.Imported(D, ToIface); 3629203955Srdivacky 3630235633Sdim if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface)) 3631235633Sdim return 0; 3632203955Srdivacky 3633204643Srdivacky return ToIface; 3634203955Srdivacky} 3635203955Srdivacky 3636218893SdimDecl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 3637218893Sdim ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>( 3638218893Sdim Importer.Import(D->getCategoryDecl())); 3639218893Sdim if (!Category) 3640218893Sdim return 0; 3641218893Sdim 3642218893Sdim ObjCCategoryImplDecl *ToImpl = Category->getImplementation(); 3643218893Sdim if (!ToImpl) { 3644218893Sdim DeclContext *DC = Importer.ImportContext(D->getDeclContext()); 3645218893Sdim if (!DC) 3646218893Sdim return 0; 3647218893Sdim 3648235633Sdim SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc()); 3649218893Sdim ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC, 3650226890Sdim Importer.Import(D->getIdentifier()), 3651226890Sdim Category->getClassInterface(), 3652218893Sdim Importer.Import(D->getLocation()), 3653235633Sdim Importer.Import(D->getAtStartLoc()), 3654235633Sdim CategoryNameLoc); 3655218893Sdim 3656218893Sdim DeclContext *LexicalDC = DC; 3657218893Sdim if (D->getDeclContext() != D->getLexicalDeclContext()) { 3658218893Sdim LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); 3659218893Sdim if (!LexicalDC) 3660218893Sdim return 0; 3661218893Sdim 3662218893Sdim ToImpl->setLexicalDeclContext(LexicalDC); 3663218893Sdim } 3664218893Sdim 3665235633Sdim LexicalDC->addDeclInternal(ToImpl); 3666218893Sdim Category->setImplementation(ToImpl); 3667218893Sdim } 3668218893Sdim 3669218893Sdim Importer.Imported(D, ToImpl); 3670218893Sdim ImportDeclContext(D); 3671218893Sdim return ToImpl; 3672218893Sdim} 3673218893Sdim 3674218893SdimDecl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 3675218893Sdim // Find the corresponding interface. 3676218893Sdim ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>( 3677218893Sdim Importer.Import(D->getClassInterface())); 3678218893Sdim if (!Iface) 3679218893Sdim return 0; 3680218893Sdim 3681218893Sdim // Import the superclass, if any. 3682218893Sdim ObjCInterfaceDecl *Super = 0; 3683218893Sdim if (D->getSuperClass()) { 3684218893Sdim Super = cast_or_null<ObjCInterfaceDecl>( 3685218893Sdim Importer.Import(D->getSuperClass())); 3686218893Sdim if (!Super) 3687218893Sdim return 0; 3688218893Sdim } 3689218893Sdim 3690218893Sdim ObjCImplementationDecl *Impl = Iface->getImplementation(); 3691218893Sdim if (!Impl) { 3692218893Sdim // We haven't imported an implementation yet. Create a new @implementation 3693218893Sdim // now. 3694218893Sdim Impl = ObjCImplementationDecl::Create(Importer.getToContext(), 3695218893Sdim Importer.ImportContext(D->getDeclContext()), 3696226890Sdim Iface, Super, 3697218893Sdim Importer.Import(D->getLocation()), 3698235633Sdim Importer.Import(D->getAtStartLoc()), 3699252723Sdim Importer.Import(D->getSuperClassLoc()), 3700235633Sdim Importer.Import(D->getIvarLBraceLoc()), 3701235633Sdim Importer.Import(D->getIvarRBraceLoc())); 3702218893Sdim 3703218893Sdim if (D->getDeclContext() != D->getLexicalDeclContext()) { 3704218893Sdim DeclContext *LexicalDC 3705218893Sdim = Importer.ImportContext(D->getLexicalDeclContext()); 3706218893Sdim if (!LexicalDC) 3707218893Sdim return 0; 3708218893Sdim Impl->setLexicalDeclContext(LexicalDC); 3709218893Sdim } 3710218893Sdim 3711218893Sdim // Associate the implementation with the class it implements. 3712218893Sdim Iface->setImplementation(Impl); 3713218893Sdim Importer.Imported(D, Iface->getImplementation()); 3714218893Sdim } else { 3715218893Sdim Importer.Imported(D, Iface->getImplementation()); 3716218893Sdim 3717218893Sdim // Verify that the existing @implementation has the same superclass. 3718218893Sdim if ((Super && !Impl->getSuperClass()) || 3719218893Sdim (!Super && Impl->getSuperClass()) || 3720218893Sdim (Super && Impl->getSuperClass() && 3721235633Sdim !declaresSameEntity(Super->getCanonicalDecl(), Impl->getSuperClass()))) { 3722218893Sdim Importer.ToDiag(Impl->getLocation(), 3723218893Sdim diag::err_odr_objc_superclass_inconsistent) 3724218893Sdim << Iface->getDeclName(); 3725218893Sdim // FIXME: It would be nice to have the location of the superclass 3726218893Sdim // below. 3727218893Sdim if (Impl->getSuperClass()) 3728218893Sdim Importer.ToDiag(Impl->getLocation(), 3729218893Sdim diag::note_odr_objc_superclass) 3730218893Sdim << Impl->getSuperClass()->getDeclName(); 3731218893Sdim else 3732218893Sdim Importer.ToDiag(Impl->getLocation(), 3733218893Sdim diag::note_odr_objc_missing_superclass); 3734218893Sdim if (D->getSuperClass()) 3735218893Sdim Importer.FromDiag(D->getLocation(), 3736218893Sdim diag::note_odr_objc_superclass) 3737218893Sdim << D->getSuperClass()->getDeclName(); 3738218893Sdim else 3739218893Sdim Importer.FromDiag(D->getLocation(), 3740218893Sdim diag::note_odr_objc_missing_superclass); 3741218893Sdim return 0; 3742218893Sdim } 3743218893Sdim } 3744218893Sdim 3745218893Sdim // Import all of the members of this @implementation. 3746218893Sdim ImportDeclContext(D); 3747218893Sdim 3748218893Sdim return Impl; 3749218893Sdim} 3750218893Sdim 3751204643SrdivackyDecl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { 3752204643Srdivacky // Import the major distinguishing characteristics of an @property. 3753204643Srdivacky DeclContext *DC, *LexicalDC; 3754204643Srdivacky DeclarationName Name; 3755204643Srdivacky SourceLocation Loc; 3756204643Srdivacky if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3757204643Srdivacky return 0; 3758204643Srdivacky 3759204643Srdivacky // Check whether we have already imported this property. 3760252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 3761226890Sdim DC->localUncachedLookup(Name, FoundDecls); 3762226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 3763204643Srdivacky if (ObjCPropertyDecl *FoundProp 3764226890Sdim = dyn_cast<ObjCPropertyDecl>(FoundDecls[I])) { 3765204643Srdivacky // Check property types. 3766204643Srdivacky if (!Importer.IsStructurallyEquivalent(D->getType(), 3767204643Srdivacky FoundProp->getType())) { 3768204643Srdivacky Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent) 3769204643Srdivacky << Name << D->getType() << FoundProp->getType(); 3770204643Srdivacky Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here) 3771204643Srdivacky << FoundProp->getType(); 3772204643Srdivacky return 0; 3773204643Srdivacky } 3774204643Srdivacky 3775204643Srdivacky // FIXME: Check property attributes, getters, setters, etc.? 3776204643Srdivacky 3777204643Srdivacky // Consider these properties to be equivalent. 3778204643Srdivacky Importer.Imported(D, FoundProp); 3779204643Srdivacky return FoundProp; 3780204643Srdivacky } 3781204643Srdivacky } 3782204643Srdivacky 3783204643Srdivacky // Import the type. 3784210299Sed TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo()); 3785210299Sed if (!T) 3786204643Srdivacky return 0; 3787204643Srdivacky 3788204643Srdivacky // Create the new property. 3789204643Srdivacky ObjCPropertyDecl *ToProperty 3790204643Srdivacky = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc, 3791204643Srdivacky Name.getAsIdentifierInfo(), 3792204643Srdivacky Importer.Import(D->getAtLoc()), 3793235633Sdim Importer.Import(D->getLParenLoc()), 3794204643Srdivacky T, 3795204643Srdivacky D->getPropertyImplementation()); 3796204643Srdivacky Importer.Imported(D, ToProperty); 3797204643Srdivacky ToProperty->setLexicalDeclContext(LexicalDC); 3798235633Sdim LexicalDC->addDeclInternal(ToProperty); 3799204643Srdivacky 3800204643Srdivacky ToProperty->setPropertyAttributes(D->getPropertyAttributes()); 3801210299Sed ToProperty->setPropertyAttributesAsWritten( 3802210299Sed D->getPropertyAttributesAsWritten()); 3803204643Srdivacky ToProperty->setGetterName(Importer.Import(D->getGetterName())); 3804204643Srdivacky ToProperty->setSetterName(Importer.Import(D->getSetterName())); 3805204643Srdivacky ToProperty->setGetterMethodDecl( 3806204643Srdivacky cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl()))); 3807204643Srdivacky ToProperty->setSetterMethodDecl( 3808204643Srdivacky cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl()))); 3809204643Srdivacky ToProperty->setPropertyIvarDecl( 3810204643Srdivacky cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl()))); 3811204643Srdivacky return ToProperty; 3812204643Srdivacky} 3813204643Srdivacky 3814218893SdimDecl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { 3815218893Sdim ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>( 3816218893Sdim Importer.Import(D->getPropertyDecl())); 3817218893Sdim if (!Property) 3818218893Sdim return 0; 3819218893Sdim 3820218893Sdim DeclContext *DC = Importer.ImportContext(D->getDeclContext()); 3821218893Sdim if (!DC) 3822218893Sdim return 0; 3823218893Sdim 3824218893Sdim // Import the lexical declaration context. 3825218893Sdim DeclContext *LexicalDC = DC; 3826218893Sdim if (D->getDeclContext() != D->getLexicalDeclContext()) { 3827218893Sdim LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); 3828218893Sdim if (!LexicalDC) 3829218893Sdim return 0; 3830218893Sdim } 3831218893Sdim 3832218893Sdim ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC); 3833218893Sdim if (!InImpl) 3834218893Sdim return 0; 3835218893Sdim 3836218893Sdim // Import the ivar (for an @synthesize). 3837218893Sdim ObjCIvarDecl *Ivar = 0; 3838218893Sdim if (D->getPropertyIvarDecl()) { 3839218893Sdim Ivar = cast_or_null<ObjCIvarDecl>( 3840218893Sdim Importer.Import(D->getPropertyIvarDecl())); 3841218893Sdim if (!Ivar) 3842218893Sdim return 0; 3843218893Sdim } 3844218893Sdim 3845218893Sdim ObjCPropertyImplDecl *ToImpl 3846218893Sdim = InImpl->FindPropertyImplDecl(Property->getIdentifier()); 3847218893Sdim if (!ToImpl) { 3848218893Sdim ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC, 3849218893Sdim Importer.Import(D->getLocStart()), 3850218893Sdim Importer.Import(D->getLocation()), 3851218893Sdim Property, 3852218893Sdim D->getPropertyImplementation(), 3853218893Sdim Ivar, 3854218893Sdim Importer.Import(D->getPropertyIvarDeclLoc())); 3855218893Sdim ToImpl->setLexicalDeclContext(LexicalDC); 3856218893Sdim Importer.Imported(D, ToImpl); 3857235633Sdim LexicalDC->addDeclInternal(ToImpl); 3858218893Sdim } else { 3859218893Sdim // Check that we have the same kind of property implementation (@synthesize 3860218893Sdim // vs. @dynamic). 3861218893Sdim if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) { 3862218893Sdim Importer.ToDiag(ToImpl->getLocation(), 3863218893Sdim diag::err_odr_objc_property_impl_kind_inconsistent) 3864218893Sdim << Property->getDeclName() 3865218893Sdim << (ToImpl->getPropertyImplementation() 3866218893Sdim == ObjCPropertyImplDecl::Dynamic); 3867218893Sdim Importer.FromDiag(D->getLocation(), 3868218893Sdim diag::note_odr_objc_property_impl_kind) 3869218893Sdim << D->getPropertyDecl()->getDeclName() 3870218893Sdim << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic); 3871218893Sdim return 0; 3872218893Sdim } 3873218893Sdim 3874218893Sdim // For @synthesize, check that we have the same 3875218893Sdim if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize && 3876218893Sdim Ivar != ToImpl->getPropertyIvarDecl()) { 3877218893Sdim Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(), 3878218893Sdim diag::err_odr_objc_synthesize_ivar_inconsistent) 3879218893Sdim << Property->getDeclName() 3880218893Sdim << ToImpl->getPropertyIvarDecl()->getDeclName() 3881218893Sdim << Ivar->getDeclName(); 3882218893Sdim Importer.FromDiag(D->getPropertyIvarDeclLoc(), 3883218893Sdim diag::note_odr_objc_synthesize_ivar_here) 3884218893Sdim << D->getPropertyIvarDecl()->getDeclName(); 3885218893Sdim return 0; 3886218893Sdim } 3887218893Sdim 3888218893Sdim // Merge the existing implementation with the new implementation. 3889218893Sdim Importer.Imported(D, ToImpl); 3890218893Sdim } 3891218893Sdim 3892218893Sdim return ToImpl; 3893218893Sdim} 3894218893Sdim 3895218893SdimDecl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { 3896218893Sdim // For template arguments, we adopt the translation unit as our declaration 3897218893Sdim // context. This context will be fixed when the actual template declaration 3898218893Sdim // is created. 3899218893Sdim 3900218893Sdim // FIXME: Import default argument. 3901218893Sdim return TemplateTypeParmDecl::Create(Importer.getToContext(), 3902218893Sdim Importer.getToContext().getTranslationUnitDecl(), 3903221345Sdim Importer.Import(D->getLocStart()), 3904218893Sdim Importer.Import(D->getLocation()), 3905218893Sdim D->getDepth(), 3906218893Sdim D->getIndex(), 3907218893Sdim Importer.Import(D->getIdentifier()), 3908218893Sdim D->wasDeclaredWithTypename(), 3909218893Sdim D->isParameterPack()); 3910218893Sdim} 3911218893Sdim 3912218893SdimDecl * 3913218893SdimASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { 3914218893Sdim // Import the name of this declaration. 3915218893Sdim DeclarationName Name = Importer.Import(D->getDeclName()); 3916218893Sdim if (D->getDeclName() && !Name) 3917218893Sdim return 0; 3918218893Sdim 3919218893Sdim // Import the location of this declaration. 3920218893Sdim SourceLocation Loc = Importer.Import(D->getLocation()); 3921218893Sdim 3922218893Sdim // Import the type of this declaration. 3923218893Sdim QualType T = Importer.Import(D->getType()); 3924218893Sdim if (T.isNull()) 3925218893Sdim return 0; 3926218893Sdim 3927218893Sdim // Import type-source information. 3928218893Sdim TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 3929218893Sdim if (D->getTypeSourceInfo() && !TInfo) 3930218893Sdim return 0; 3931218893Sdim 3932218893Sdim // FIXME: Import default argument. 3933218893Sdim 3934218893Sdim return NonTypeTemplateParmDecl::Create(Importer.getToContext(), 3935218893Sdim Importer.getToContext().getTranslationUnitDecl(), 3936221345Sdim Importer.Import(D->getInnerLocStart()), 3937218893Sdim Loc, D->getDepth(), D->getPosition(), 3938218893Sdim Name.getAsIdentifierInfo(), 3939218893Sdim T, D->isParameterPack(), TInfo); 3940218893Sdim} 3941218893Sdim 3942218893SdimDecl * 3943218893SdimASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { 3944218893Sdim // Import the name of this declaration. 3945218893Sdim DeclarationName Name = Importer.Import(D->getDeclName()); 3946218893Sdim if (D->getDeclName() && !Name) 3947218893Sdim return 0; 3948218893Sdim 3949218893Sdim // Import the location of this declaration. 3950218893Sdim SourceLocation Loc = Importer.Import(D->getLocation()); 3951218893Sdim 3952218893Sdim // Import template parameters. 3953218893Sdim TemplateParameterList *TemplateParams 3954218893Sdim = ImportTemplateParameterList(D->getTemplateParameters()); 3955218893Sdim if (!TemplateParams) 3956218893Sdim return 0; 3957218893Sdim 3958218893Sdim // FIXME: Import default argument. 3959218893Sdim 3960218893Sdim return TemplateTemplateParmDecl::Create(Importer.getToContext(), 3961218893Sdim Importer.getToContext().getTranslationUnitDecl(), 3962218893Sdim Loc, D->getDepth(), D->getPosition(), 3963218893Sdim D->isParameterPack(), 3964218893Sdim Name.getAsIdentifierInfo(), 3965218893Sdim TemplateParams); 3966218893Sdim} 3967218893Sdim 3968218893SdimDecl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { 3969218893Sdim // If this record has a definition in the translation unit we're coming from, 3970218893Sdim // but this particular declaration is not that definition, import the 3971218893Sdim // definition and map to that. 3972218893Sdim CXXRecordDecl *Definition 3973218893Sdim = cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition()); 3974218893Sdim if (Definition && Definition != D->getTemplatedDecl()) { 3975218893Sdim Decl *ImportedDef 3976218893Sdim = Importer.Import(Definition->getDescribedClassTemplate()); 3977218893Sdim if (!ImportedDef) 3978218893Sdim return 0; 3979218893Sdim 3980218893Sdim return Importer.Imported(D, ImportedDef); 3981218893Sdim } 3982218893Sdim 3983218893Sdim // Import the major distinguishing characteristics of this class template. 3984218893Sdim DeclContext *DC, *LexicalDC; 3985218893Sdim DeclarationName Name; 3986218893Sdim SourceLocation Loc; 3987218893Sdim if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 3988218893Sdim return 0; 3989218893Sdim 3990218893Sdim // We may already have a template of the same name; try to find and match it. 3991218893Sdim if (!DC->isFunctionOrMethod()) { 3992226890Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 3993252723Sdim SmallVector<NamedDecl *, 2> FoundDecls; 3994226890Sdim DC->localUncachedLookup(Name, FoundDecls); 3995226890Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 3996226890Sdim if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary)) 3997218893Sdim continue; 3998218893Sdim 3999226890Sdim Decl *Found = FoundDecls[I]; 4000218893Sdim if (ClassTemplateDecl *FoundTemplate 4001218893Sdim = dyn_cast<ClassTemplateDecl>(Found)) { 4002218893Sdim if (IsStructuralMatch(D, FoundTemplate)) { 4003218893Sdim // The class templates structurally match; call it the same template. 4004218893Sdim // FIXME: We may be filling in a forward declaration here. Handle 4005218893Sdim // this case! 4006218893Sdim Importer.Imported(D->getTemplatedDecl(), 4007218893Sdim FoundTemplate->getTemplatedDecl()); 4008218893Sdim return Importer.Imported(D, FoundTemplate); 4009218893Sdim } 4010218893Sdim } 4011218893Sdim 4012226890Sdim ConflictingDecls.push_back(FoundDecls[I]); 4013218893Sdim } 4014218893Sdim 4015218893Sdim if (!ConflictingDecls.empty()) { 4016218893Sdim Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary, 4017218893Sdim ConflictingDecls.data(), 4018218893Sdim ConflictingDecls.size()); 4019218893Sdim } 4020218893Sdim 4021218893Sdim if (!Name) 4022218893Sdim return 0; 4023218893Sdim } 4024218893Sdim 4025218893Sdim CXXRecordDecl *DTemplated = D->getTemplatedDecl(); 4026218893Sdim 4027218893Sdim // Create the declaration that is being templated. 4028221345Sdim SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart()); 4029221345Sdim SourceLocation IdLoc = Importer.Import(DTemplated->getLocation()); 4030218893Sdim CXXRecordDecl *D2Templated = CXXRecordDecl::Create(Importer.getToContext(), 4031218893Sdim DTemplated->getTagKind(), 4032221345Sdim DC, StartLoc, IdLoc, 4033221345Sdim Name.getAsIdentifierInfo()); 4034218893Sdim D2Templated->setAccess(DTemplated->getAccess()); 4035219077Sdim D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc())); 4036218893Sdim D2Templated->setLexicalDeclContext(LexicalDC); 4037218893Sdim 4038218893Sdim // Create the class template declaration itself. 4039218893Sdim TemplateParameterList *TemplateParams 4040218893Sdim = ImportTemplateParameterList(D->getTemplateParameters()); 4041218893Sdim if (!TemplateParams) 4042218893Sdim return 0; 4043218893Sdim 4044218893Sdim ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC, 4045218893Sdim Loc, Name, TemplateParams, 4046218893Sdim D2Templated, 4047218893Sdim /*PrevDecl=*/0); 4048218893Sdim D2Templated->setDescribedClassTemplate(D2); 4049218893Sdim 4050218893Sdim D2->setAccess(D->getAccess()); 4051218893Sdim D2->setLexicalDeclContext(LexicalDC); 4052235633Sdim LexicalDC->addDeclInternal(D2); 4053218893Sdim 4054218893Sdim // Note the relationship between the class templates. 4055218893Sdim Importer.Imported(D, D2); 4056218893Sdim Importer.Imported(DTemplated, D2Templated); 4057218893Sdim 4058226890Sdim if (DTemplated->isCompleteDefinition() && 4059226890Sdim !D2Templated->isCompleteDefinition()) { 4060218893Sdim // FIXME: Import definition! 4061218893Sdim } 4062218893Sdim 4063218893Sdim return D2; 4064218893Sdim} 4065218893Sdim 4066218893SdimDecl *ASTNodeImporter::VisitClassTemplateSpecializationDecl( 4067218893Sdim ClassTemplateSpecializationDecl *D) { 4068218893Sdim // If this record has a definition in the translation unit we're coming from, 4069218893Sdim // but this particular declaration is not that definition, import the 4070218893Sdim // definition and map to that. 4071218893Sdim TagDecl *Definition = D->getDefinition(); 4072218893Sdim if (Definition && Definition != D) { 4073218893Sdim Decl *ImportedDef = Importer.Import(Definition); 4074218893Sdim if (!ImportedDef) 4075218893Sdim return 0; 4076218893Sdim 4077218893Sdim return Importer.Imported(D, ImportedDef); 4078218893Sdim } 4079218893Sdim 4080218893Sdim ClassTemplateDecl *ClassTemplate 4081218893Sdim = cast_or_null<ClassTemplateDecl>(Importer.Import( 4082218893Sdim D->getSpecializedTemplate())); 4083218893Sdim if (!ClassTemplate) 4084218893Sdim return 0; 4085218893Sdim 4086218893Sdim // Import the context of this declaration. 4087218893Sdim DeclContext *DC = ClassTemplate->getDeclContext(); 4088218893Sdim if (!DC) 4089218893Sdim return 0; 4090218893Sdim 4091218893Sdim DeclContext *LexicalDC = DC; 4092218893Sdim if (D->getDeclContext() != D->getLexicalDeclContext()) { 4093218893Sdim LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); 4094218893Sdim if (!LexicalDC) 4095218893Sdim return 0; 4096218893Sdim } 4097218893Sdim 4098218893Sdim // Import the location of this declaration. 4099221345Sdim SourceLocation StartLoc = Importer.Import(D->getLocStart()); 4100221345Sdim SourceLocation IdLoc = Importer.Import(D->getLocation()); 4101218893Sdim 4102218893Sdim // Import template arguments. 4103226890Sdim SmallVector<TemplateArgument, 2> TemplateArgs; 4104218893Sdim if (ImportTemplateArguments(D->getTemplateArgs().data(), 4105218893Sdim D->getTemplateArgs().size(), 4106218893Sdim TemplateArgs)) 4107218893Sdim return 0; 4108218893Sdim 4109218893Sdim // Try to find an existing specialization with these template arguments. 4110218893Sdim void *InsertPos = 0; 4111218893Sdim ClassTemplateSpecializationDecl *D2 4112218893Sdim = ClassTemplate->findSpecialization(TemplateArgs.data(), 4113218893Sdim TemplateArgs.size(), InsertPos); 4114218893Sdim if (D2) { 4115218893Sdim // We already have a class template specialization with these template 4116218893Sdim // arguments. 4117218893Sdim 4118218893Sdim // FIXME: Check for specialization vs. instantiation errors. 4119218893Sdim 4120218893Sdim if (RecordDecl *FoundDef = D2->getDefinition()) { 4121226890Sdim if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) { 4122218893Sdim // The record types structurally match, or the "from" translation 4123218893Sdim // unit only had a forward declaration anyway; call it the same 4124218893Sdim // function. 4125218893Sdim return Importer.Imported(D, FoundDef); 4126218893Sdim } 4127218893Sdim } 4128218893Sdim } else { 4129218893Sdim // Create a new specialization. 4130218893Sdim D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(), 4131218893Sdim D->getTagKind(), DC, 4132221345Sdim StartLoc, IdLoc, 4133221345Sdim ClassTemplate, 4134218893Sdim TemplateArgs.data(), 4135218893Sdim TemplateArgs.size(), 4136218893Sdim /*PrevDecl=*/0); 4137218893Sdim D2->setSpecializationKind(D->getSpecializationKind()); 4138218893Sdim 4139218893Sdim // Add this specialization to the class template. 4140218893Sdim ClassTemplate->AddSpecialization(D2, InsertPos); 4141218893Sdim 4142218893Sdim // Import the qualifier, if any. 4143219077Sdim D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); 4144218893Sdim 4145218893Sdim // Add the specialization to this context. 4146218893Sdim D2->setLexicalDeclContext(LexicalDC); 4147235633Sdim LexicalDC->addDeclInternal(D2); 4148218893Sdim } 4149218893Sdim Importer.Imported(D, D2); 4150218893Sdim 4151226890Sdim if (D->isCompleteDefinition() && ImportDefinition(D, D2)) 4152218893Sdim return 0; 4153218893Sdim 4154218893Sdim return D2; 4155218893Sdim} 4156218893Sdim 4157263509SdimDecl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) { 4158263509Sdim // If this variable has a definition in the translation unit we're coming 4159263509Sdim // from, 4160263509Sdim // but this particular declaration is not that definition, import the 4161263509Sdim // definition and map to that. 4162263509Sdim VarDecl *Definition = 4163263509Sdim cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition()); 4164263509Sdim if (Definition && Definition != D->getTemplatedDecl()) { 4165263509Sdim Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate()); 4166263509Sdim if (!ImportedDef) 4167263509Sdim return 0; 4168263509Sdim 4169263509Sdim return Importer.Imported(D, ImportedDef); 4170263509Sdim } 4171263509Sdim 4172263509Sdim // Import the major distinguishing characteristics of this variable template. 4173263509Sdim DeclContext *DC, *LexicalDC; 4174263509Sdim DeclarationName Name; 4175263509Sdim SourceLocation Loc; 4176263509Sdim if (ImportDeclParts(D, DC, LexicalDC, Name, Loc)) 4177263509Sdim return 0; 4178263509Sdim 4179263509Sdim // We may already have a template of the same name; try to find and match it. 4180263509Sdim assert(!DC->isFunctionOrMethod() && 4181263509Sdim "Variable templates cannot be declared at function scope"); 4182263509Sdim SmallVector<NamedDecl *, 4> ConflictingDecls; 4183263509Sdim SmallVector<NamedDecl *, 2> FoundDecls; 4184263509Sdim DC->localUncachedLookup(Name, FoundDecls); 4185263509Sdim for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { 4186263509Sdim if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary)) 4187263509Sdim continue; 4188263509Sdim 4189263509Sdim Decl *Found = FoundDecls[I]; 4190263509Sdim if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) { 4191263509Sdim if (IsStructuralMatch(D, FoundTemplate)) { 4192263509Sdim // The variable templates structurally match; call it the same template. 4193263509Sdim Importer.Imported(D->getTemplatedDecl(), 4194263509Sdim FoundTemplate->getTemplatedDecl()); 4195263509Sdim return Importer.Imported(D, FoundTemplate); 4196263509Sdim } 4197263509Sdim } 4198263509Sdim 4199263509Sdim ConflictingDecls.push_back(FoundDecls[I]); 4200263509Sdim } 4201263509Sdim 4202263509Sdim if (!ConflictingDecls.empty()) { 4203263509Sdim Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary, 4204263509Sdim ConflictingDecls.data(), 4205263509Sdim ConflictingDecls.size()); 4206263509Sdim } 4207263509Sdim 4208263509Sdim if (!Name) 4209263509Sdim return 0; 4210263509Sdim 4211263509Sdim VarDecl *DTemplated = D->getTemplatedDecl(); 4212263509Sdim 4213263509Sdim // Import the type. 4214263509Sdim QualType T = Importer.Import(DTemplated->getType()); 4215263509Sdim if (T.isNull()) 4216263509Sdim return 0; 4217263509Sdim 4218263509Sdim // Create the declaration that is being templated. 4219263509Sdim SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart()); 4220263509Sdim SourceLocation IdLoc = Importer.Import(DTemplated->getLocation()); 4221263509Sdim TypeSourceInfo *TInfo = Importer.Import(DTemplated->getTypeSourceInfo()); 4222263509Sdim VarDecl *D2Templated = VarDecl::Create(Importer.getToContext(), DC, StartLoc, 4223263509Sdim IdLoc, Name.getAsIdentifierInfo(), T, 4224263509Sdim TInfo, DTemplated->getStorageClass()); 4225263509Sdim D2Templated->setAccess(DTemplated->getAccess()); 4226263509Sdim D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc())); 4227263509Sdim D2Templated->setLexicalDeclContext(LexicalDC); 4228263509Sdim 4229263509Sdim // Importer.Imported(DTemplated, D2Templated); 4230263509Sdim // LexicalDC->addDeclInternal(D2Templated); 4231263509Sdim 4232263509Sdim // Merge the initializer. 4233263509Sdim if (ImportDefinition(DTemplated, D2Templated)) 4234263509Sdim return 0; 4235263509Sdim 4236263509Sdim // Create the variable template declaration itself. 4237263509Sdim TemplateParameterList *TemplateParams = 4238263509Sdim ImportTemplateParameterList(D->getTemplateParameters()); 4239263509Sdim if (!TemplateParams) 4240263509Sdim return 0; 4241263509Sdim 4242263509Sdim VarTemplateDecl *D2 = VarTemplateDecl::Create( 4243263509Sdim Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated, 4244263509Sdim /*PrevDecl=*/0); 4245263509Sdim D2Templated->setDescribedVarTemplate(D2); 4246263509Sdim 4247263509Sdim D2->setAccess(D->getAccess()); 4248263509Sdim D2->setLexicalDeclContext(LexicalDC); 4249263509Sdim LexicalDC->addDeclInternal(D2); 4250263509Sdim 4251263509Sdim // Note the relationship between the variable templates. 4252263509Sdim Importer.Imported(D, D2); 4253263509Sdim Importer.Imported(DTemplated, D2Templated); 4254263509Sdim 4255263509Sdim if (DTemplated->isThisDeclarationADefinition() && 4256263509Sdim !D2Templated->isThisDeclarationADefinition()) { 4257263509Sdim // FIXME: Import definition! 4258263509Sdim } 4259263509Sdim 4260263509Sdim return D2; 4261263509Sdim} 4262263509Sdim 4263263509SdimDecl *ASTNodeImporter::VisitVarTemplateSpecializationDecl( 4264263509Sdim VarTemplateSpecializationDecl *D) { 4265263509Sdim // If this record has a definition in the translation unit we're coming from, 4266263509Sdim // but this particular declaration is not that definition, import the 4267263509Sdim // definition and map to that. 4268263509Sdim VarDecl *Definition = D->getDefinition(); 4269263509Sdim if (Definition && Definition != D) { 4270263509Sdim Decl *ImportedDef = Importer.Import(Definition); 4271263509Sdim if (!ImportedDef) 4272263509Sdim return 0; 4273263509Sdim 4274263509Sdim return Importer.Imported(D, ImportedDef); 4275263509Sdim } 4276263509Sdim 4277263509Sdim VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>( 4278263509Sdim Importer.Import(D->getSpecializedTemplate())); 4279263509Sdim if (!VarTemplate) 4280263509Sdim return 0; 4281263509Sdim 4282263509Sdim // Import the context of this declaration. 4283263509Sdim DeclContext *DC = VarTemplate->getDeclContext(); 4284263509Sdim if (!DC) 4285263509Sdim return 0; 4286263509Sdim 4287263509Sdim DeclContext *LexicalDC = DC; 4288263509Sdim if (D->getDeclContext() != D->getLexicalDeclContext()) { 4289263509Sdim LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); 4290263509Sdim if (!LexicalDC) 4291263509Sdim return 0; 4292263509Sdim } 4293263509Sdim 4294263509Sdim // Import the location of this declaration. 4295263509Sdim SourceLocation StartLoc = Importer.Import(D->getLocStart()); 4296263509Sdim SourceLocation IdLoc = Importer.Import(D->getLocation()); 4297263509Sdim 4298263509Sdim // Import template arguments. 4299263509Sdim SmallVector<TemplateArgument, 2> TemplateArgs; 4300263509Sdim if (ImportTemplateArguments(D->getTemplateArgs().data(), 4301263509Sdim D->getTemplateArgs().size(), TemplateArgs)) 4302263509Sdim return 0; 4303263509Sdim 4304263509Sdim // Try to find an existing specialization with these template arguments. 4305263509Sdim void *InsertPos = 0; 4306263509Sdim VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization( 4307263509Sdim TemplateArgs.data(), TemplateArgs.size(), InsertPos); 4308263509Sdim if (D2) { 4309263509Sdim // We already have a variable template specialization with these template 4310263509Sdim // arguments. 4311263509Sdim 4312263509Sdim // FIXME: Check for specialization vs. instantiation errors. 4313263509Sdim 4314263509Sdim if (VarDecl *FoundDef = D2->getDefinition()) { 4315263509Sdim if (!D->isThisDeclarationADefinition() || 4316263509Sdim IsStructuralMatch(D, FoundDef)) { 4317263509Sdim // The record types structurally match, or the "from" translation 4318263509Sdim // unit only had a forward declaration anyway; call it the same 4319263509Sdim // variable. 4320263509Sdim return Importer.Imported(D, FoundDef); 4321263509Sdim } 4322263509Sdim } 4323263509Sdim } else { 4324263509Sdim 4325263509Sdim // Import the type. 4326263509Sdim QualType T = Importer.Import(D->getType()); 4327263509Sdim if (T.isNull()) 4328263509Sdim return 0; 4329263509Sdim TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); 4330263509Sdim 4331263509Sdim // Create a new specialization. 4332263509Sdim D2 = VarTemplateSpecializationDecl::Create( 4333263509Sdim Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo, 4334263509Sdim D->getStorageClass(), TemplateArgs.data(), TemplateArgs.size()); 4335263509Sdim D2->setSpecializationKind(D->getSpecializationKind()); 4336263509Sdim D2->setTemplateArgsInfo(D->getTemplateArgsInfo()); 4337263509Sdim 4338263509Sdim // Add this specialization to the class template. 4339263509Sdim VarTemplate->AddSpecialization(D2, InsertPos); 4340263509Sdim 4341263509Sdim // Import the qualifier, if any. 4342263509Sdim D2->setQualifierInfo(Importer.Import(D->getQualifierLoc())); 4343263509Sdim 4344263509Sdim // Add the specialization to this context. 4345263509Sdim D2->setLexicalDeclContext(LexicalDC); 4346263509Sdim LexicalDC->addDeclInternal(D2); 4347263509Sdim } 4348263509Sdim Importer.Imported(D, D2); 4349263509Sdim 4350263509Sdim if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2)) 4351263509Sdim return 0; 4352263509Sdim 4353263509Sdim return D2; 4354263509Sdim} 4355263509Sdim 4356203955Srdivacky//---------------------------------------------------------------------------- 4357203955Srdivacky// Import Statements 4358203955Srdivacky//---------------------------------------------------------------------------- 4359203955Srdivacky 4360203955SrdivackyStmt *ASTNodeImporter::VisitStmt(Stmt *S) { 4361203955Srdivacky Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node) 4362203955Srdivacky << S->getStmtClassName(); 4363203955Srdivacky return 0; 4364203955Srdivacky} 4365203955Srdivacky 4366203955Srdivacky//---------------------------------------------------------------------------- 4367203955Srdivacky// Import Expressions 4368203955Srdivacky//---------------------------------------------------------------------------- 4369203955SrdivackyExpr *ASTNodeImporter::VisitExpr(Expr *E) { 4370203955Srdivacky Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node) 4371203955Srdivacky << E->getStmtClassName(); 4372203955Srdivacky return 0; 4373203955Srdivacky} 4374203955Srdivacky 4375204643SrdivackyExpr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { 4376204643Srdivacky ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl())); 4377204643Srdivacky if (!ToD) 4378204643Srdivacky return 0; 4379221345Sdim 4380221345Sdim NamedDecl *FoundD = 0; 4381221345Sdim if (E->getDecl() != E->getFoundDecl()) { 4382221345Sdim FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl())); 4383221345Sdim if (!FoundD) 4384221345Sdim return 0; 4385221345Sdim } 4386204643Srdivacky 4387204643Srdivacky QualType T = Importer.Import(E->getType()); 4388204643Srdivacky if (T.isNull()) 4389204643Srdivacky return 0; 4390226890Sdim 4391226890Sdim DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(), 4392226890Sdim Importer.Import(E->getQualifierLoc()), 4393235633Sdim Importer.Import(E->getTemplateKeywordLoc()), 4394226890Sdim ToD, 4395235633Sdim E->refersToEnclosingLocal(), 4396226890Sdim Importer.Import(E->getLocation()), 4397226890Sdim T, E->getValueKind(), 4398226890Sdim FoundD, 4399226890Sdim /*FIXME:TemplateArgs=*/0); 4400226890Sdim if (E->hadMultipleCandidates()) 4401226890Sdim DRE->setHadMultipleCandidates(true); 4402226890Sdim return DRE; 4403204643Srdivacky} 4404204643Srdivacky 4405203955SrdivackyExpr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) { 4406203955Srdivacky QualType T = Importer.Import(E->getType()); 4407203955Srdivacky if (T.isNull()) 4408203955Srdivacky return 0; 4409203955Srdivacky 4410212904Sdim return IntegerLiteral::Create(Importer.getToContext(), 4411212904Sdim E->getValue(), T, 4412212904Sdim Importer.Import(E->getLocation())); 4413203955Srdivacky} 4414203955Srdivacky 4415204643SrdivackyExpr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) { 4416204643Srdivacky QualType T = Importer.Import(E->getType()); 4417204643Srdivacky if (T.isNull()) 4418204643Srdivacky return 0; 4419204643Srdivacky 4420226890Sdim return new (Importer.getToContext()) CharacterLiteral(E->getValue(), 4421226890Sdim E->getKind(), T, 4422204643Srdivacky Importer.Import(E->getLocation())); 4423204643Srdivacky} 4424204643Srdivacky 4425204643SrdivackyExpr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) { 4426204643Srdivacky Expr *SubExpr = Importer.Import(E->getSubExpr()); 4427204643Srdivacky if (!SubExpr) 4428204643Srdivacky return 0; 4429204643Srdivacky 4430204643Srdivacky return new (Importer.getToContext()) 4431204643Srdivacky ParenExpr(Importer.Import(E->getLParen()), 4432204643Srdivacky Importer.Import(E->getRParen()), 4433204643Srdivacky SubExpr); 4434204643Srdivacky} 4435204643Srdivacky 4436204643SrdivackyExpr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { 4437204643Srdivacky QualType T = Importer.Import(E->getType()); 4438204643Srdivacky if (T.isNull()) 4439204643Srdivacky return 0; 4440204643Srdivacky 4441204643Srdivacky Expr *SubExpr = Importer.Import(E->getSubExpr()); 4442204643Srdivacky if (!SubExpr) 4443204643Srdivacky return 0; 4444204643Srdivacky 4445204643Srdivacky return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(), 4446218893Sdim T, E->getValueKind(), 4447218893Sdim E->getObjectKind(), 4448204643Srdivacky Importer.Import(E->getOperatorLoc())); 4449204643Srdivacky} 4450204643Srdivacky 4451221345SdimExpr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr( 4452221345Sdim UnaryExprOrTypeTraitExpr *E) { 4453204643Srdivacky QualType ResultType = Importer.Import(E->getType()); 4454204643Srdivacky 4455204643Srdivacky if (E->isArgumentType()) { 4456204643Srdivacky TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo()); 4457204643Srdivacky if (!TInfo) 4458204643Srdivacky return 0; 4459204643Srdivacky 4460221345Sdim return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(), 4461221345Sdim TInfo, ResultType, 4462204643Srdivacky Importer.Import(E->getOperatorLoc()), 4463204643Srdivacky Importer.Import(E->getRParenLoc())); 4464204643Srdivacky } 4465204643Srdivacky 4466204643Srdivacky Expr *SubExpr = Importer.Import(E->getArgumentExpr()); 4467204643Srdivacky if (!SubExpr) 4468204643Srdivacky return 0; 4469204643Srdivacky 4470221345Sdim return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(), 4471221345Sdim SubExpr, ResultType, 4472204643Srdivacky Importer.Import(E->getOperatorLoc()), 4473204643Srdivacky Importer.Import(E->getRParenLoc())); 4474204643Srdivacky} 4475204643Srdivacky 4476204643SrdivackyExpr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) { 4477204643Srdivacky QualType T = Importer.Import(E->getType()); 4478204643Srdivacky if (T.isNull()) 4479204643Srdivacky return 0; 4480204643Srdivacky 4481204643Srdivacky Expr *LHS = Importer.Import(E->getLHS()); 4482204643Srdivacky if (!LHS) 4483204643Srdivacky return 0; 4484204643Srdivacky 4485204643Srdivacky Expr *RHS = Importer.Import(E->getRHS()); 4486204643Srdivacky if (!RHS) 4487204643Srdivacky return 0; 4488204643Srdivacky 4489204643Srdivacky return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(), 4490218893Sdim T, E->getValueKind(), 4491218893Sdim E->getObjectKind(), 4492245431Sdim Importer.Import(E->getOperatorLoc()), 4493245431Sdim E->isFPContractable()); 4494204643Srdivacky} 4495204643Srdivacky 4496204643SrdivackyExpr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { 4497204643Srdivacky QualType T = Importer.Import(E->getType()); 4498204643Srdivacky if (T.isNull()) 4499204643Srdivacky return 0; 4500204643Srdivacky 4501204643Srdivacky QualType CompLHSType = Importer.Import(E->getComputationLHSType()); 4502204643Srdivacky if (CompLHSType.isNull()) 4503204643Srdivacky return 0; 4504204643Srdivacky 4505204643Srdivacky QualType CompResultType = Importer.Import(E->getComputationResultType()); 4506204643Srdivacky if (CompResultType.isNull()) 4507204643Srdivacky return 0; 4508204643Srdivacky 4509204643Srdivacky Expr *LHS = Importer.Import(E->getLHS()); 4510204643Srdivacky if (!LHS) 4511204643Srdivacky return 0; 4512204643Srdivacky 4513204643Srdivacky Expr *RHS = Importer.Import(E->getRHS()); 4514204643Srdivacky if (!RHS) 4515204643Srdivacky return 0; 4516204643Srdivacky 4517204643Srdivacky return new (Importer.getToContext()) 4518204643Srdivacky CompoundAssignOperator(LHS, RHS, E->getOpcode(), 4519218893Sdim T, E->getValueKind(), 4520218893Sdim E->getObjectKind(), 4521218893Sdim CompLHSType, CompResultType, 4522245431Sdim Importer.Import(E->getOperatorLoc()), 4523245431Sdim E->isFPContractable()); 4524204643Srdivacky} 4525204643Srdivacky 4526221345Sdimstatic bool ImportCastPath(CastExpr *E, CXXCastPath &Path) { 4527212904Sdim if (E->path_empty()) return false; 4528212904Sdim 4529212904Sdim // TODO: import cast paths 4530212904Sdim return true; 4531212904Sdim} 4532212904Sdim 4533203955SrdivackyExpr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) { 4534203955Srdivacky QualType T = Importer.Import(E->getType()); 4535203955Srdivacky if (T.isNull()) 4536203955Srdivacky return 0; 4537203955Srdivacky 4538203955Srdivacky Expr *SubExpr = Importer.Import(E->getSubExpr()); 4539203955Srdivacky if (!SubExpr) 4540203955Srdivacky return 0; 4541212904Sdim 4542212904Sdim CXXCastPath BasePath; 4543212904Sdim if (ImportCastPath(E, BasePath)) 4544212904Sdim return 0; 4545212904Sdim 4546212904Sdim return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(), 4547212904Sdim SubExpr, &BasePath, E->getValueKind()); 4548203955Srdivacky} 4549203955Srdivacky 4550204643SrdivackyExpr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { 4551204643Srdivacky QualType T = Importer.Import(E->getType()); 4552204643Srdivacky if (T.isNull()) 4553204643Srdivacky return 0; 4554204643Srdivacky 4555204643Srdivacky Expr *SubExpr = Importer.Import(E->getSubExpr()); 4556204643Srdivacky if (!SubExpr) 4557204643Srdivacky return 0; 4558204643Srdivacky 4559204643Srdivacky TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten()); 4560204643Srdivacky if (!TInfo && E->getTypeInfoAsWritten()) 4561204643Srdivacky return 0; 4562204643Srdivacky 4563212904Sdim CXXCastPath BasePath; 4564212904Sdim if (ImportCastPath(E, BasePath)) 4565212904Sdim return 0; 4566212904Sdim 4567218893Sdim return CStyleCastExpr::Create(Importer.getToContext(), T, 4568218893Sdim E->getValueKind(), E->getCastKind(), 4569212904Sdim SubExpr, &BasePath, TInfo, 4570212904Sdim Importer.Import(E->getLParenLoc()), 4571212904Sdim Importer.Import(E->getRParenLoc())); 4572204643Srdivacky} 4573204643Srdivacky 4574218893SdimASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, 4575218893Sdim ASTContext &FromContext, FileManager &FromFileManager, 4576218893Sdim bool MinimalImport) 4577203955Srdivacky : ToContext(ToContext), FromContext(FromContext), 4578203955Srdivacky ToFileManager(ToFileManager), FromFileManager(FromFileManager), 4579252723Sdim Minimal(MinimalImport), LastDiagFromFrom(false) 4580218893Sdim{ 4581203955Srdivacky ImportedDecls[FromContext.getTranslationUnitDecl()] 4582203955Srdivacky = ToContext.getTranslationUnitDecl(); 4583203955Srdivacky} 4584203955Srdivacky 4585203955SrdivackyASTImporter::~ASTImporter() { } 4586203955Srdivacky 4587203955SrdivackyQualType ASTImporter::Import(QualType FromT) { 4588203955Srdivacky if (FromT.isNull()) 4589203955Srdivacky return QualType(); 4590218893Sdim 4591218893Sdim const Type *fromTy = FromT.getTypePtr(); 4592203955Srdivacky 4593203955Srdivacky // Check whether we've already imported this type. 4594218893Sdim llvm::DenseMap<const Type *, const Type *>::iterator Pos 4595218893Sdim = ImportedTypes.find(fromTy); 4596203955Srdivacky if (Pos != ImportedTypes.end()) 4597218893Sdim return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers()); 4598203955Srdivacky 4599203955Srdivacky // Import the type 4600203955Srdivacky ASTNodeImporter Importer(*this); 4601218893Sdim QualType ToT = Importer.Visit(fromTy); 4602203955Srdivacky if (ToT.isNull()) 4603203955Srdivacky return ToT; 4604203955Srdivacky 4605203955Srdivacky // Record the imported type. 4606218893Sdim ImportedTypes[fromTy] = ToT.getTypePtr(); 4607203955Srdivacky 4608218893Sdim return ToContext.getQualifiedType(ToT, FromT.getLocalQualifiers()); 4609203955Srdivacky} 4610203955Srdivacky 4611203955SrdivackyTypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) { 4612203955Srdivacky if (!FromTSI) 4613203955Srdivacky return FromTSI; 4614203955Srdivacky 4615203955Srdivacky // FIXME: For now we just create a "trivial" type source info based 4616212904Sdim // on the type and a single location. Implement a real version of this. 4617203955Srdivacky QualType T = Import(FromTSI->getType()); 4618203955Srdivacky if (T.isNull()) 4619203955Srdivacky return 0; 4620203955Srdivacky 4621203955Srdivacky return ToContext.getTrivialTypeSourceInfo(T, 4622235633Sdim FromTSI->getTypeLoc().getLocStart()); 4623203955Srdivacky} 4624203955Srdivacky 4625203955SrdivackyDecl *ASTImporter::Import(Decl *FromD) { 4626203955Srdivacky if (!FromD) 4627203955Srdivacky return 0; 4628203955Srdivacky 4629226890Sdim ASTNodeImporter Importer(*this); 4630226890Sdim 4631203955Srdivacky // Check whether we've already imported this declaration. 4632203955Srdivacky llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD); 4633226890Sdim if (Pos != ImportedDecls.end()) { 4634226890Sdim Decl *ToD = Pos->second; 4635226890Sdim Importer.ImportDefinitionIfNeeded(FromD, ToD); 4636226890Sdim return ToD; 4637226890Sdim } 4638203955Srdivacky 4639203955Srdivacky // Import the type 4640203955Srdivacky Decl *ToD = Importer.Visit(FromD); 4641203955Srdivacky if (!ToD) 4642203955Srdivacky return 0; 4643203955Srdivacky 4644203955Srdivacky // Record the imported declaration. 4645203955Srdivacky ImportedDecls[FromD] = ToD; 4646203955Srdivacky 4647203955Srdivacky if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) { 4648203955Srdivacky // Keep track of anonymous tags that have an associated typedef. 4649221345Sdim if (FromTag->getTypedefNameForAnonDecl()) 4650203955Srdivacky AnonTagsWithPendingTypedefs.push_back(FromTag); 4651221345Sdim } else if (TypedefNameDecl *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) { 4652203955Srdivacky // When we've finished transforming a typedef, see whether it was the 4653203955Srdivacky // typedef for an anonymous tag. 4654263509Sdim for (SmallVectorImpl<TagDecl *>::iterator 4655203955Srdivacky FromTag = AnonTagsWithPendingTypedefs.begin(), 4656203955Srdivacky FromTagEnd = AnonTagsWithPendingTypedefs.end(); 4657203955Srdivacky FromTag != FromTagEnd; ++FromTag) { 4658221345Sdim if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) { 4659203955Srdivacky if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) { 4660203955Srdivacky // We found the typedef for an anonymous tag; link them. 4661221345Sdim ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD)); 4662203955Srdivacky AnonTagsWithPendingTypedefs.erase(FromTag); 4663203955Srdivacky break; 4664203955Srdivacky } 4665203955Srdivacky } 4666203955Srdivacky } 4667203955Srdivacky } 4668203955Srdivacky 4669203955Srdivacky return ToD; 4670203955Srdivacky} 4671203955Srdivacky 4672203955SrdivackyDeclContext *ASTImporter::ImportContext(DeclContext *FromDC) { 4673203955Srdivacky if (!FromDC) 4674203955Srdivacky return FromDC; 4675203955Srdivacky 4676235633Sdim DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC))); 4677235633Sdim if (!ToDC) 4678235633Sdim return 0; 4679235633Sdim 4680235633Sdim // When we're using a record/enum/Objective-C class/protocol as a context, we 4681235633Sdim // need it to have a definition. 4682235633Sdim if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) { 4683235633Sdim RecordDecl *FromRecord = cast<RecordDecl>(FromDC); 4684235633Sdim if (ToRecord->isCompleteDefinition()) { 4685235633Sdim // Do nothing. 4686235633Sdim } else if (FromRecord->isCompleteDefinition()) { 4687235633Sdim ASTNodeImporter(*this).ImportDefinition(FromRecord, ToRecord, 4688235633Sdim ASTNodeImporter::IDK_Basic); 4689235633Sdim } else { 4690235633Sdim CompleteDecl(ToRecord); 4691235633Sdim } 4692235633Sdim } else if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(ToDC)) { 4693235633Sdim EnumDecl *FromEnum = cast<EnumDecl>(FromDC); 4694235633Sdim if (ToEnum->isCompleteDefinition()) { 4695235633Sdim // Do nothing. 4696235633Sdim } else if (FromEnum->isCompleteDefinition()) { 4697235633Sdim ASTNodeImporter(*this).ImportDefinition(FromEnum, ToEnum, 4698235633Sdim ASTNodeImporter::IDK_Basic); 4699235633Sdim } else { 4700235633Sdim CompleteDecl(ToEnum); 4701235633Sdim } 4702235633Sdim } else if (ObjCInterfaceDecl *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) { 4703235633Sdim ObjCInterfaceDecl *FromClass = cast<ObjCInterfaceDecl>(FromDC); 4704235633Sdim if (ToClass->getDefinition()) { 4705235633Sdim // Do nothing. 4706235633Sdim } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) { 4707235633Sdim ASTNodeImporter(*this).ImportDefinition(FromDef, ToClass, 4708235633Sdim ASTNodeImporter::IDK_Basic); 4709235633Sdim } else { 4710235633Sdim CompleteDecl(ToClass); 4711235633Sdim } 4712235633Sdim } else if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) { 4713235633Sdim ObjCProtocolDecl *FromProto = cast<ObjCProtocolDecl>(FromDC); 4714235633Sdim if (ToProto->getDefinition()) { 4715235633Sdim // Do nothing. 4716235633Sdim } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) { 4717235633Sdim ASTNodeImporter(*this).ImportDefinition(FromDef, ToProto, 4718235633Sdim ASTNodeImporter::IDK_Basic); 4719235633Sdim } else { 4720235633Sdim CompleteDecl(ToProto); 4721235633Sdim } 4722235633Sdim } 4723235633Sdim 4724235633Sdim return ToDC; 4725203955Srdivacky} 4726203955Srdivacky 4727203955SrdivackyExpr *ASTImporter::Import(Expr *FromE) { 4728203955Srdivacky if (!FromE) 4729203955Srdivacky return 0; 4730203955Srdivacky 4731203955Srdivacky return cast_or_null<Expr>(Import(cast<Stmt>(FromE))); 4732203955Srdivacky} 4733203955Srdivacky 4734203955SrdivackyStmt *ASTImporter::Import(Stmt *FromS) { 4735203955Srdivacky if (!FromS) 4736203955Srdivacky return 0; 4737203955Srdivacky 4738203955Srdivacky // Check whether we've already imported this declaration. 4739203955Srdivacky llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS); 4740203955Srdivacky if (Pos != ImportedStmts.end()) 4741203955Srdivacky return Pos->second; 4742203955Srdivacky 4743203955Srdivacky // Import the type 4744203955Srdivacky ASTNodeImporter Importer(*this); 4745203955Srdivacky Stmt *ToS = Importer.Visit(FromS); 4746203955Srdivacky if (!ToS) 4747203955Srdivacky return 0; 4748203955Srdivacky 4749203955Srdivacky // Record the imported declaration. 4750203955Srdivacky ImportedStmts[FromS] = ToS; 4751203955Srdivacky return ToS; 4752203955Srdivacky} 4753203955Srdivacky 4754203955SrdivackyNestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) { 4755203955Srdivacky if (!FromNNS) 4756203955Srdivacky return 0; 4757203955Srdivacky 4758221345Sdim NestedNameSpecifier *prefix = Import(FromNNS->getPrefix()); 4759221345Sdim 4760221345Sdim switch (FromNNS->getKind()) { 4761221345Sdim case NestedNameSpecifier::Identifier: 4762221345Sdim if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) { 4763221345Sdim return NestedNameSpecifier::Create(ToContext, prefix, II); 4764221345Sdim } 4765221345Sdim return 0; 4766221345Sdim 4767221345Sdim case NestedNameSpecifier::Namespace: 4768221345Sdim if (NamespaceDecl *NS = 4769221345Sdim cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) { 4770221345Sdim return NestedNameSpecifier::Create(ToContext, prefix, NS); 4771221345Sdim } 4772221345Sdim return 0; 4773221345Sdim 4774221345Sdim case NestedNameSpecifier::NamespaceAlias: 4775221345Sdim if (NamespaceAliasDecl *NSAD = 4776221345Sdim cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) { 4777221345Sdim return NestedNameSpecifier::Create(ToContext, prefix, NSAD); 4778221345Sdim } 4779221345Sdim return 0; 4780221345Sdim 4781221345Sdim case NestedNameSpecifier::Global: 4782221345Sdim return NestedNameSpecifier::GlobalSpecifier(ToContext); 4783221345Sdim 4784221345Sdim case NestedNameSpecifier::TypeSpec: 4785221345Sdim case NestedNameSpecifier::TypeSpecWithTemplate: { 4786221345Sdim QualType T = Import(QualType(FromNNS->getAsType(), 0u)); 4787221345Sdim if (!T.isNull()) { 4788221345Sdim bool bTemplate = FromNNS->getKind() == 4789221345Sdim NestedNameSpecifier::TypeSpecWithTemplate; 4790221345Sdim return NestedNameSpecifier::Create(ToContext, prefix, 4791221345Sdim bTemplate, T.getTypePtr()); 4792221345Sdim } 4793221345Sdim } 4794221345Sdim return 0; 4795221345Sdim } 4796221345Sdim 4797221345Sdim llvm_unreachable("Invalid nested name specifier kind"); 4798203955Srdivacky} 4799203955Srdivacky 4800219077SdimNestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) { 4801219077Sdim // FIXME: Implement! 4802219077Sdim return NestedNameSpecifierLoc(); 4803219077Sdim} 4804219077Sdim 4805218893SdimTemplateName ASTImporter::Import(TemplateName From) { 4806218893Sdim switch (From.getKind()) { 4807218893Sdim case TemplateName::Template: 4808218893Sdim if (TemplateDecl *ToTemplate 4809218893Sdim = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl()))) 4810218893Sdim return TemplateName(ToTemplate); 4811218893Sdim 4812218893Sdim return TemplateName(); 4813218893Sdim 4814218893Sdim case TemplateName::OverloadedTemplate: { 4815218893Sdim OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate(); 4816218893Sdim UnresolvedSet<2> ToTemplates; 4817218893Sdim for (OverloadedTemplateStorage::iterator I = FromStorage->begin(), 4818218893Sdim E = FromStorage->end(); 4819218893Sdim I != E; ++I) { 4820218893Sdim if (NamedDecl *To = cast_or_null<NamedDecl>(Import(*I))) 4821218893Sdim ToTemplates.addDecl(To); 4822218893Sdim else 4823218893Sdim return TemplateName(); 4824218893Sdim } 4825218893Sdim return ToContext.getOverloadedTemplateName(ToTemplates.begin(), 4826218893Sdim ToTemplates.end()); 4827218893Sdim } 4828218893Sdim 4829218893Sdim case TemplateName::QualifiedTemplate: { 4830218893Sdim QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName(); 4831218893Sdim NestedNameSpecifier *Qualifier = Import(QTN->getQualifier()); 4832218893Sdim if (!Qualifier) 4833218893Sdim return TemplateName(); 4834218893Sdim 4835218893Sdim if (TemplateDecl *ToTemplate 4836218893Sdim = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl()))) 4837218893Sdim return ToContext.getQualifiedTemplateName(Qualifier, 4838218893Sdim QTN->hasTemplateKeyword(), 4839218893Sdim ToTemplate); 4840218893Sdim 4841218893Sdim return TemplateName(); 4842218893Sdim } 4843218893Sdim 4844218893Sdim case TemplateName::DependentTemplate: { 4845218893Sdim DependentTemplateName *DTN = From.getAsDependentTemplateName(); 4846218893Sdim NestedNameSpecifier *Qualifier = Import(DTN->getQualifier()); 4847218893Sdim if (!Qualifier) 4848218893Sdim return TemplateName(); 4849218893Sdim 4850218893Sdim if (DTN->isIdentifier()) { 4851218893Sdim return ToContext.getDependentTemplateName(Qualifier, 4852218893Sdim Import(DTN->getIdentifier())); 4853218893Sdim } 4854218893Sdim 4855218893Sdim return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator()); 4856218893Sdim } 4857224145Sdim 4858224145Sdim case TemplateName::SubstTemplateTemplateParm: { 4859224145Sdim SubstTemplateTemplateParmStorage *subst 4860224145Sdim = From.getAsSubstTemplateTemplateParm(); 4861224145Sdim TemplateTemplateParmDecl *param 4862224145Sdim = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter())); 4863224145Sdim if (!param) 4864224145Sdim return TemplateName(); 4865224145Sdim 4866224145Sdim TemplateName replacement = Import(subst->getReplacement()); 4867224145Sdim if (replacement.isNull()) return TemplateName(); 4868224145Sdim 4869224145Sdim return ToContext.getSubstTemplateTemplateParm(param, replacement); 4870224145Sdim } 4871218893Sdim 4872218893Sdim case TemplateName::SubstTemplateTemplateParmPack: { 4873218893Sdim SubstTemplateTemplateParmPackStorage *SubstPack 4874218893Sdim = From.getAsSubstTemplateTemplateParmPack(); 4875218893Sdim TemplateTemplateParmDecl *Param 4876218893Sdim = cast_or_null<TemplateTemplateParmDecl>( 4877218893Sdim Import(SubstPack->getParameterPack())); 4878218893Sdim if (!Param) 4879218893Sdim return TemplateName(); 4880218893Sdim 4881218893Sdim ASTNodeImporter Importer(*this); 4882218893Sdim TemplateArgument ArgPack 4883218893Sdim = Importer.ImportTemplateArgument(SubstPack->getArgumentPack()); 4884218893Sdim if (ArgPack.isNull()) 4885218893Sdim return TemplateName(); 4886218893Sdim 4887218893Sdim return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack); 4888218893Sdim } 4889218893Sdim } 4890218893Sdim 4891218893Sdim llvm_unreachable("Invalid template name kind"); 4892218893Sdim} 4893218893Sdim 4894203955SrdivackySourceLocation ASTImporter::Import(SourceLocation FromLoc) { 4895203955Srdivacky if (FromLoc.isInvalid()) 4896203955Srdivacky return SourceLocation(); 4897203955Srdivacky 4898203955Srdivacky SourceManager &FromSM = FromContext.getSourceManager(); 4899203955Srdivacky 4900203955Srdivacky // For now, map everything down to its spelling location, so that we 4901224145Sdim // don't have to import macro expansions. 4902224145Sdim // FIXME: Import macro expansions! 4903203955Srdivacky FromLoc = FromSM.getSpellingLoc(FromLoc); 4904203955Srdivacky std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc); 4905203955Srdivacky SourceManager &ToSM = ToContext.getSourceManager(); 4906203955Srdivacky return ToSM.getLocForStartOfFile(Import(Decomposed.first)) 4907226890Sdim .getLocWithOffset(Decomposed.second); 4908203955Srdivacky} 4909203955Srdivacky 4910203955SrdivackySourceRange ASTImporter::Import(SourceRange FromRange) { 4911203955Srdivacky return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd())); 4912203955Srdivacky} 4913203955Srdivacky 4914203955SrdivackyFileID ASTImporter::Import(FileID FromID) { 4915218893Sdim llvm::DenseMap<FileID, FileID>::iterator Pos 4916218893Sdim = ImportedFileIDs.find(FromID); 4917203955Srdivacky if (Pos != ImportedFileIDs.end()) 4918203955Srdivacky return Pos->second; 4919203955Srdivacky 4920203955Srdivacky SourceManager &FromSM = FromContext.getSourceManager(); 4921203955Srdivacky SourceManager &ToSM = ToContext.getSourceManager(); 4922203955Srdivacky const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID); 4923224145Sdim assert(FromSLoc.isFile() && "Cannot handle macro expansions yet"); 4924203955Srdivacky 4925203955Srdivacky // Include location of this file. 4926203955Srdivacky SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc()); 4927203955Srdivacky 4928203955Srdivacky // Map the FileID for to the "to" source manager. 4929203955Srdivacky FileID ToID; 4930203955Srdivacky const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache(); 4931221345Sdim if (Cache->OrigEntry) { 4932203955Srdivacky // FIXME: We probably want to use getVirtualFile(), so we don't hit the 4933203955Srdivacky // disk again 4934203955Srdivacky // FIXME: We definitely want to re-use the existing MemoryBuffer, rather 4935203955Srdivacky // than mmap the files several times. 4936221345Sdim const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName()); 4937203955Srdivacky ToID = ToSM.createFileID(Entry, ToIncludeLoc, 4938203955Srdivacky FromSLoc.getFile().getFileCharacteristic()); 4939203955Srdivacky } else { 4940203955Srdivacky // FIXME: We want to re-use the existing MemoryBuffer! 4941218893Sdim const llvm::MemoryBuffer * 4942218893Sdim FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM); 4943203955Srdivacky llvm::MemoryBuffer *ToBuf 4944206275Srdivacky = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(), 4945203955Srdivacky FromBuf->getBufferIdentifier()); 4946245431Sdim ToID = ToSM.createFileIDForMemBuffer(ToBuf, 4947245431Sdim FromSLoc.getFile().getFileCharacteristic()); 4948203955Srdivacky } 4949203955Srdivacky 4950203955Srdivacky 4951218893Sdim ImportedFileIDs[FromID] = ToID; 4952203955Srdivacky return ToID; 4953203955Srdivacky} 4954203955Srdivacky 4955218893Sdimvoid ASTImporter::ImportDefinition(Decl *From) { 4956218893Sdim Decl *To = Import(From); 4957218893Sdim if (!To) 4958218893Sdim return; 4959218893Sdim 4960218893Sdim if (DeclContext *FromDC = cast<DeclContext>(From)) { 4961218893Sdim ASTNodeImporter Importer(*this); 4962226890Sdim 4963226890Sdim if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(To)) { 4964226890Sdim if (!ToRecord->getDefinition()) { 4965226890Sdim Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord, 4966235633Sdim ASTNodeImporter::IDK_Everything); 4967226890Sdim return; 4968226890Sdim } 4969226890Sdim } 4970226890Sdim 4971226890Sdim if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(To)) { 4972226890Sdim if (!ToEnum->getDefinition()) { 4973226890Sdim Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum, 4974235633Sdim ASTNodeImporter::IDK_Everything); 4975226890Sdim return; 4976226890Sdim } 4977226890Sdim } 4978235633Sdim 4979235633Sdim if (ObjCInterfaceDecl *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) { 4980235633Sdim if (!ToIFace->getDefinition()) { 4981235633Sdim Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace, 4982235633Sdim ASTNodeImporter::IDK_Everything); 4983235633Sdim return; 4984235633Sdim } 4985235633Sdim } 4986226890Sdim 4987235633Sdim if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(To)) { 4988235633Sdim if (!ToProto->getDefinition()) { 4989235633Sdim Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto, 4990235633Sdim ASTNodeImporter::IDK_Everything); 4991235633Sdim return; 4992235633Sdim } 4993235633Sdim } 4994235633Sdim 4995218893Sdim Importer.ImportDeclContext(FromDC, true); 4996218893Sdim } 4997218893Sdim} 4998218893Sdim 4999203955SrdivackyDeclarationName ASTImporter::Import(DeclarationName FromName) { 5000203955Srdivacky if (!FromName) 5001203955Srdivacky return DeclarationName(); 5002203955Srdivacky 5003203955Srdivacky switch (FromName.getNameKind()) { 5004203955Srdivacky case DeclarationName::Identifier: 5005203955Srdivacky return Import(FromName.getAsIdentifierInfo()); 5006203955Srdivacky 5007203955Srdivacky case DeclarationName::ObjCZeroArgSelector: 5008203955Srdivacky case DeclarationName::ObjCOneArgSelector: 5009203955Srdivacky case DeclarationName::ObjCMultiArgSelector: 5010203955Srdivacky return Import(FromName.getObjCSelector()); 5011203955Srdivacky 5012203955Srdivacky case DeclarationName::CXXConstructorName: { 5013203955Srdivacky QualType T = Import(FromName.getCXXNameType()); 5014203955Srdivacky if (T.isNull()) 5015203955Srdivacky return DeclarationName(); 5016203955Srdivacky 5017203955Srdivacky return ToContext.DeclarationNames.getCXXConstructorName( 5018203955Srdivacky ToContext.getCanonicalType(T)); 5019203955Srdivacky } 5020203955Srdivacky 5021203955Srdivacky case DeclarationName::CXXDestructorName: { 5022203955Srdivacky QualType T = Import(FromName.getCXXNameType()); 5023203955Srdivacky if (T.isNull()) 5024203955Srdivacky return DeclarationName(); 5025203955Srdivacky 5026203955Srdivacky return ToContext.DeclarationNames.getCXXDestructorName( 5027203955Srdivacky ToContext.getCanonicalType(T)); 5028203955Srdivacky } 5029203955Srdivacky 5030203955Srdivacky case DeclarationName::CXXConversionFunctionName: { 5031203955Srdivacky QualType T = Import(FromName.getCXXNameType()); 5032203955Srdivacky if (T.isNull()) 5033203955Srdivacky return DeclarationName(); 5034203955Srdivacky 5035203955Srdivacky return ToContext.DeclarationNames.getCXXConversionFunctionName( 5036203955Srdivacky ToContext.getCanonicalType(T)); 5037203955Srdivacky } 5038203955Srdivacky 5039203955Srdivacky case DeclarationName::CXXOperatorName: 5040203955Srdivacky return ToContext.DeclarationNames.getCXXOperatorName( 5041203955Srdivacky FromName.getCXXOverloadedOperator()); 5042203955Srdivacky 5043203955Srdivacky case DeclarationName::CXXLiteralOperatorName: 5044203955Srdivacky return ToContext.DeclarationNames.getCXXLiteralOperatorName( 5045203955Srdivacky Import(FromName.getCXXLiteralIdentifier())); 5046203955Srdivacky 5047203955Srdivacky case DeclarationName::CXXUsingDirective: 5048203955Srdivacky // FIXME: STATICS! 5049203955Srdivacky return DeclarationName::getUsingDirectiveName(); 5050203955Srdivacky } 5051203955Srdivacky 5052235633Sdim llvm_unreachable("Invalid DeclarationName Kind!"); 5053203955Srdivacky} 5054203955Srdivacky 5055218893SdimIdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) { 5056203955Srdivacky if (!FromId) 5057203955Srdivacky return 0; 5058203955Srdivacky 5059203955Srdivacky return &ToContext.Idents.get(FromId->getName()); 5060203955Srdivacky} 5061203955Srdivacky 5062204643SrdivackySelector ASTImporter::Import(Selector FromSel) { 5063204643Srdivacky if (FromSel.isNull()) 5064204643Srdivacky return Selector(); 5065204643Srdivacky 5066226890Sdim SmallVector<IdentifierInfo *, 4> Idents; 5067204643Srdivacky Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0))); 5068204643Srdivacky for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I) 5069204643Srdivacky Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I))); 5070204643Srdivacky return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data()); 5071204643Srdivacky} 5072204643Srdivacky 5073203955SrdivackyDeclarationName ASTImporter::HandleNameConflict(DeclarationName Name, 5074203955Srdivacky DeclContext *DC, 5075203955Srdivacky unsigned IDNS, 5076203955Srdivacky NamedDecl **Decls, 5077203955Srdivacky unsigned NumDecls) { 5078203955Srdivacky return Name; 5079203955Srdivacky} 5080203955Srdivacky 5081203955SrdivackyDiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) { 5082252723Sdim if (LastDiagFromFrom) 5083252723Sdim ToContext.getDiagnostics().notePriorDiagnosticFrom( 5084252723Sdim FromContext.getDiagnostics()); 5085252723Sdim LastDiagFromFrom = false; 5086218893Sdim return ToContext.getDiagnostics().Report(Loc, DiagID); 5087203955Srdivacky} 5088203955Srdivacky 5089203955SrdivackyDiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) { 5090252723Sdim if (!LastDiagFromFrom) 5091252723Sdim FromContext.getDiagnostics().notePriorDiagnosticFrom( 5092252723Sdim ToContext.getDiagnostics()); 5093252723Sdim LastDiagFromFrom = true; 5094218893Sdim return FromContext.getDiagnostics().Report(Loc, DiagID); 5095203955Srdivacky} 5096203955Srdivacky 5097235633Sdimvoid ASTImporter::CompleteDecl (Decl *D) { 5098235633Sdim if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { 5099235633Sdim if (!ID->getDefinition()) 5100235633Sdim ID->startDefinition(); 5101235633Sdim } 5102235633Sdim else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { 5103235633Sdim if (!PD->getDefinition()) 5104235633Sdim PD->startDefinition(); 5105235633Sdim } 5106235633Sdim else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 5107235633Sdim if (!TD->getDefinition() && !TD->isBeingDefined()) { 5108235633Sdim TD->startDefinition(); 5109235633Sdim TD->setCompleteDefinition(true); 5110235633Sdim } 5111235633Sdim } 5112235633Sdim else { 5113235633Sdim assert (0 && "CompleteDecl called on a Decl that can't be completed"); 5114235633Sdim } 5115235633Sdim} 5116235633Sdim 5117203955SrdivackyDecl *ASTImporter::Imported(Decl *From, Decl *To) { 5118203955Srdivacky ImportedDecls[From] = To; 5119203955Srdivacky return To; 5120203955Srdivacky} 5121203955Srdivacky 5122245431Sdimbool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To, 5123245431Sdim bool Complain) { 5124218893Sdim llvm::DenseMap<const Type *, const Type *>::iterator Pos 5125203955Srdivacky = ImportedTypes.find(From.getTypePtr()); 5126203955Srdivacky if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To)) 5127203955Srdivacky return true; 5128203955Srdivacky 5129245431Sdim StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls, 5130245431Sdim false, Complain); 5131204643Srdivacky return Ctx.IsStructurallyEquivalent(From, To); 5132203955Srdivacky} 5133