// 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; } }
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) { }
bool RemoveNamespaceRewriteVisitor::VisitUsingDecl(UsingDecl *D) { if (ConsumerInstance->isForUsingNamedDecls) return true; if (ConsumerInstance->UselessUsingDecls.count(D)) { ConsumerInstance->RewriteHelper->removeDecl(D); return true; } // check if this UsingDecl refers to the namespaced being removed NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); TransAssert(QualifierLoc && "Bad QualifierLoc!"); NestedNameSpecifierLoc PrefixLoc = QualifierLoc.getPrefix(); const NestedNameSpecifier *NNS = D->getQualifier(); TransAssert(NNS && "Bad NameSpecifier!"); if (ConsumerInstance->isTheNamespaceSpecifier(NNS) && (!PrefixLoc || ConsumerInstance->isGlobalNamespace(PrefixLoc))) { ConsumerInstance->RewriteHelper->removeDecl(D); SkipTraverseNestedNameSpecifier = true; } return true; }
bool RemoveNamespaceRewriteVisitor::VisitNamespaceAliasDecl( NamespaceAliasDecl *D) { if (ConsumerInstance->isForUsingNamedDecls) return true; const NamespaceDecl *CanonicalND = D->getNamespace()->getCanonicalDecl(); if (D->getQualifier()) { TraverseNestedNameSpecifierLoc(D->getQualifierLoc()); if (CanonicalND == ConsumerInstance->TheNamespaceDecl) { NestedNameSpecifierLoc QualLoc = D->getQualifierLoc(); SourceLocation QualEndLoc = QualLoc.getEndLoc(); SourceLocation DeclEndLoc = D->getSourceRange().getEnd(); ConsumerInstance->TheRewriter.RemoveText( SourceRange(QualEndLoc, DeclEndLoc)); } } else { if (CanonicalND == ConsumerInstance->TheNamespaceDecl) ConsumerInstance->RewriteHelper->removeDecl(D); } return true; }
void RewriteUtils::getQualifierAsString(NestedNameSpecifierLoc Loc, std::string &Str) { SourceLocation StartLoc = Loc.getBeginLoc(); TransAssert(StartLoc.isValid() && "Bad StartLoc for NestedNameSpecifier!"); SourceRange Range = Loc.getSourceRange(); int Len = TheRewriter->getRangeSize(Range); const char *StartBuf = SrcManager->getCharacterData(StartLoc); Str.assign(StartBuf, Len); }
SourceRange NestedNameSpecifierLoc::getSourceRange() const { if (!Qualifier) return SourceRange(); NestedNameSpecifierLoc First = *this; while (NestedNameSpecifierLoc Prefix = First.getPrefix()) First = Prefix; return SourceRange(First.getLocalSourceRange().getBegin(), getLocalSourceRange().getEnd()); }
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; } }
bool RewriteUtils::removeSpecifier(NestedNameSpecifierLoc Loc) { SourceRange LocRange = Loc.getLocalSourceRange(); TransAssert((TheRewriter->getRangeSize(LocRange) != -1) && "Bad NestedNameSpecifierLoc Range!"); return !(TheRewriter->RemoveText(LocRange)); }
bool RewriteUtils::replaceSpecifier(NestedNameSpecifierLoc Loc, const std::string &Name) { SourceRange LocRange = Loc.getLocalSourceRange(); TransAssert((TheRewriter->getRangeSize(LocRange) != -1) && "Bad NestedNameSpecifierLoc Range!"); return !(TheRewriter->ReplaceText(LocRange, Name + "::")); }
// 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; }
void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) { if (!Other) { Range = SourceRange(); Builder.Clear(); return; } Range = Other.getSourceRange(); Builder.Adopt(Other); }
// Handle cases like: // struct S { // typedef int Int; // }; // S::Int g; // where S::Int is referred as an ElaboratedType bool ReplaceSimpleTypedefRewriteVisitor::VisitElaboratedTypeLoc( ElaboratedTypeLoc Loc) { const ElaboratedType *ETy = dyn_cast<ElaboratedType>(Loc.getTypePtr()); const Type *NamedTy = ETy->getNamedType().getTypePtr(); const TypedefType *TdefTy = NamedTy->getAs<TypedefType>(); if (!TdefTy) return true; const TypedefDecl *TdefD = dyn_cast<TypedefDecl>(TdefTy->getDecl()); if (!TdefD || (dyn_cast<TypedefDecl>(TdefD->getCanonicalDecl()) != ConsumerInstance->TheTypedefDecl)) { return true; } NestedNameSpecifierLoc QualifierLoc = Loc.getQualifierLoc(); if (QualifierLoc && ConsumerInstance->IsScalarType) { ConsumerInstance->TheRewriter.RemoveText(QualifierLoc.getSourceRange()); } return true; }
bool VisitCallExpr(CallExpr *E) { llvm::errs() << "I see a CallExpr\n"; E->dump(); Expr *callee = E->getCallee(); if (ImplicitCastExpr *ica = llvm::dyn_cast<ImplicitCastExpr>(callee)) { callee = ica->getSubExpr(); } if (DeclRefExpr *dref = llvm::dyn_cast<DeclRefExpr>(callee)) { llvm::errs() << "declref:\n"; dref->dump(); NamedDecl *d = dref->getFoundDecl(); ASTContext &Context = d->getASTContext(); SourceManager &SM = Context.getSourceManager(); if (dref->hasQualifier()) { llvm::errs() << " has qualifier in name.\n"; NestedNameSpecifierLoc lc = dref->getQualifierLoc(); llvm::errs() << " begin loc: " << lc.getBeginLoc().printToString(SM) << "\n"; llvm::errs() << " end loc: " << lc.getEndLoc().printToString(SM) << "\n"; } if (UsingShadowDecl *sh = llvm::dyn_cast<UsingShadowDecl>(d)) { NamedDecl *td = sh->getTargetDecl(); FoundRealDecl(td); //d->dump(); } else { FoundRealDecl(d); //d->dump(); } } else if (UnresolvedLookupExpr *ule = dyn_cast<UnresolvedLookupExpr>(callee)) { llvm::errs() << "unresolved\n"; ASTContext* Context; SourceManager* SM; for (const auto *d : ule->decls()) { FoundRealDecl(d); Context = &d->getASTContext(); SM = &Context->getSourceManager(); } llvm::errs() << " begin loc: " << ule->getLocStart().printToString(*SM) << "\n"; llvm::errs() << " end loc: " << ule->getLocEnd().printToString(*SM) << "\n"; NestedNameSpecifierLoc ll = ule->getQualifierLoc(); llvm::errs() << " nested begin loc: " << ll.getBeginLoc().printToString(*SM) << "\n"; llvm::errs() << " nested end loc: " << ll.getEndLoc().printToString(*SM) << "\n"; } return true; }
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; } }
void RewriteUtils::getSpecifierAsString(NestedNameSpecifierLoc Loc, std::string &Str) { SourceLocation StartLoc = Loc.getBeginLoc(); TransAssert(StartLoc.isValid() && "Bad StartLoc for NestedNameSpecifier!"); const char *StartBuf = SrcManager->getCharacterData(StartLoc); const char *OrigBuf = StartBuf; unsigned int Len = 0; while (!isspace(*StartBuf) && (*StartBuf != ':')) { StartBuf++; Len++; } Str.assign(OrigBuf, Len); }
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) { }
SourceLocation ReplaceDependentName::getElaboratedTypeLocBegin( const ElaboratedTypeLoc &TLoc) { SourceLocation Loc = TLoc.getElaboratedKeywordLoc(); if (Loc.isValid()) return Loc; NestedNameSpecifierLoc SpecLoc = TLoc.getQualifierLoc(); NestedNameSpecifierLoc Prefix = SpecLoc.getPrefix(); while (Prefix.getBeginLoc().isValid()) { SpecLoc = Prefix; Prefix = Prefix.getPrefix(); } Loc = SpecLoc.getBeginLoc(); TransAssert(Loc.isValid() && "Failed to get ElaboratedTypeLoc!"); return Loc; }
// 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; }
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); }
bool RemoveNamespace::isGlobalNamespace(NestedNameSpecifierLoc Loc) { NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier(); return (NNS->getKind() == NestedNameSpecifier::Global); }