// DependentScopeDeclRefExpr DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, true, true, (NameInfo.isInstantiationDependent() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))), QualifierLoc(QualifierLoc), NameInfo(NameInfo), HasExplicitTemplateArgs(Args != 0) { if (Args) { bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = ExprBits.ContainsUnexpandedParameterPack; reinterpret_cast<ASTTemplateArgumentListInfo*>(this+1) ->initializeFrom(*Args, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; } }
void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC) { if (!NNS) return; if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) indexNestedNameSpecifierLoc(Prefix, Parent, DC); if (!DC) DC = Parent->getLexicalDeclContext(); SourceLocation Loc = NNS.getSourceRange().getBegin(); switch (NNS.getNestedNameSpecifier()->getKind()) { case NestedNameSpecifier::Identifier: case NestedNameSpecifier::Global: case NestedNameSpecifier::Super: break; case NestedNameSpecifier::Namespace: handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(), Loc, Parent, DC, SymbolRoleSet()); break; case NestedNameSpecifier::NamespaceAlias: handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Loc, Parent, DC, SymbolRoleSet()); break; case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: indexTypeLoc(NNS.getTypeLoc(), Parent, DC); break; } }
CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context, Expr *Base, bool isArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, TypeSourceInfo *ScopeType, SourceLocation ColonColonLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage DestroyedType) : Expr(CXXPseudoDestructorExprClass, Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0, FunctionProtoType::ExtProtoInfo())), VK_RValue, OK_Ordinary, /*isTypeDependent=*/(Base->isTypeDependent() || (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), /*isValueDependent=*/Base->isValueDependent(), (Base->isInstantiationDependent() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) || (ScopeType && ScopeType->getType()->isInstantiationDependentType()) || (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType() ->isInstantiationDependentType())), // ContainsUnexpandedParameterPack (Base->containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()) || (ScopeType && ScopeType->getType()->containsUnexpandedParameterPack()) || (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType() ->containsUnexpandedParameterPack()))), Base(static_cast<Stmt *>(Base)), IsArrow(isArrow), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc), DestroyedType(DestroyedType) { }
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()) || MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(TemplateArgs != 0), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { if (TemplateArgs) { bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } }
// A using declaration in the removed namespace could cause // name conflict, e.g., // namespace NS1 { // void foo(void) {} // } // namespace NS2 { // using NS1::foo; // void bar() { ... foo(); ... } // } // void foo() {...} // void func() {... foo(); ...} // if we remove NS2, then foo() in func() will become ambiguous. // In this case, we need to replace the first invocation of foo() // with NS1::foo() void RemoveNamespace::handleOneUsingShadowDecl(const UsingShadowDecl *UD, const DeclContext *ParentCtx) { const NamedDecl *ND = UD->getTargetDecl(); if (!hasNameConflict(ND, ParentCtx)) return; std::string NewName; const UsingDecl *D = UD->getUsingDecl(); NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); NestedNameSpecifier *NNS = QualifierLoc.getNestedNameSpecifier(); // QualifierLoc could be ::foo, whose PrefixLoc is invalid, e.g., // void foo(); // namespace NS2 { // using ::foo; // void bar () { foo(); } // } if (NNS->getKind() != NestedNameSpecifier::Global) { // NestedNameSpecifierLoc PrefixLoc = QualifierLoc.getPrefix(); RewriteHelper->getQualifierAsString(QualifierLoc, NewName); } if ( const TemplateDecl *TD = dyn_cast<TemplateDecl>(ND) ) { ND = TD->getTemplatedDecl(); } // NewName += "::"; const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); if (FD && FD->isOverloadedOperator()) { const char *Op = clang::getOperatorSpelling(FD->getOverloadedOperator()); std::string OpStr(Op); NewName += ("operator::" + OpStr); } else { const IdentifierInfo *IdInfo = ND->getIdentifier(); TransAssert(IdInfo && "Invalid IdentifierInfo!"); NewName += IdInfo->getName(); } UsingNamedDeclToNewName[ND] = NewName; // the tied UsingDecl becomes useless, and hence it's removable UselessUsingDecls.insert(D); }
void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) { if (BufferCapacity) free(Buffer); if (!Other) { Representation = 0; BufferSize = 0; return; } // Rather than copying the data (which is wasteful), "adopt" the // pointer (which points into the ASTContext) but set the capacity to zero to // indicate that we don't own it. Representation = Other.getNestedNameSpecifier(); Buffer = static_cast<char *>(Other.getOpaqueData()); BufferSize = Other.getDataLength(); BufferCapacity = 0; }
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()-> containsUnexpandedParameterPack()) || MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { }
// fix the "B" part of names like A::B::C if B is our target void TypeRenameTransform::processQualifierLoc(NestedNameSpecifierLoc NNSL, bool forceRewriteMacro) { while (NNSL) { auto NNS = NNSL.getNestedNameSpecifier(); auto NNSK = NNS->getKind(); if (NNSK == NestedNameSpecifier::TypeSpec || NNSK == NestedNameSpecifier::TypeSpecWithTemplate) { processTypeLoc(NNSL.getTypeLoc(), forceRewriteMacro); } else if (NNSK == NestedNameSpecifier::Namespace) { std::string newName; if (nameMatches(NNS->getAsNamespace(), newName, true)) { renameLocation(NNSL.getLocalBeginLoc(), newName); } processTypeLoc(NNSL.getTypeLoc(), forceRewriteMacro); } else if (NNSK == NestedNameSpecifier::NamespaceAlias) { std::string newName; if (nameMatches(NNS->getAsNamespaceAlias(), newName, true)) { renameLocation(NNSL.getLocalBeginLoc(), newName); } processTypeLoc(NNSL.getTypeLoc(), forceRewriteMacro); } // else { // auto srcrange = NNSL.getSourceRange(); // llvm::errs() << indent() // << "==> ??? (" << ii << ") " // << " range=[" << range(srcrange) // << "\n"; // break; // } NNSL = NNSL.getPrefix(); } }
// It handles two cases: // * remove the specifier if it refers to TheNamespaceDecl // * replace the specifier with a new name if the corresponding namespace // has a name conflicts, e.g., // namespace NS1 { } // namespace NS2 { // namespace NS1 { // void foo() {} // } // namespace NS3 { // using NS1::foo; // void bar() { foo(); } // } // } // If we remove NS2, then the inner namespace NS1 conflicts with // the global NS1, but "using NS1::foo" refers to the conflicting NS1. bool RemoveNamespaceRewriteVisitor::TraverseNestedNameSpecifierLoc( NestedNameSpecifierLoc QualifierLoc) { SkipRewriteName = false; // Reset the flag if (SkipTraverseNestedNameSpecifier) { SkipTraverseNestedNameSpecifier = false; return true; } if (!QualifierLoc || QualifierLoc.getBeginLoc().isInvalid()) return true; SmallVector<NestedNameSpecifierLoc, 8> QualifierLocs; for (; QualifierLoc; QualifierLoc = QualifierLoc.getPrefix()) QualifierLocs.push_back(QualifierLoc); while (!QualifierLocs.empty()) { NestedNameSpecifierLoc Loc = QualifierLocs.pop_back_val(); NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier(); NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); const NamespaceDecl *ND = NULL; switch (Kind) { case NestedNameSpecifier::Namespace: { ND = NNS->getAsNamespace()->getCanonicalDecl(); break; } case NestedNameSpecifier::NamespaceAlias: { const NamespaceAliasDecl *NAD = NNS->getAsNamespaceAlias(); if (!NAD->getQualifier()) ND = NAD->getNamespace()->getCanonicalDecl(); break; } case NestedNameSpecifier::TypeSpec: // Fall-through case NestedNameSpecifier::TypeSpecWithTemplate: TraverseTypeLoc(Loc.getTypeLoc()); break; default: break; } if (!ND) continue; if (ND == ConsumerInstance->TheNamespaceDecl) { ConsumerInstance->RewriteHelper->removeSpecifier(Loc); continue; } std::string SpecifierName; if (Loc.getBeginLoc().isInvalid()) continue; ConsumerInstance->RewriteHelper->getSpecifierAsString(Loc, SpecifierName); std::string NDName = ND->getNameAsString(); std::string Name = ""; ConsumerInstance->getNewName(ND, Name); // Skip it if this specifier is the same as ND's name. // Note that the above case could only happen for UsingNamedDecls if (ConsumerInstance->isForUsingNamedDecls && (SpecifierName == NDName)) { // It could happen for example: // namespace NS1 { } // namespace NS2 { // using namespace NS1; // void bar() { NS1::foo(); } // } // If we remove NS2, then the guard below avoids renaming // NS1::foo to NS1::foo::foo. if (Name.empty()) { SkipRewriteName = true; return true; } // another case to handle: // namespace NS1 { // namespace NS2 { // void foo() {} // } // } // namespace NS3 { // using namespace NS1; // void bar() { NS2::foo(); } // } // If we remove NS3, we do need to rename NS2::foo as NS1::NS2::foo if (!ConsumerInstance->isSuffix(Name, SpecifierName)) { SkipRewriteName = true; return true; } } if (!Name.empty()) { ConsumerInstance->RewriteHelper->replaceSpecifier(Loc, Name); SkipRewriteName = true; return true; } } return true; }
bool RemoveNamespace::isGlobalNamespace(NestedNameSpecifierLoc Loc) { NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier(); return (NNS->getKind() == NestedNameSpecifier::Global); }
OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent, bool KnownContainsUnexpandedParameterPack) : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, KnownDependent, (KnownInstantiationDependent || NameInfo.isInstantiationDependent() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (KnownContainsUnexpandedParameterPack || NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))), Results(0), NumResults(End - Begin), NameInfo(NameInfo), QualifierLoc(QualifierLoc), HasExplicitTemplateArgs(TemplateArgs != 0) { NumResults = End - Begin; if (NumResults) { // Determine whether this expression is type-dependent. for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) { if ((*I)->getDeclContext()->isDependentContext() || isa<UnresolvedUsingValueDecl>(*I)) { ExprBits.TypeDependent = true; ExprBits.ValueDependent = true; } } Results = static_cast<DeclAccessPair *>( C.Allocate(sizeof(DeclAccessPair) * NumResults, llvm::alignOf<DeclAccessPair>())); memcpy(Results, &*Begin.getIterator(), NumResults * sizeof(DeclAccessPair)); } // If we have explicit template arguments, check for dependent // template arguments and whether they contain any unexpanded pack // expansions. if (TemplateArgs) { bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (Dependent) { ExprBits.TypeDependent = true; ExprBits.ValueDependent = true; } if (InstantiationDependent) ExprBits.InstantiationDependent = true; if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } if (isTypeDependent()) setType(C.DependentTy); }