/// Returns true if the given C++ class is a container. /// /// Our heuristic for this is whether it contains a method named 'begin()' or a /// nested type named 'iterator'. static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) { // Don't record any path information. CXXBasePaths Paths(false, false, false); const IdentifierInfo &BeginII = Ctx.Idents.get("begin"); DeclarationName BeginName = Ctx.DeclarationNames.getIdentifier(&BeginII); DeclContext::lookup_const_result BeginDecls = RD->lookup(BeginName); if (!BeginDecls.empty()) return true; if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember, BeginName.getAsOpaquePtr(), Paths)) return true; const IdentifierInfo &IterII = Ctx.Idents.get("iterator"); DeclarationName IteratorName = Ctx.DeclarationNames.getIdentifier(&IterII); DeclContext::lookup_const_result IterDecls = RD->lookup(IteratorName); if (!IterDecls.empty()) return true; if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember, IteratorName.getAsOpaquePtr(), Paths)) return true; return false; }
bool GetFields( RecordDecl * rd, Obj * entries) { //check the fields of this struct, if any one of them is not understandable, then this struct becomes 'opaque' //that is, we insert the type, and link it to its llvm type, so it can be used in terra code //but none of its fields are exposed (since we don't understand the layout) bool opaque = false; for(RecordDecl::field_iterator it = rd->field_begin(), end = rd->field_end(); it != end; ++it) { if(it->isBitField() || it->isAnonymousStructOrUnion() || !it->getDeclName()) { opaque = true; continue; } DeclarationName declname = it->getDeclName(); std::string declstr = declname.getAsString(); QualType FT = it->getType(); Obj fobj; if(!GetType(FT,&fobj)) { opaque = true; continue; } lua_newtable(L); fobj.push(); lua_setfield(L,-2,"type"); lua_pushstring(L,declstr.c_str()); lua_setfield(L,-2,"field"); entries->addentry(); } return !opaque; }
bool TraverseFunctionDecl(FunctionDecl *f) { // Function name DeclarationName DeclName = f->getNameInfo().getName(); std::string FuncName = DeclName.getAsString(); const FunctionType * fntyp = f->getType()->getAs<FunctionType>(); if(!fntyp) return true; if(f->getStorageClass() == clang::SC_Static) { ImportError("cannot import static functions."); SetErrorReport(FuncName.c_str()); return true; } Obj typ; if(!GetFuncType(fntyp,&typ)) { SetErrorReport(FuncName.c_str()); return true; } std::string InternalName = FuncName; AsmLabelAttr * asmlabel = f->getAttr<AsmLabelAttr>(); if(asmlabel) { InternalName = asmlabel->getLabel(); #ifndef __linux__ //In OSX and Windows LLVM mangles assembler labels by adding a '\01' prefix InternalName.insert(InternalName.begin(), '\01'); #endif } CreateFunction(FuncName,InternalName,&typ); KeepFunctionLive(f);//make sure this function is live in codegen by creating a dummy reference to it (void) is to suppress unused warnings return true; }
bool VisitFunctionDecl(FunctionDecl *f) { // Only function definitions (with bodies), not declarations. if (f->hasBody()) { Stmt *FuncBody = f->getBody(); // Type name as string QualType QT = f->getResultType(); string TypeStr = QT.getAsString(); // Function name DeclarationName DeclName = f->getNameInfo().getName(); string FuncName = DeclName.getAsString(); // Add comment before stringstream SSBefore; SSBefore << "// Begin function " << FuncName << " returning " << TypeStr << "\n"; SourceLocation ST = f->getSourceRange().getBegin(); TheRewriter.InsertText(ST, SSBefore.str(), true, true); // And after stringstream SSAfter; SSAfter << "\n// End function " << FuncName << "\n"; ST = FuncBody->getLocEnd().getLocWithOffset(1); TheRewriter.InsertText(ST, SSAfter.str(), true, true); } return true; }
void RemoveUnusedFunction::handleOneCXXDependentScopeMemberExpr( const FunctionDecl *CurrentFD, const CXXDependentScopeMemberExpr *E) { if (E->isImplicitAccess()) return; DeclarationName DName = E->getMember(); DeclarationName::NameKind K = DName.getNameKind(); if ((K != DeclarationName::CXXOperatorName) && (K != DeclarationName::Identifier)) return; const Expr *Base = E->getBase()->IgnoreParenCasts(); const FunctionDecl *FD = NULL; if (dyn_cast<CXXThisExpr>(Base)) { TransAssert(CurrentFD && "NULL CurrentFD"); const DeclContext *Ctx = CurrentFD->getLookupParent(); TransAssert(Ctx && "Bad DeclContext!"); DeclContextSet VisitedCtxs; FD = lookupFunctionDecl(DName, Ctx, VisitedCtxs); // we may not get FD in cases where we have this->m_field if (FD) addOneReferencedFunction(FD); return; } }
/// AddDecl - Link the decl to its shadowed decl chain. void IdentifierResolver::AddDecl(NamedDecl *D) { DeclarationName Name = D->getDeclName(); if (IdentifierInfo *II = Name.getAsIdentifierInfo()) { updatingIdentifier(*II); //@@ if (II->isMetaGenerated()) return; //@@ } void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) { Name.setFETokenInfo(D); return; } IdDeclInfo *IDI; if (isDeclPtr(Ptr)) { Name.setFETokenInfo(nullptr); IDI = &(*IdDeclInfos)[Name]; NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); IDI->AddDecl(PrevD); } else IDI = toIdDeclInfo(Ptr); IDI->AddDecl(D); }
bool operator<(DeclarationName LHS, DeclarationName RHS) { if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo()) if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo()) return strcmp(LhsId->getName(), RhsId->getName()) < 0; return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger(); }
/// \brief Retrieve the name that should be used to order a result. /// /// If the name needs to be constructed as a string, that string will be /// saved into Saved and the returned StringRef will refer to it. static StringRef getOrderedName(const CodeCompletionResult &R, std::string &Saved) { switch (R.Kind) { case CodeCompletionResult::RK_Keyword: return R.Keyword; case CodeCompletionResult::RK_Pattern: return R.Pattern->getTypedText(); case CodeCompletionResult::RK_Macro: return R.Macro->getName(); case CodeCompletionResult::RK_Declaration: // Handle declarations below. break; } DeclarationName Name = R.Declaration->getDeclName(); // If the name is a simple identifier (by far the common case), or a // zero-argument selector, just return a reference to that identifier. if (IdentifierInfo *Id = Name.getAsIdentifierInfo()) return Id->getName(); if (Name.isObjCZeroArgSelector()) if (IdentifierInfo *Id = Name.getObjCSelector().getIdentifierInfoForSlot(0)) return Id->getName(); Saved = Name.getAsString(); return Saved; }
bool DynamicIDHandler::LookupUnqualified(LookupResult& R, Scope* S) { if (!IsDynamicLookup(R, S)) return false; if (Callbacks && Callbacks->isEnabled()) { return Callbacks->LookupObject(R, S); } DeclarationName Name = R.getLookupName(); IdentifierInfo* II = Name.getAsIdentifierInfo(); SourceLocation Loc = R.getNameLoc(); VarDecl* Result = VarDecl::Create(m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, II, m_Context.DependentTy, /*TypeSourceInfo*/0, SC_None, SC_None); if (Result) { R.addDecl(Result); // Say that we can handle the situation. Clang should try to recover return true; } // We cannot handle the situation. Give up return false; }
void ODRHash::AddDeclarationName(DeclarationName Name) { // Index all DeclarationName and use index numbers to refer to them. auto Result = DeclNameMap.insert(std::make_pair(Name, DeclNameMap.size())); ID.AddInteger(Result.first->second); if (!Result.second) { // If found in map, the the DeclarationName has previously been processed. return; } // First time processing each DeclarationName, also process its details. AddBoolean(Name.isEmpty()); if (Name.isEmpty()) return; auto Kind = Name.getNameKind(); ID.AddInteger(Kind); switch (Kind) { case DeclarationName::Identifier: AddIdentifierInfo(Name.getAsIdentifierInfo()); break; case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: { Selector S = Name.getObjCSelector(); AddBoolean(S.isNull()); AddBoolean(S.isKeywordSelector()); AddBoolean(S.isUnarySelector()); unsigned NumArgs = S.getNumArgs(); for (unsigned i = 0; i < NumArgs; ++i) { AddIdentifierInfo(S.getIdentifierInfoForSlot(i)); } break; } case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: AddQualType(Name.getCXXNameType()); break; case DeclarationName::CXXOperatorName: ID.AddInteger(Name.getCXXOverloadedOperator()); break; case DeclarationName::CXXLiteralOperatorName: AddIdentifierInfo(Name.getCXXLiteralIdentifier()); break; case DeclarationName::CXXConversionFunctionName: AddQualType(Name.getCXXNameType()); break; case DeclarationName::CXXUsingDirective: break; case DeclarationName::CXXDeductionGuideName: { auto *Template = Name.getCXXDeductionGuideTemplate(); AddBoolean(Template); if (Template) { AddDecl(Template); } } } }
/// Returns true if the given C++ class contains a member with the given name. static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD, StringRef Name) { const IdentifierInfo &II = Ctx.Idents.get(Name); DeclarationName DeclName = Ctx.DeclarationNames.getIdentifier(&II); if (!RD->lookup(DeclName).empty()) return true; CXXBasePaths Paths(false, false, false); if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember, DeclName.getAsOpaquePtr(), Paths)) return true; return false; }
/// RemoveDecl - Unlink the decl from its shadowed decl chain. /// The decl must already be part of the decl chain. void IdentifierResolver::RemoveDecl(NamedDecl *D) { assert(D && "null param passed"); DeclarationName Name = D->getDeclName(); void *Ptr = Name.getFETokenInfo<void>(); assert(Ptr && "Didn't find this decl on its identifier's chain!"); if (isDeclPtr(Ptr)) { assert(D == Ptr && "Didn't find this decl on its identifier's chain!"); Name.setFETokenInfo(NULL); return; } return toIdDeclInfo(Ptr)->RemoveDecl(D); }
void ODRHash::AddDeclarationName(DeclarationName Name) { AddBoolean(Name.isEmpty()); if (Name.isEmpty()) return; auto Kind = Name.getNameKind(); ID.AddInteger(Kind); switch (Kind) { case DeclarationName::Identifier: AddIdentifierInfo(Name.getAsIdentifierInfo()); break; case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: { Selector S = Name.getObjCSelector(); AddBoolean(S.isNull()); AddBoolean(S.isKeywordSelector()); AddBoolean(S.isUnarySelector()); unsigned NumArgs = S.getNumArgs(); for (unsigned i = 0; i < NumArgs; ++i) { AddIdentifierInfo(S.getIdentifierInfoForSlot(i)); } break; } case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: AddQualType(Name.getCXXNameType()); break; case DeclarationName::CXXOperatorName: ID.AddInteger(Name.getCXXOverloadedOperator()); break; case DeclarationName::CXXLiteralOperatorName: AddIdentifierInfo(Name.getCXXLiteralIdentifier()); break; case DeclarationName::CXXConversionFunctionName: AddQualType(Name.getCXXNameType()); break; case DeclarationName::CXXUsingDirective: break; case DeclarationName::CXXDeductionGuideName: { auto *Template = Name.getCXXDeductionGuideTemplate(); AddBoolean(Template); if (Template) { AddDecl(Template); } } } }
DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { switch (Name.getNameKind()) { case DeclarationName::Identifier: break; case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: case DeclarationName::CXXConversionFunctionName: NamedType.TInfo = nullptr; break; case DeclarationName::CXXOperatorName: CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); break; case DeclarationName::CXXLiteralOperatorName: CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); break; case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: // FIXME: ? break; case DeclarationName::CXXUsingDirective: break; } }
bool index::printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS) { if (auto *ND = dyn_cast<NamedDecl>(D)) { PrintingPolicy Policy(LO); // Forward references can have different template argument names. Suppress // the template argument names in constructors to make their name more // stable. Policy.SuppressTemplateArgsInCXXConstructors = true; DeclarationName DeclName = ND->getDeclName(); if (DeclName.isEmpty()) return true; DeclName.print(OS, Policy); return false; } else { return true; } }
bool SymbolResolverCallback::LookupObject(LookupResult& R, Scope* S) { if (!ShouldResolveAtRuntime(R, S)) return false; if (m_IsRuntime) { // We are currently parsing an EvaluateT() expression if (!m_Resolve) return false; // Only for demo resolve all unknown objects to cling::test::Tester if (!m_TesterDecl) { clang::Sema& SemaR = m_Interpreter->getSema(); clang::NamespaceDecl* NSD = utils::Lookup::Namespace(&SemaR, "cling"); NSD = utils::Lookup::Namespace(&SemaR, "test", NSD); m_TesterDecl = utils::Lookup::Named(&SemaR, "Tester", NSD); } assert (m_TesterDecl && "Tester not found!"); R.addDecl(m_TesterDecl); return true; // Tell clang to continue. } // We are currently NOT parsing an EvaluateT() expression. // Escape the expression into an EvaluateT() expression. ASTContext& C = R.getSema().getASTContext(); DeclContext* DC = 0; // For DeclContext-less scopes like if (dyn_expr) {} while (!DC) { DC = static_cast<DeclContext*>(S->getEntity()); S = S->getParent(); } DeclarationName Name = R.getLookupName(); IdentifierInfo* II = Name.getAsIdentifierInfo(); SourceLocation Loc = R.getNameLoc(); VarDecl* Res = VarDecl::Create(C, DC, Loc, Loc, II, C.DependentTy, /*TypeSourceInfo*/0, SC_None); // Annotate the decl to give a hint in cling. FIXME: Current implementation // is a gross hack, because TClingCallbacks shouldn't know about // EvaluateTSynthesizer at all! SourceRange invalidRange; Res->addAttr(new (C) AnnotateAttr(invalidRange, C, "__ResolveAtRuntime", 0)); R.addDecl(Res); DC->addDecl(Res); // Say that we can handle the situation. Clang should try to recover return true; }
bool VisitFunctionDecl(FunctionDecl *f) { // Only function definitions (with bodies), not declarations. Stmt *FuncBody = f->getBody(); // Type name as string QualType QT = f->getResultType(); string TypeStr = QT.getAsString(); // Function name DeclarationName DeclName = f->getNameInfo().getName(); string FuncName = DeclName.getAsString(); func_info fi; fi.name = FuncName; fi.return_type = TypeStr; unsigned nbp = f->getNumParams(); for (int i = 0; i < nbp; ++i) { //getTypeSourceInfo()->getType() and getOriginalType() is the final type. e.g. for size_t, the result may be unsigned int, but we need only size_t //fi.argv.push_back(f->getParamDecl(i)->getTypeSourceInfo()->getType().getAsString());//->getOriginalType().getAsString()); /* TypeLoc tl = f->getParamDecl(i)->getTypeSourceInfo()->getTypeLoc(); SourceLocation sl0 = tl.getBeginLoc(); SourceLocation sl1 = tl.getEndLoc(); const char* ptr0 = TheRewriter.getSourceMgr().getCharacterData(sl0); const char* ptr1 = TheRewriter.getSourceMgr().getCharacterData(sl1); */ fi.argv.push_back(trim(decl2str_without_var(f->getParamDecl(i), &TheRewriter.getSourceMgr()))); } mFuncInfo.push_back(fi); #if 0 if (f->hasBody()) { // Add comment before stringstream SSBefore; SSBefore << "// Begin function " << FuncName << " returning " << TypeStr << "\n"; SourceLocation ST = f->getSourceRange().getBegin(); TheRewriter.InsertText(ST, SSBefore.str(), true, true); // And after stringstream SSAfter; SSAfter << "\n// End function " << FuncName << "\n"; ST = FuncBody->getLocEnd().getLocWithOffset(1); TheRewriter.InsertText(ST, SSAfter.str(), true, true); } #endif return true; }
bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) { assert(Old->getDeclName() == New->getDeclName() && "Cannot replace a decl with another decl of a different name"); DeclarationName Name = Old->getDeclName(); void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) return false; if (isDeclPtr(Ptr)) { if (Ptr == Old) { Name.setFETokenInfo(New); return true; } return false; } return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New); }
void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) { DeclarationName Name = D->getDeclName(); if (IdentifierInfo *II = Name.getAsIdentifierInfo()) updatingIdentifier(*II); void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) { AddDecl(D); return; } if (isDeclPtr(Ptr)) { // We only have a single declaration: insert before or after it, // as appropriate. if (Pos == iterator()) { // Add the new declaration before the existing declaration. NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); RemoveDecl(PrevD); AddDecl(D); AddDecl(PrevD); } else { // Add new declaration after the existing declaration. AddDecl(D); } return; } if (IdentifierInfo *II = Name.getAsIdentifierInfo()) if (II->isFromAST()) II->setChangedSinceDeserialization(); // General case: insert the declaration at the appropriate point in the // list, which already has at least two elements. IdDeclInfo *IDI = toIdDeclInfo(Ptr); if (Pos.isIterator()) { IDI->InsertDecl(Pos.getIterator() + 1, D); } else IDI->InsertDecl(IDI->decls_begin(), D); }
/// AddDecl - Link the decl to its shadowed decl chain. void IdentifierResolver::AddDecl(NamedDecl *D) { DeclarationName Name = D->getDeclName(); void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) { Name.setFETokenInfo(D); return; } IdDeclInfo *IDI; if (isDeclPtr(Ptr)) { Name.setFETokenInfo(NULL); IDI = &(*IdDeclInfos)[Name]; NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); IDI->AddDecl(PrevD); } else IDI = toIdDeclInfo(Ptr); IDI->AddDecl(D); }
/// AddShadowedDecl - Link the decl to its shadowed decl chain putting it /// after the decl that the iterator points to, thus the 'Shadow' decl will be /// encountered before the 'D' decl. void IdentifierResolver::AddShadowedDecl(NamedDecl *D, NamedDecl *Shadow) { assert(D->getDeclName() == Shadow->getDeclName() && "Different ids!"); DeclarationName Name = D->getDeclName(); void *Ptr = Name.getFETokenInfo<void>(); assert(Ptr && "No decl from Ptr ?"); IdDeclInfo *IDI; if (isDeclPtr(Ptr)) { Name.setFETokenInfo(NULL); IDI = &(*IdDeclInfos)[Name]; NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); assert(PrevD == Shadow && "Invalid shadow decl ?"); IDI->AddDecl(D); IDI->AddDecl(PrevD); return; } IDI = toIdDeclInfo(Ptr); IDI->AddShadowed(D, Shadow); }
/// RemoveDecl - Unlink the decl from its shadowed decl chain. /// The decl must already be part of the decl chain. void IdentifierResolver::RemoveDecl(NamedDecl *D) { assert(D && "null param passed"); DeclarationName Name = D->getDeclName(); if (IdentifierInfo *II = Name.getAsIdentifierInfo()) { updatingIdentifier(*II); //@@ if (II->isMetaGenerated()) return; //@@ } void *Ptr = Name.getFETokenInfo<void>(); assert(Ptr && "Didn't find this decl on its identifier's chain!"); if (isDeclPtr(Ptr)) { assert(D == Ptr && "Didn't find this decl on its identifier's chain!"); Name.setFETokenInfo(nullptr); return; } return toIdDeclInfo(Ptr)->RemoveDecl(D); }
///\brief This is the most important function of the class ASTImportSource /// since from here initiates the lookup and import part of the missing /// Decl(s) (Contexts). /// bool ASTImportSource::FindExternalVisibleDeclsByName( const DeclContext *childCurrentDeclContext, DeclarationName childDeclName) { assert(childCurrentDeclContext->hasExternalVisibleStorage() && "DeclContext has no visible decls in storage"); //Check if we have already found this declaration Name before DeclarationName parentDeclName; std::map<clang::DeclarationName, clang::DeclarationName>::iterator II = m_DeclName_map.find(childDeclName); if (II != m_DeclName_map.end()) { parentDeclName = II->second; } else { // Get the identifier info from the parent interpreter // for this Name. llvm::StringRef name(childDeclName.getAsString()); IdentifierTable &parentIdentifierTable = m_parent_Interp->getCI()->getASTContext().Idents; IdentifierInfo &parentIdentifierInfo = parentIdentifierTable.get(name); DeclarationName parentDeclNameTemp(&parentIdentifierInfo); parentDeclName = parentDeclNameTemp; } // Search in the map of the stored Decl Contexts for this // Decl Context. std::map<const clang::DeclContext *, clang::DeclContext *>::iterator I; if ((I = m_DeclContexts_map.find(childCurrentDeclContext)) != m_DeclContexts_map.end()) { // If childCurrentDeclContext was found before and is already in the map, // then do the lookup using the stored pointer. DeclContext *parentDeclContext = I->second; Decl *fromDeclContext = Decl::castFromDeclContext(parentDeclContext); ASTContext &from_ASTContext = fromDeclContext->getASTContext(); Decl *toDeclContext = Decl::castFromDeclContext(childCurrentDeclContext); ASTContext &to_ASTContext = toDeclContext->getASTContext(); DeclContext::lookup_result lookup_result = parentDeclContext->lookup(parentDeclName); // Check if we found this Name in the parent interpreter if (!lookup_result.empty()) { // Do the import if (Import(lookup_result, from_ASTContext, to_ASTContext, childCurrentDeclContext, childDeclName, parentDeclName)) return true; } } return false; }
bool RewriteUtils::replaceCXXDestructorDeclName( const CXXDestructorDecl *DtorDecl, const std::string &Name) { SourceLocation StartLoc = DtorDecl->getLocation(); const char *StartBuf = SrcManager->getCharacterData(StartLoc); TransAssert((*StartBuf == '~') && "Invalid Destructor Location"); // FIXME: it's quite ugly, better to use clang's Lexer unsigned Off = 0; StartBuf++; while (isspace(*StartBuf)) { StartBuf++; Off++; } std::string DName = DtorDecl->getNameAsString(); DeclarationNameInfo NameInfo = DtorDecl->getNameInfo(); DeclarationName DeclName = NameInfo.getName(); const Type *Ty = DeclName.getCXXNameType().getTypePtr(); size_t NameLen; if (Ty->getTypeClass() == Type::InjectedClassName) { const CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl(); std::string RDName = CXXRD->getNameAsString(); NameLen = DName.find(RDName); TransAssert((NameLen != std::string::npos) && "Cannot find RecordDecl Name!"); NameLen += RDName.length(); } else { NameLen = DName.length(); } NameLen += Off; return !TheRewriter->ReplaceText(StartLoc, NameLen, "~" + Name); }
// The core lookup interface. DeclContext::lookup_result ClangASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { switch (Name.getNameKind()) { // Normal identifiers. case DeclarationName::Identifier: break; // Operator names. Not important for now. case DeclarationName::CXXOperatorName: case DeclarationName::CXXLiteralOperatorName: return DeclContext::lookup_result(); // Using directives found in this context. // Tell Sema we didn't find any or we'll end up getting asked a *lot*. case DeclarationName::CXXUsingDirective: return SetNoExternalVisibleDeclsForName(DC, Name); // These aren't looked up like this. case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: return DeclContext::lookup_result(); // These aren't possible in the global context. case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: case DeclarationName::CXXConversionFunctionName: return DeclContext::lookup_result(); } llvm::SmallVector<NamedDecl*, 4> Decls; NameSearchContext NSC(*this, Decls, Name, DC); DeclMap.GetDecls(NSC, Name.getAsString().c_str()); return SetExternalVisibleDeclsForName(DC, Name, Decls); }
void RemoveUnusedFunction::handleOneUnresolvedLookupExpr( const FunctionDecl *CurrentFD, const UnresolvedLookupExpr *E) { DeclarationName DName = E->getName(); DeclarationName::NameKind K = DName.getNameKind(); if ((K != DeclarationName::CXXOperatorName) && (K != DeclarationName::Identifier)) return; const NestedNameSpecifier *NNS = E->getQualifier(); // we fail only if UE is invoked with some qualifier or // instantiation, e.g.: // namespace NS { template<typename T> void foo(T&) { } } // template<typename T> void bar(T p) { NS::foo(p); } // removing foo would fail. // // template <typename T> void foo() { } // template <typename T> void bar() { foo<T>(); } // removing foo would faill, too // // On the other handle, the following code is ok: // template<typename T> void foo(T&) { } // template<typename T> void bar(T p) { foo(p); } const FunctionDecl *FD = NULL; if (NNS) { FD = getFunctionDeclFromSpecifier(DName, NNS); } else { const DeclContext *Ctx = CurrentFD->getLookupParent(); FD = lookupFunctionDeclShallow(DName, Ctx); } if (!FD || FD->isReferenced()) return; addOneReferencedFunction(FD); }
bool RewriteUtils::replaceFunctionDeclName(const FunctionDecl *FD, const std::string &NameStr) { // We cannot naively use FD->getNameAsString() here. // For example, for a template class // template<typename T> // class SomeClass { // public: // SomeClass() {} // }; // applying getNameAsString() on SomeClass() gives us SomeClass<T>. DeclarationNameInfo NameInfo = FD->getNameInfo(); DeclarationName DeclName = NameInfo.getName(); DeclarationName::NameKind K = DeclName.getNameKind(); TransAssert((K != DeclarationName::CXXDestructorName) && "Cannot rename CXXDestructorName here!"); std::string FDName = FD->getNameAsString(); size_t FDNameLen = FD->getNameAsString().length(); if (K == DeclarationName::CXXConstructorName) { const Type *Ty = DeclName.getCXXNameType().getTypePtr(); if (Ty->getTypeClass() == Type::InjectedClassName) { const CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl(); std::string RDName = CXXRD->getNameAsString(); FDNameLen = FDName.find(RDName); TransAssert((FDNameLen != std::string::npos) && "Cannot find RecordDecl Name!"); FDNameLen += RDName.length(); } } return !TheRewriter->ReplaceText(NameInfo.getLoc(), FDNameLen, NameStr); }
/// begin - Returns an iterator for decls with name 'Name'. IdentifierResolver::iterator IdentifierResolver::begin(DeclarationName Name) { if (IdentifierInfo *II = Name.getAsIdentifierInfo()) readingIdentifier(*II); void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) return end(); if (isDeclPtr(Ptr)) return iterator(static_cast<NamedDecl*>(Ptr)); IdDeclInfo *IDI = toIdDeclInfo(Ptr); IdDeclInfo::DeclsTy::iterator I = IDI->decls_end(); if (I != IDI->decls_begin()) return iterator(I-1); // No decls found. return end(); }
void StmtProfiler::VisitName(DeclarationName Name) { ID.AddPointer(Name.getAsOpaquePtr()); }
bool IdentifierResolver::tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name){ if (IdentifierInfo *II = Name.getAsIdentifierInfo()) readingIdentifier(*II); void *Ptr = Name.getFETokenInfo<void>(); if (!Ptr) { Name.setFETokenInfo(D); return true; } IdDeclInfo *IDI; if (isDeclPtr(Ptr)) { NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); switch (compareDeclarations(PrevD, D)) { case DMK_Different: break; case DMK_Ignore: return false; case DMK_Replace: Name.setFETokenInfo(D); return true; } Name.setFETokenInfo(nullptr); IDI = &(*IdDeclInfos)[Name]; // If the existing declaration is not visible in translation unit scope, // then add the new top-level declaration first. if (!PrevD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { IDI->AddDecl(D); IDI->AddDecl(PrevD); } else { IDI->AddDecl(PrevD); IDI->AddDecl(D); } return true; } IDI = toIdDeclInfo(Ptr); // See whether this declaration is identical to any existing declarations. // If not, find the right place to insert it. for (IdDeclInfo::DeclsTy::iterator I = IDI->decls_begin(), IEnd = IDI->decls_end(); I != IEnd; ++I) { switch (compareDeclarations(*I, D)) { case DMK_Different: break; case DMK_Ignore: return false; case DMK_Replace: *I = D; return true; } if (!(*I)->getDeclContext()->getRedeclContext()->isTranslationUnit()) { // We've found a declaration that is not visible from the translation // unit (it's in an inner scope). Insert our declaration here. IDI->InsertDecl(I, D); return true; } } // Add the declaration to the end. IDI->AddDecl(D); return true; }