diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 41 | ||||
-rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 29 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/Mangle.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReader.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHWriter.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 83 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 84 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 51 |
12 files changed, 279 insertions, 49 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a63db14a0f9..94f2fdcff9f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -260,24 +260,40 @@ ASTContext::setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl, } NamedDecl * -ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) { +ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) { llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos - = InstantiatedFromUnresolvedUsingDecl.find(UUD); - if (Pos == InstantiatedFromUnresolvedUsingDecl.end()) + = InstantiatedFromUsingDecl.find(UUD); + if (Pos == InstantiatedFromUsingDecl.end()) return 0; return Pos->second; } void -ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD, - NamedDecl *UUD) { - assert((isa<UnresolvedUsingValueDecl>(UUD) || - isa<UnresolvedUsingTypenameDecl>(UUD)) && - "original declaration is not an unresolved using decl"); - assert(!InstantiatedFromUnresolvedUsingDecl[UD] && - "Already noted what using decl what instantiated from"); - InstantiatedFromUnresolvedUsingDecl[UD] = UUD; +ASTContext::setInstantiatedFromUsingDecl(UsingDecl *Inst, NamedDecl *Pattern) { + assert((isa<UsingDecl>(Pattern) || + isa<UnresolvedUsingValueDecl>(Pattern) || + isa<UnresolvedUsingTypenameDecl>(Pattern)) && + "pattern decl is not a using decl"); + assert(!InstantiatedFromUsingDecl[Inst] && "pattern already exists"); + InstantiatedFromUsingDecl[Inst] = Pattern; +} + +UsingShadowDecl * +ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) { + llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos + = InstantiatedFromUsingShadowDecl.find(Inst); + if (Pos == InstantiatedFromUsingShadowDecl.end()) + return 0; + + return Pos->second; +} + +void +ASTContext::setInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst, + UsingShadowDecl *Pattern) { + assert(!InstantiatedFromUsingShadowDecl[Inst] && "pattern already exists"); + InstantiatedFromUsingShadowDecl[Inst] = Pattern; } FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) { @@ -1766,6 +1782,9 @@ QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) { Decl->TypeForDecl = PrevDecl->TypeForDecl; else Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum); + } else if (UnresolvedUsingTypenameDecl *Using = + dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) { + Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using); } else assert(false && "TypeDecl without a type?"); diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 50a512028e9..3ccb7a9cc61 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -94,3 +94,32 @@ void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) { TypeLocInitializer(Loc).Visit(TL); } while ((TL = TL.getNextTypeLoc())); } + +namespace { + struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> { + // Overload resolution does the real work for us. + static bool isTypeSpec(TypeSpecTypeLoc _) { return true; } + static bool isTypeSpec(TypeLoc _) { return false; } + +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return isTypeSpec(TyLoc); \ + } +#include "clang/AST/TypeLocNodes.def" + }; +} + + +/// \brief Determines if the given type loc corresponds to a +/// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in +/// the type hierarchy, this is made somewhat complicated. +/// +/// There are a lot of types that currently use TypeSpecTypeLoc +/// because it's a convenient base class. Ideally we would not accept +/// those here, but ideally we would have better implementations for +/// them. +bool TypeSpecTypeLoc::classof(const TypeLoc *TL) { + if (TL->getType().hasLocalQualifiers()) return false; + return TSTChecker().Visit(*TL); +} diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 3d7a5376d75..2f58ebed4b9 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -303,6 +303,15 @@ void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, Print(T->getResultType(), S); } +void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T, + std::string &S) { + IdentifierInfo *II = T->getDecl()->getIdentifier(); + if (S.empty()) + S = II->getName().str(); + else + S = II->getName().str() + ' ' + S; +} + void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. S = ' ' + S; diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 4d021e8964c..df708eda9cb 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -843,6 +843,12 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T, // <type> ::= <class-enum-type> // <class-enum-type> ::= <name> +void CXXNameMangler::mangleType(const UnresolvedUsingType *T) { + mangleName(T->getDecl()); +} + +// <type> ::= <class-enum-type> +// <class-enum-type> ::= <name> void CXXNameMangler::mangleType(const EnumType *T) { mangleType(static_cast<const TagType*>(T)); } diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 40eb9ca536d..811f9ed4afb 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -1880,6 +1880,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { Exceptions.data()); } + case pch::TYPE_UNRESOLVED_USING: + return Context->getTypeDeclType( + cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0]))); + case pch::TYPE_TYPEDEF: assert(Record.size() == 1 && "incorrect encoding of typedef type"); return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0]))); @@ -2044,6 +2048,9 @@ void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { VisitFunctionTypeLoc(TL); } +void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index e79f9c9dac1..0e6d1d2f669 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -166,6 +166,14 @@ void PCHTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { Code = pch::TYPE_FUNCTION_PROTO; } +#if 0 +// For when we want it.... +void PCHTypeWriter::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { + Writer.AddDeclRef(T->getDecl(), Record); + Code = pch::TYPE_UNRESOLVED_USING; +} +#endif + void PCHTypeWriter::VisitTypedefType(const TypedefType *T) { Writer.AddDeclRef(T->getDecl(), Record); Code = pch::TYPE_TYPEDEF; @@ -337,6 +345,9 @@ void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { VisitFunctionTypeLoc(TL); } +void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 616151efea3..9606821f78a 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1729,6 +1729,10 @@ public: SourceLocation IdentLoc, IdentifierInfo *Ident); + bool CheckUsingDeclQualifier(SourceLocation UsingLoc, + const CXXScopeSpec &SS, + SourceLocation NameLoc); + NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, const CXXScopeSpec &SS, diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 58b5633afad..992bb80189a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2900,10 +2900,8 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S, TargetName, AttrList, /* IsInstantiation */ false, IsTypeName, TypenameLoc); - if (UD) { - PushOnScopeChains(UD, S); - UD->setAccess(AS); - } + if (UD) + PushOnScopeChains(UD, S, /*AddToContext*/ false); return DeclPtrTy::make(UD); } @@ -2962,19 +2960,33 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, NestedNameSpecifier *NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); + if (CheckUsingDeclQualifier(UsingLoc, SS, IdentLoc)) + return 0; + DeclContext *LookupContext = computeDeclContext(SS); + NamedDecl *D; if (!LookupContext) { if (IsTypeName) { - return UnresolvedUsingTypenameDecl::Create(Context, CurContext, - UsingLoc, TypenameLoc, - SS.getRange(), NNS, - IdentLoc, Name); - } else { - return UnresolvedUsingValueDecl::Create(Context, CurContext, - UsingLoc, SS.getRange(), NNS, + // FIXME: not all declaration name kinds are legal here + D = UnresolvedUsingTypenameDecl::Create(Context, CurContext, + UsingLoc, TypenameLoc, + SS.getRange(), NNS, IdentLoc, Name); + } else { + D = UnresolvedUsingValueDecl::Create(Context, CurContext, + UsingLoc, SS.getRange(), NNS, + IdentLoc, Name); } + } else { + D = UsingDecl::Create(Context, CurContext, IdentLoc, + SS.getRange(), UsingLoc, NNS, Name, + IsTypeName); } + D->setAccess(AS); + CurContext->addDecl(D); + + if (!LookupContext) return D; + UsingDecl *UD = cast<UsingDecl>(D); if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(CurContext)) { // C++0x N2914 [namespace.udecl]p3: @@ -2989,7 +3001,8 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, Diag(SS.getRange().getBegin(), diag::err_using_decl_nested_name_specifier_is_not_a_base_class) << NNS << RD->getDeclName(); - return 0; + UD->setInvalidDecl(); + return UD; } } else { // C++0x N2914 [namespace.udecl]p8: @@ -2997,7 +3010,8 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, if (isa<CXXRecordDecl>(LookupContext)) { Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_class_member) << SS.getRange(); - return 0; + UD->setInvalidDecl(); + return UD; } } @@ -3017,54 +3031,63 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, if (R.empty()) { Diag(IdentLoc, diag::err_no_member) << Name << LookupContext << SS.getRange(); - return 0; + UD->setInvalidDecl(); + return UD; } - if (R.isAmbiguous()) - return 0; + if (R.isAmbiguous()) { + UD->setInvalidDecl(); + return UD; + } if (IsTypeName) { // If we asked for a typename and got a non-type decl, error out. - if (R.getResultKind() != LookupResult::Found - || !isa<TypeDecl>(R.getFoundDecl())) { + if (!R.getAsSingle<TypeDecl>()) { Diag(IdentLoc, diag::err_using_typename_non_type); for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) Diag((*I)->getUnderlyingDecl()->getLocation(), diag::note_using_decl_target); - return 0; + UD->setInvalidDecl(); + return UD; } } else { // If we asked for a non-typename and we got a type, error out, // but only if this is an instantiation of an unresolved using // decl. Otherwise just silently find the type name. - if (IsInstantiation && - R.getResultKind() == LookupResult::Found && - isa<TypeDecl>(R.getFoundDecl())) { + if (IsInstantiation && R.getAsSingle<TypeDecl>()) { Diag(IdentLoc, diag::err_using_dependent_value_is_type); Diag(R.getFoundDecl()->getLocation(), diag::note_using_decl_target); - return 0; + UD->setInvalidDecl(); + return UD; } } // C++0x N2914 [namespace.udecl]p6: // A using-declaration shall not name a namespace. - if (R.getResultKind() == LookupResult::Found - && isa<NamespaceDecl>(R.getFoundDecl())) { + if (R.getAsSingle<NamespaceDecl>()) { Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace) << SS.getRange(); - return 0; + UD->setInvalidDecl(); + return UD; } - UsingDecl *UD = UsingDecl::Create(Context, CurContext, IdentLoc, - SS.getRange(), UsingLoc, NNS, Name, - IsTypeName); - for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) BuildUsingShadowDecl(*this, S, AS, UD, *I); return UD; } +/// Checks that the given nested-name qualifier used in a using decl +/// in the current context is appropriately related to the current +/// scope. If an error is found, diagnoses it and returns true. +bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, + const CXXScopeSpec &SS, + SourceLocation NameLoc) { + // FIXME: implement + + return false; +} + Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, SourceLocation AliasLoc, diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 613ffde5734..b4754db7d6b 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2361,6 +2361,7 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T, case Type::Enum: case Type::ObjCInterface: case Type::ObjCObjectPointer: + case Type::UnresolvedUsing: #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) #define DEPENDENT_TYPE(Class, Base) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 122e85eaa51..6a4ac3c5628 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1064,8 +1064,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, Invalid = true; } else if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) Fields.push_back(DeclPtrTy::make(Field)); - else if (UsingDecl *UD = dyn_cast<UsingDecl>(NewMember)) - Instantiation->addDecl(UD); } else { // FIXME: Eventually, a NULL return will mean that one of the // instantiations was a semantic disaster, and we'll want to set Invalid = diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index ec28f474179..6b41d9a9b2a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -66,6 +66,8 @@ namespace { Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); + Decl *VisitUsingDecl(UsingDecl *D); + Decl *VisitUsingShadowDecl(UsingShadowDecl *D); Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); @@ -1034,6 +1036,56 @@ Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { return Inst; } +Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { + // The nested name specifier is non-dependent, so no transformation + // is required. + + UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner, + D->getLocation(), + D->getNestedNameRange(), + D->getUsingLocation(), + D->getTargetNestedNameDecl(), + D->getDeclName(), + D->isTypeName()); + + CXXScopeSpec SS; + SS.setScopeRep(D->getTargetNestedNameDecl()); + SS.setRange(D->getNestedNameRange()); + if (SemaRef.CheckUsingDeclQualifier(D->getUsingLocation(), SS, + D->getLocation())) + NewUD->setInvalidDecl(); + SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D); + NewUD->setAccess(D->getAccess()); + Owner->addDecl(NewUD); + + // We'll transform the UsingShadowDecls as we reach them. + + return NewUD; +} + +Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) { + UsingDecl *InstUsing = + cast<UsingDecl>(SemaRef.FindInstantiatedDecl(D->getUsingDecl(), + TemplateArgs)); + NamedDecl *InstTarget = + cast<NamedDecl>(SemaRef.FindInstantiatedDecl(D->getTargetDecl(), + TemplateArgs)); + + UsingShadowDecl *InstD = UsingShadowDecl::Create(SemaRef.Context, Owner, + InstUsing->getLocation(), + InstUsing, InstTarget); + InstUsing->addShadowDecl(InstD); + + if (InstTarget->isInvalidDecl() || InstUsing->isInvalidDecl()) + InstD->setInvalidDecl(); + + SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstD, D); + InstD->setAccess(D->getAccess()); + Owner->addDecl(InstD); + + return InstD; +} + Decl * TemplateDeclInstantiator ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { NestedNameSpecifier *NNS = @@ -1054,8 +1106,8 @@ Decl * TemplateDeclInstantiator /*instantiation*/ true, /*typename*/ true, D->getTypenameLoc()); if (UD) - SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD), - D); + SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D); + return UD; } @@ -1079,8 +1131,8 @@ Decl * TemplateDeclInstantiator /*instantiation*/ true, /*typename*/ false, SourceLocation()); if (UD) - SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD), - D); + SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D); + return UD; } @@ -1753,16 +1805,28 @@ static bool isInstantiationOf(EnumDecl *Pattern, return false; } +static bool isInstantiationOf(UsingShadowDecl *Pattern, + UsingShadowDecl *Instance, + ASTContext &C) { + return C.getInstantiatedFromUsingShadowDecl(Instance) == Pattern; +} + +static bool isInstantiationOf(UsingDecl *Pattern, + UsingDecl *Instance, + ASTContext &C) { + return C.getInstantiatedFromUsingDecl(Instance) == Pattern; +} + static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern, UsingDecl *Instance, ASTContext &C) { - return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern; + return C.getInstantiatedFromUsingDecl(Instance) == Pattern; } static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern, UsingDecl *Instance, ASTContext &C) { - return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern; + return C.getInstantiatedFromUsingDecl(Instance) == Pattern; } static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, @@ -1780,6 +1844,8 @@ static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, return false; } +// Other is the prospective instantiation +// D is the prospective pattern static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { if (D->getKind() != Other->getKind()) { if (UnresolvedUsingTypenameDecl *UUD @@ -1831,6 +1897,12 @@ static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { } } + if (UsingDecl *Using = dyn_cast<UsingDecl>(Other)) + return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx); + + if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(Other)) + return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx); + return D->getDeclName() && isa<NamedDecl>(Other) && D->getDeclName() == cast<NamedDecl>(Other)->getDeclName(); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index e1ac3225d2d..b029a379671 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -461,6 +461,10 @@ public: /// \brief Build a new unprototyped function type. QualType RebuildFunctionNoProtoType(QualType ResultType); + /// \brief Rebuild an unresolved typename type, given the decl that + /// the UnresolvedUsingTypenameDecl was transformed to. + QualType RebuildUnresolvedUsingType(Decl *D); + /// \brief Build a new typedef type. QualType RebuildTypedefType(TypedefDecl *Typedef) { return SemaRef.Context.getTypeDeclType(Typedef); @@ -2578,6 +2582,29 @@ QualType TreeTransform<Derived>::TransformFunctionNoProtoType( return Result; } +template<typename Derived> QualType +TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB, + UnresolvedUsingTypeLoc TL) { + UnresolvedUsingType *T = TL.getTypePtr(); + Decl *D = getDerived().TransformDecl(T->getDecl()); + if (!D) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || D != T->getDecl()) { + Result = getDerived().RebuildUnresolvedUsingType(D); + if (Result.isNull()) + return QualType(); + } + + // We might get an arbitrary type spec type back. We should at + // least always get a type spec type, though. + TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result); + NewTL.setNameLoc(TL.getNameLoc()); + + return Result; +} + template<typename Derived> QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) { @@ -5318,6 +5345,30 @@ QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) { } template<typename Derived> +QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) { + assert(D && "no decl found"); + if (D->isInvalidDecl()) return QualType(); + + TypeDecl *Ty; + if (isa<UsingDecl>(D)) { + UsingDecl *Using = cast<UsingDecl>(D); + assert(Using->isTypeName() && + "UnresolvedUsingTypenameDecl transformed to non-typename using"); + + // A valid resolved using typename decl points to exactly one type decl. + assert(++Using->shadow_begin() == Using->shadow_end()); + Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl()); + + } else { + assert(isa<UnresolvedUsingTypenameDecl>(D) && + "UnresolvedUsingTypenameDecl transformed to non-using decl"); + Ty = cast<UnresolvedUsingTypenameDecl>(D); + } + + return SemaRef.Context.getTypeDeclType(Ty); +} + +template<typename Derived> QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) { return SemaRef.BuildTypeofExprType(E.takeAs<Expr>()); } |