diff options
Diffstat (limited to 'lib/AST/ASTImporter.cpp')
-rw-r--r-- | lib/AST/ASTImporter.cpp | 601 |
1 files changed, 581 insertions, 20 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 2c0bb11cc4bc3..84b0d7ecff93f 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -58,7 +58,7 @@ namespace clang { QualType VisitExtVectorType(const ExtVectorType *T); QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T); QualType VisitFunctionProtoType(const FunctionProtoType *T); - // FIXME: UnresolvedUsingType + QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T); QualType VisitParenType(const ParenType *T); QualType VisitTypedefType(const TypedefType *T); QualType VisitTypeOfExprType(const TypeOfExprType *T); @@ -77,6 +77,7 @@ namespace clang { QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); QualType VisitElaboratedType(const ElaboratedType *T); // FIXME: DependentNameType + QualType VisitPackExpansionType(const PackExpansionType *T); // FIXME: DependentTemplateSpecializationType QualType VisitObjCInterfaceType(const ObjCInterfaceType *T); QualType VisitObjCObjectType(const ObjCObjectType *T); @@ -128,27 +129,35 @@ namespace clang { TemplateParameterList *ImportTemplateParameterList( TemplateParameterList *Params); TemplateArgument ImportTemplateArgument(const TemplateArgument &From); - TemplateArgumentLoc ImportTemplateArgumentLoc( - const TemplateArgumentLoc &TALoc, bool &Error); + Optional<TemplateArgumentLoc> ImportTemplateArgumentLoc( + const TemplateArgumentLoc &TALoc); bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl<TemplateArgument> &ToArgs); + template <typename InContainerTy> + bool ImportTemplateArgumentListInfo(const InContainerTy &Container, + TemplateArgumentListInfo &ToTAInfo); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, bool Complain = true); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); + bool IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To); bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); + Decl *VisitEmptyDecl(EmptyDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); + Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); + Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); Decl *VisitLabelDecl(LabelDecl *D); Decl *VisitEnumDecl(EnumDecl *D); Decl *VisitRecordDecl(RecordDecl *D); @@ -170,6 +179,12 @@ namespace clang { Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D); Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D); Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D); + Decl *VisitUsingDecl(UsingDecl *D); + Decl *VisitUsingShadowDecl(UsingShadowDecl *D); + Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); + Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); + Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); + ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list); Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); @@ -185,6 +200,7 @@ namespace clang { ClassTemplateSpecializationDecl *D); Decl *VisitVarTemplateDecl(VarTemplateDecl *D); Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); + Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); // Importing statements DeclGroupRef ImportDeclGroup(DeclGroupRef DG); @@ -265,13 +281,16 @@ namespace clang { Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE); Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E); + Expr *VisitPackExpansionExpr(PackExpansionExpr *E); Expr *VisitCXXNewExpr(CXXNewExpr *CE); Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); + Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); + Expr *VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); Expr *VisitInitListExpr(InitListExpr *E); @@ -280,6 +299,7 @@ namespace clang { Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E); Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E); + Expr *VisitTypeTraitExpr(TypeTraitExpr *E); template<typename IIter, typename OIter> @@ -566,6 +586,22 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) { return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI); } +QualType ASTNodeImporter::VisitUnresolvedUsingType( + const UnresolvedUsingType *T) { + UnresolvedUsingTypenameDecl *ToD = cast_or_null<UnresolvedUsingTypenameDecl>( + Importer.Import(T->getDecl())); + if (!ToD) + return QualType(); + + UnresolvedUsingTypenameDecl *ToPrevD = + cast_or_null<UnresolvedUsingTypenameDecl>( + Importer.Import(T->getDecl()->getPreviousDecl())); + if (!ToPrevD && T->getDecl()->getPreviousDecl()) + return QualType(); + + return Importer.getToContext().getTypeDeclType(ToD, ToPrevD); +} + QualType ASTNodeImporter::VisitParenType(const ParenType *T) { QualType ToInnerType = Importer.Import(T->getInnerType()); if (ToInnerType.isNull()) @@ -767,6 +803,15 @@ QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) { ToQualifier, ToNamedType); } +QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) { + QualType Pattern = Importer.Import(T->getPattern()); + if (Pattern.isNull()) + return QualType(); + + return Importer.getToContext().getPackExpansionType(Pattern, + T->getNumExpansions()); +} + QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) { ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl())); @@ -1171,9 +1216,8 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) { llvm_unreachable("Invalid template argument kind"); } -TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc( - const TemplateArgumentLoc &TALoc, bool &Error) { - Error = false; +Optional<TemplateArgumentLoc> +ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) { TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument()); TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo(); TemplateArgumentLocInfo ToInfo; @@ -1181,12 +1225,12 @@ TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc( Expr *E = Importer.Import(FromInfo.getAsExpr()); ToInfo = TemplateArgumentLocInfo(E); if (!E) - Error = true; + return None; } else if (Arg.getKind() == TemplateArgument::Type) { if (TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo())) ToInfo = TemplateArgumentLocInfo(TSI); else - Error = true; + return None; } else { ToInfo = TemplateArgumentLocInfo( Importer.Import(FromInfo.getTemplateQualifierLoc()), @@ -1210,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs, return false; } +template <typename InContainerTy> +bool ASTNodeImporter::ImportTemplateArgumentListInfo( + const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { + for (const auto &FromLoc : Container) { + if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) + ToTAInfo.addArgument(*ToLoc); + else + return true; + } + return false; +} + bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1243,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) { return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); } +bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To) { + StructuralEquivalenceContext Ctx( + Importer.getFromContext(), Importer.getToContext(), + Importer.getNonEquivalentDecls(), false, false); + return Ctx.IsStructurallyEquivalent(From, To); +} + bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC) { @@ -1276,6 +1340,29 @@ Decl *ASTNodeImporter::VisitDecl(Decl *D) { return nullptr; } +Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) { + // Import the context of this declaration. + DeclContext *DC = Importer.ImportContext(D->getDeclContext()); + if (!DC) + return nullptr; + + DeclContext *LexicalDC = DC; + if (D->getDeclContext() != D->getLexicalDeclContext()) { + LexicalDC = Importer.ImportContext(D->getLexicalDeclContext()); + if (!LexicalDC) + return nullptr; + } + + // Import the location of this declaration. + SourceLocation Loc = Importer.Import(D->getLocation()); + + EmptyDecl *ToD = EmptyDecl::Create(Importer.getToContext(), DC, Loc); + ToD->setLexicalDeclContext(LexicalDC); + Importer.Imported(D, ToD); + LexicalDC->addDeclInternal(ToD); + return ToD; +} + Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { TranslationUnitDecl *ToD = Importer.getToContext().getTranslationUnitDecl(); @@ -1410,6 +1497,44 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) { return ToNamespace; } +Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { + // Import the major distinguishing characteristics of this namespace. + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *LookupD; + if (ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc)) + return nullptr; + if (LookupD) + return LookupD; + + // NOTE: No conflict resolution is done for namespace aliases now. + + NamespaceDecl *TargetDecl = cast_or_null<NamespaceDecl>( + Importer.Import(D->getNamespace())); + if (!TargetDecl) + return nullptr; + + IdentifierInfo *ToII = Importer.Import(D->getIdentifier()); + if (!ToII) + return nullptr; + + NestedNameSpecifierLoc ToQLoc = Importer.Import(D->getQualifierLoc()); + if (D->getQualifierLoc() && !ToQLoc) + return nullptr; + + NamespaceAliasDecl *ToD = NamespaceAliasDecl::Create( + Importer.getToContext(), DC, Importer.Import(D->getNamespaceLoc()), + Importer.Import(D->getAliasLoc()), ToII, ToQLoc, + Importer.Import(D->getTargetNameLoc()), TargetDecl); + + ToD->setLexicalDeclContext(LexicalDC); + Importer.Imported(D, ToD); + LexicalDC->addDeclInternal(ToD); + + return ToD; +} + Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) { // Import the major distinguishing characteristics of this typedef. DeclContext *DC, *LexicalDC; @@ -1487,6 +1612,63 @@ Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) { return VisitTypedefNameDecl(D, /*IsAlias=*/true); } +Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { + // Import the major distinguishing characteristics of this typedef. + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + // If this typedef is not in block scope, determine whether we've + // seen a typedef with the same name (that we can merge with) or any + // other entity by that name (which name lookup could conflict with). + if (!DC->isFunctionOrMethod()) { + SmallVector<NamedDecl *, 4> ConflictingDecls; + unsigned IDNS = Decl::IDNS_Ordinary; + SmallVector<NamedDecl *, 2> FoundDecls; + DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); + for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { + if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) + continue; + if (auto *FoundAlias = + dyn_cast<TypeAliasTemplateDecl>(FoundDecls[I])) + return Importer.Imported(D, FoundAlias); + ConflictingDecls.push_back(FoundDecls[I]); + } + + if (!ConflictingDecls.empty()) { + Name = Importer.HandleNameConflict(Name, DC, IDNS, + ConflictingDecls.data(), + ConflictingDecls.size()); + if (!Name) + return nullptr; + } + } + + TemplateParameterList *Params = ImportTemplateParameterList( + D->getTemplateParameters()); + if (!Params) + return nullptr; + + NamedDecl *TemplDecl = cast_or_null<NamedDecl>( + Importer.Import(D->getTemplatedDecl())); + if (!TemplDecl) + return nullptr; + + TypeAliasTemplateDecl *ToAlias = TypeAliasTemplateDecl::Create( + Importer.getToContext(), DC, Loc, Name, Params, TemplDecl); + + ToAlias->setAccess(D->getAccess()); + ToAlias->setLexicalDeclContext(LexicalDC); + Importer.Imported(D, ToAlias); + LexicalDC->addDeclInternal(ToAlias); + return ToD; +} + Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) { // Import the major distinguishing characteristics of this label. DeclContext *DC, *LexicalDC; @@ -1752,6 +1934,31 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { } D2 = D2CXX; D2->setAccess(D->getAccess()); + + Importer.Imported(D, D2); + + if (ClassTemplateDecl *FromDescribed = + DCXX->getDescribedClassTemplate()) { + ClassTemplateDecl *ToDescribed = cast_or_null<ClassTemplateDecl>( + Importer.Import(FromDescribed)); + if (!ToDescribed) + return nullptr; + D2CXX->setDescribedClassTemplate(ToDescribed); + + } else if (MemberSpecializationInfo *MemberInfo = + DCXX->getMemberSpecializationInfo()) { + TemplateSpecializationKind SK = + MemberInfo->getTemplateSpecializationKind(); + CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass(); + CXXRecordDecl *ToInst = + cast_or_null<CXXRecordDecl>(Importer.Import(FromInst)); + if (FromInst && !ToInst) + return nullptr; + D2CXX->setInstantiationOfMemberClass(ToInst, SK); + D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation( + Importer.Import(MemberInfo->getPointOfInstantiation())); + } + } else { D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(), DC, StartLoc, Loc, Name.getAsIdentifierInfo()); @@ -1846,6 +2053,8 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { if (ToD) return ToD; + const FunctionDecl *FoundWithoutBody = nullptr; + // Try to find a function in our own ("to") context with the same name, same // type, and in the same context as the function we're importing. if (!LexicalDC->isFunctionOrMethod()) { @@ -1863,6 +2072,13 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { if (Importer.IsStructurallyEquivalent(D->getType(), FoundFunction->getType())) { // FIXME: Actually try to merge the body and other attributes. + const FunctionDecl *FromBodyDecl = nullptr; + D->hasBody(FromBodyDecl); + if (D == FromBodyDecl && !FoundFunction->hasBody()) { + // This function is needed to merge completely. + FoundWithoutBody = FoundFunction; + break; + } return Importer.Imported(D, FoundFunction); } @@ -2013,6 +2229,12 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { } ToFunction->setParams(Parameters); + if (FoundWithoutBody) { + auto *Recent = const_cast<FunctionDecl *>( + FoundWithoutBody->getMostRecentDecl()); + ToFunction->setPreviousDecl(Recent); + } + if (usedDifferentExceptionSpec) { // Update FunctionProtoType::ExtProtoInfo. QualType T = Importer.Import(D->getType()); @@ -2876,6 +3098,178 @@ Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { return ToLinkageSpec; } +Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD = nullptr; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + DeclarationNameInfo NameInfo(Name, + Importer.Import(D->getNameInfo().getLoc())); + ImportDeclarationNameLoc(D->getNameInfo(), NameInfo); + + UsingDecl *ToUsing = UsingDecl::Create(Importer.getToContext(), DC, + Importer.Import(D->getUsingLoc()), + Importer.Import(D->getQualifierLoc()), + NameInfo, D->hasTypename()); + ToUsing->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToUsing); + Importer.Imported(D, ToUsing); + + if (NamedDecl *FromPattern = + Importer.getFromContext().getInstantiatedFromUsingDecl(D)) { + if (NamedDecl *ToPattern = + dyn_cast_or_null<NamedDecl>(Importer.Import(FromPattern))) + Importer.getToContext().setInstantiatedFromUsingDecl(ToUsing, ToPattern); + else + return nullptr; + } + + for (UsingShadowDecl *FromShadow : D->shadows()) { + if (UsingShadowDecl *ToShadow = + dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromShadow))) + ToUsing->addShadowDecl(ToShadow); + else + // FIXME: We return a nullptr here but the definition is already created + // and available with lookups. How to fix this?.. + return nullptr; + } + return ToUsing; +} + +Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD = nullptr; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + UsingDecl *ToUsing = dyn_cast_or_null<UsingDecl>( + Importer.Import(D->getUsingDecl())); + if (!ToUsing) + return nullptr; + + NamedDecl *ToTarget = dyn_cast_or_null<NamedDecl>( + Importer.Import(D->getTargetDecl())); + if (!ToTarget) + return nullptr; + + UsingShadowDecl *ToShadow = UsingShadowDecl::Create( + Importer.getToContext(), DC, Loc, ToUsing, ToTarget); + + ToShadow->setLexicalDeclContext(LexicalDC); + ToShadow->setAccess(D->getAccess()); + Importer.Imported(D, ToShadow); + + if (UsingShadowDecl *FromPattern = + Importer.getFromContext().getInstantiatedFromUsingShadowDecl(D)) { + if (UsingShadowDecl *ToPattern = + dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromPattern))) + Importer.getToContext().setInstantiatedFromUsingShadowDecl(ToShadow, + ToPattern); + else + // FIXME: We return a nullptr here but the definition is already created + // and available with lookups. How to fix this?.. + return nullptr; + } + + LexicalDC->addDeclInternal(ToShadow); + + return ToShadow; +} + + +Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD = nullptr; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + DeclContext *ToComAncestor = Importer.ImportContext(D->getCommonAncestor()); + if (!ToComAncestor) + return nullptr; + + NamespaceDecl *ToNominated = cast_or_null<NamespaceDecl>( + Importer.Import(D->getNominatedNamespace())); + if (!ToNominated) + return nullptr; + + UsingDirectiveDecl *ToUsingDir = UsingDirectiveDecl::Create( + Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()), + Importer.Import(D->getNamespaceKeyLocation()), + Importer.Import(D->getQualifierLoc()), + Importer.Import(D->getIdentLocation()), ToNominated, ToComAncestor); + ToUsingDir->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToUsingDir); + Importer.Imported(D, ToUsingDir); + + return ToUsingDir; +} + +Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl( + UnresolvedUsingValueDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD = nullptr; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + DeclarationNameInfo NameInfo(Name, Importer.Import(D->getNameInfo().getLoc())); + ImportDeclarationNameLoc(D->getNameInfo(), NameInfo); + + UnresolvedUsingValueDecl *ToUsingValue = UnresolvedUsingValueDecl::Create( + Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()), + Importer.Import(D->getQualifierLoc()), NameInfo, + Importer.Import(D->getEllipsisLoc())); + + Importer.Imported(D, ToUsingValue); + ToUsingValue->setAccess(D->getAccess()); + ToUsingValue->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToUsingValue); + + return ToUsingValue; +} + +Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl( + UnresolvedUsingTypenameDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD = nullptr; + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + if (ToD) + return ToD; + + UnresolvedUsingTypenameDecl *ToUsing = UnresolvedUsingTypenameDecl::Create( + Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()), + Importer.Import(D->getTypenameLoc()), + Importer.Import(D->getQualifierLoc()), Loc, Name, + Importer.Import(D->getEllipsisLoc())); + + Importer.Imported(D, ToUsing); + ToUsing->setAccess(D->getAccess()); + ToUsing->setLexicalDeclContext(LexicalDC); + LexicalDC->addDeclInternal(ToUsing); + + return ToUsing; +} + + bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To, ImportDefinitionKind Kind) { @@ -3453,7 +3847,6 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXRecordDecl *DTemplated = D->getTemplatedDecl(); // Create the declaration that is being templated. - // Create the declaration that is being templated. CXXRecordDecl *D2Templated = cast_or_null<CXXRecordDecl>( Importer.Import(DTemplated)); if (!D2Templated) @@ -3560,11 +3953,10 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl( TemplateArgumentListInfo ToTAInfo; auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten(); for (unsigned I = 0, E = ASTTemplateArgs.NumTemplateArgs; I < E; ++I) { - bool Error = false; - auto ToLoc = ImportTemplateArgumentLoc(ASTTemplateArgs[I], Error); - if (Error) + if (auto ToLoc = ImportTemplateArgumentLoc(ASTTemplateArgs[I])) + ToTAInfo.addArgument(*ToLoc); + else return nullptr; - ToTAInfo.addArgument(ToLoc); } QualType CanonInjType = Importer.Import( @@ -3832,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl( return D2; } +Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD; + + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + return nullptr; + + if (ToD) + return ToD; + + // Try to find a function in our own ("to") context with the same name, same + // type, and in the same context as the function we're importing. + if (!LexicalDC->isFunctionOrMethod()) { + unsigned IDNS = Decl::IDNS_Ordinary; + SmallVector<NamedDecl *, 2> FoundDecls; + DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); + for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { + if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) + continue; + + if (FunctionTemplateDecl *FoundFunction = + dyn_cast<FunctionTemplateDecl>(FoundDecls[I])) { + if (FoundFunction->hasExternalFormalLinkage() && + D->hasExternalFormalLinkage()) { + if (IsStructuralMatch(D, FoundFunction)) { + Importer.Imported(D, FoundFunction); + // FIXME: Actually try to merge the body and other attributes. + return FoundFunction; + } + } + } + } + } + + TemplateParameterList *Params = + ImportTemplateParameterList(D->getTemplateParameters()); + if (!Params) + return nullptr; + + FunctionDecl *TemplatedFD = + cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl())); + if (!TemplatedFD) + return nullptr; + + FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create( + Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD); + + TemplatedFD->setDescribedFunctionTemplate(ToFunc); + ToFunc->setAccess(D->getAccess()); + ToFunc->setLexicalDeclContext(LexicalDC); + Importer.Imported(D, ToFunc); + + LexicalDC->addDeclInternal(ToFunc); + return ToFunc; +} + //---------------------------------------------------------------------------- // Import Statements //---------------------------------------------------------------------------- @@ -3968,12 +4418,16 @@ Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) { Expr *ToRHS = Importer.Import(S->getRHS()); if (!ToRHS && S->getRHS()) return nullptr; + Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); + if (!ToSubStmt && S->getSubStmt()) + return nullptr; SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc()); SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc()); SourceLocation ToColonLoc = Importer.Import(S->getColonLoc()); - return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS, - ToCaseLoc, ToEllipsisLoc, - ToColonLoc); + CaseStmt *ToStmt = new (Importer.getToContext()) + CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc); + ToStmt->setSubStmt(ToSubStmt); + return ToStmt; } Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) { @@ -4443,11 +4897,10 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { TemplateArgumentListInfo *ResInfo = nullptr; if (E->hasExplicitTemplateArgs()) { for (const auto &FromLoc : E->template_arguments()) { - bool Error = false; - TemplateArgumentLoc ToTALoc = ImportTemplateArgumentLoc(FromLoc, Error); - if (Error) + if (auto ToTALoc = ImportTemplateArgumentLoc(FromLoc)) + ToTAInfo.addArgument(*ToTALoc); + else return nullptr; - ToTAInfo.addArgument(ToTALoc); } ResInfo = &ToTAInfo; } @@ -5161,6 +5614,20 @@ ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { return ToMTE; } +Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) + return nullptr; + + Expr *Pattern = Importer.Import(E->getPattern()); + if (!Pattern) + return nullptr; + + return new (Importer.getToContext()) PackExpansionExpr( + T, Pattern, Importer.Import(E->getEllipsisLoc()), + E->getNumExpansions()); +} + Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) { QualType T = Importer.Import(CE->getType()); if (T.isNull()) @@ -5344,6 +5811,80 @@ Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) { E->getObjectKind()); } +Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr( + CXXPseudoDestructorExpr *E) { + + Expr *BaseE = Importer.Import(E->getBase()); + if (!BaseE) + return nullptr; + + TypeSourceInfo *ScopeInfo = Importer.Import(E->getScopeTypeInfo()); + if (!ScopeInfo && E->getScopeTypeInfo()) + return nullptr; + + PseudoDestructorTypeStorage Storage; + if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) { + IdentifierInfo *ToII = Importer.Import(FromII); + if (!ToII) + return nullptr; + Storage = PseudoDestructorTypeStorage( + ToII, Importer.Import(E->getDestroyedTypeLoc())); + } else { + TypeSourceInfo *TI = Importer.Import(E->getDestroyedTypeInfo()); + if (!TI) + return nullptr; + Storage = PseudoDestructorTypeStorage(TI); + } + + return new (Importer.getToContext()) CXXPseudoDestructorExpr( + Importer.getToContext(), BaseE, E->isArrow(), + Importer.Import(E->getOperatorLoc()), + Importer.Import(E->getQualifierLoc()), + ScopeInfo, Importer.Import(E->getColonColonLoc()), + Importer.Import(E->getTildeLoc()), Storage); +} + +Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr( + CXXDependentScopeMemberExpr *E) { + Expr *Base = nullptr; + if (!E->isImplicitAccess()) { + Base = Importer.Import(E->getBase()); + if (!Base) + return nullptr; + } + + QualType BaseType = Importer.Import(E->getBaseType()); + if (BaseType.isNull()) + return nullptr; + + TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()), + Importer.Import(E->getRAngleLoc())); + TemplateArgumentListInfo *ResInfo = nullptr; + if (E->hasExplicitTemplateArgs()) { + if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo)) + return nullptr; + ResInfo = &ToTAInfo; + } + + DeclarationName Name = Importer.Import(E->getMember()); + if (!E->getMember().isEmpty() && Name.isEmpty()) + return nullptr; + + DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E->getMemberLoc())); + // Import additional name location/type info. + ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo); + auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope()); + if (!ToFQ && E->getFirstQualifierFoundInScope()) + return nullptr; + + return CXXDependentScopeMemberExpr::Create( + Importer.getToContext(), Base, BaseType, E->isArrow(), + Importer.Import(E->getOperatorLoc()), + Importer.Import(E->getQualifierLoc()), + Importer.Import(E->getTemplateKeywordLoc()), + cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo); +} + Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5510,6 +6051,26 @@ Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr( Replacement); } +Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) { + QualType ToType = Importer.Import(E->getType()); + if (ToType.isNull()) + return nullptr; + + SmallVector<TypeSourceInfo *, 4> ToArgs(E->getNumArgs()); + if (ImportContainerChecked(E->getArgs(), ToArgs)) + return nullptr; + + // According to Sema::BuildTypeTrait(), if E is value-dependent, + // Value is always false. + bool ToValue = false; + if (!E->isValueDependent()) + ToValue = E->getValue(); + + return TypeTraitExpr::Create( + Importer.getToContext(), ToType, Importer.Import(E->getLocStart()), + E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue); +} + void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod) { for (auto *FromOverriddenMethod : FromMethod->overridden_methods()) |