static void FindEntitiesInDC(DeclContext *DC, Program &Prog, EntityHandler &Handler) { for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { if (I->getLocation().isInvalid()) continue; Entity Ent = Entity::get(*I, Prog); if (Ent.isValid()) Handler.Handle(Ent); if (DeclContext *SubDC = dyn_cast<DeclContext>(*I)) FindEntitiesInDC(SubDC, Prog, Handler); } }
void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, unsigned Indentation) { // Print DeclContext name. switch (DC->getDeclKind()) { case Decl::TranslationUnit: Out << "[translation unit] " << DC; break; case Decl::Namespace: { Out << "[namespace] "; const NamespaceDecl* ND = cast<NamespaceDecl>(DC); Out << *ND; break; } case Decl::Enum: { const EnumDecl* ED = cast<EnumDecl>(DC); if (ED->isCompleteDefinition()) Out << "[enum] "; else Out << "<enum> "; Out << *ED; break; } case Decl::Record: { const RecordDecl* RD = cast<RecordDecl>(DC); if (RD->isCompleteDefinition()) Out << "[struct] "; else Out << "<struct> "; Out << *RD; break; } case Decl::CXXRecord: { const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC); if (RD->isCompleteDefinition()) Out << "[class] "; else Out << "<class> "; Out << *RD << ' ' << DC; break; } case Decl::ObjCMethod: Out << "[objc method]"; break; case Decl::ObjCInterface: Out << "[objc interface]"; break; case Decl::ObjCCategory: Out << "[objc category]"; break; case Decl::ObjCProtocol: Out << "[objc protocol]"; break; case Decl::ObjCImplementation: Out << "[objc implementation]"; break; case Decl::ObjCCategoryImpl: Out << "[objc categoryimpl]"; break; case Decl::LinkageSpec: Out << "[linkage spec]"; break; case Decl::Block: Out << "[block]"; break; case Decl::Function: { const FunctionDecl* FD = cast<FunctionDecl>(DC); if (FD->doesThisDeclarationHaveABody()) Out << "[function] "; else Out << "<function> "; Out << *FD; // Print the parameters. Out << "("; bool PrintComma = false; for (FunctionDecl::param_const_iterator I = FD->param_begin(), E = FD->param_end(); I != E; ++I) { if (PrintComma) Out << ", "; else PrintComma = true; Out << **I; } Out << ")"; break; } case Decl::CXXMethod: { const CXXMethodDecl* D = cast<CXXMethodDecl>(DC); if (D->isOutOfLine()) Out << "[c++ method] "; else if (D->isImplicit()) Out << "(c++ method) "; else Out << "<c++ method> "; Out << *D; // Print the parameters. Out << "("; bool PrintComma = false; for (FunctionDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); I != E; ++I) { if (PrintComma) Out << ", "; else PrintComma = true; Out << **I; } Out << ")"; // Check the semantic DeclContext. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } case Decl::CXXConstructor: { const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC); if (D->isOutOfLine()) Out << "[c++ ctor] "; else if (D->isImplicit()) Out << "(c++ ctor) "; else Out << "<c++ ctor> "; Out << *D; // Print the parameters. Out << "("; bool PrintComma = false; for (FunctionDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); I != E; ++I) { if (PrintComma) Out << ", "; else PrintComma = true; Out << **I; } Out << ")"; // Check the semantic DC. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } case Decl::CXXDestructor: { const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC); if (D->isOutOfLine()) Out << "[c++ dtor] "; else if (D->isImplicit()) Out << "(c++ dtor) "; else Out << "<c++ dtor> "; Out << *D; // Check the semantic DC. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } case Decl::CXXConversion: { const CXXConversionDecl* D = cast<CXXConversionDecl>(DC); if (D->isOutOfLine()) Out << "[c++ conversion] "; else if (D->isImplicit()) Out << "(c++ conversion) "; else Out << "<c++ conversion> "; Out << *D; // Check the semantic DC. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } default: llvm_unreachable("a decl that inherits DeclContext isn't handled"); } Out << "\n"; // Print decls in the DeclContext. for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { for (unsigned i = 0; i < Indentation; ++i) Out << " "; Decl::Kind DK = I->getKind(); switch (DK) { case Decl::Namespace: case Decl::Enum: case Decl::Record: case Decl::CXXRecord: case Decl::ObjCMethod: case Decl::ObjCInterface: case Decl::ObjCCategory: case Decl::ObjCProtocol: case Decl::ObjCImplementation: case Decl::ObjCCategoryImpl: case Decl::LinkageSpec: case Decl::Block: case Decl::Function: case Decl::CXXMethod: case Decl::CXXConstructor: case Decl::CXXDestructor: case Decl::CXXConversion: { DeclContext* DC = cast<DeclContext>(*I); PrintDeclContext(DC, Indentation+2); break; } case Decl::IndirectField: { IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(*I); Out << "<IndirectField> " << *IFD << '\n'; break; } case Decl::Label: { LabelDecl *LD = cast<LabelDecl>(*I); Out << "<Label> " << *LD << '\n'; break; } case Decl::Field: { FieldDecl *FD = cast<FieldDecl>(*I); Out << "<field> " << *FD << '\n'; break; } case Decl::Typedef: case Decl::TypeAlias: { TypedefNameDecl* TD = cast<TypedefNameDecl>(*I); Out << "<typedef> " << *TD << '\n'; break; } case Decl::EnumConstant: { EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I); Out << "<enum constant> " << *ECD << '\n'; break; } case Decl::Var: { VarDecl* VD = cast<VarDecl>(*I); Out << "<var> " << *VD << '\n'; break; } case Decl::ImplicitParam: { ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I); Out << "<implicit parameter> " << *IPD << '\n'; break; } case Decl::ParmVar: { ParmVarDecl* PVD = cast<ParmVarDecl>(*I); Out << "<parameter> " << *PVD << '\n'; break; } case Decl::ObjCProperty: { ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I); Out << "<objc property> " << *OPD << '\n'; break; } case Decl::FunctionTemplate: { FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I); Out << "<function template> " << *FTD << '\n'; break; } case Decl::FileScopeAsm: { Out << "<file-scope asm>\n"; break; } case Decl::UsingDirective: { Out << "<using directive>\n"; break; } case Decl::NamespaceAlias: { NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I); Out << "<namespace alias> " << *NAD << '\n'; break; } case Decl::ClassTemplate: { ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I); Out << "<class template> " << *CTD << '\n'; break; } default: Out << "DeclKind: " << DK << '"' << *I << "\"\n"; llvm_unreachable("decl unhandled"); } } }
void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (Policy.TerseOutput) return; if (Indent) Indentation += Policy.Indentation; SmallVector<Decl*, 2> Decls; bool MergeOneDecl = false; for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); D != DEnd; ++D) { // Don't print ObjCIvarDecls, as they are printed when visiting the // containing ObjCInterfaceDecl. if (isa<ObjCIvarDecl>(*D)) continue; // Skip over implicit declarations in pretty-printing mode. if (D->isImplicit()) continue; // Don't print implicit specializations, as they are printed when visiting // corresponding templates. if (auto FD = dyn_cast<FunctionDecl>(*D)) if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation && !isa<ClassTemplateSpecializationDecl>(DC)) continue; // The next bits of code handles stuff like "struct {int x;} a,b"; we're // forced to merge the declarations because there's no other way to // refer to the struct in question. This limited merging is safe without // a bunch of other checks because it only merges declarations directly // referring to the tag, not typedefs. // // Check whether the current declaration should be grouped with a previous // unnamed struct. QualType CurDeclType = getDeclType(*D); if (!Decls.empty() && !CurDeclType.isNull() && (!MergeOneDecl || Decls.size() == 1)) { QualType BaseType = GetBaseType(CurDeclType); if (!BaseType.isNull() && isa<ElaboratedType>(BaseType)) BaseType = cast<ElaboratedType>(BaseType)->getNamedType(); if (!BaseType.isNull() && isa<TagType>(BaseType) && cast<TagType>(BaseType)->getDecl() == Decls[0]) { Decls.push_back(*D); continue; } } // If we have a merged group waiting to be handled, handle it now. if (!Decls.empty()) ProcessDeclGroup(Decls); // If the current declaration is an unnamed tag type, save it // so we can merge it with the subsequent declaration(s) using it. if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) { Decls.push_back(*D); MergeOneDecl = false; continue; } // Attempt to merge named tags too, but // only with a single decl. (This cleans // up warnings about unused declarations // when a struct is defined inline inside // another struct.) Only merge one variable // declaration, so we don't have to worry // about whether the storage class and/or // qualifiers match. if (isa<TagDecl>(*D)) { Decls.push_back(*D); MergeOneDecl = true; continue; } if (isa<AccessSpecDecl>(*D)) { Indentation -= Policy.Indentation; this->Indent(); Print(D->getAccess()); Out << ":\n"; Indentation += Policy.Indentation; continue; } this->Indent(); Visit(*D); // FIXME: Need to be able to tell the DeclPrinter when const char *Terminator = nullptr; if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) || isa<PragmaPupcDecl>(*D)) Terminator = nullptr; else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody()) Terminator = nullptr; else if (auto FD = dyn_cast<FunctionDecl>(*D)) { if (FD->isThisDeclarationADefinition()) Terminator = nullptr; else Terminator = ";"; } else if (auto TD = dyn_cast<FunctionTemplateDecl>(*D)) { if (TD->getTemplatedDecl()->isThisDeclarationADefinition()) Terminator = nullptr; else Terminator = ";"; } else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) || isa<ObjCImplementationDecl>(*D) || isa<ObjCInterfaceDecl>(*D) || isa<ObjCProtocolDecl>(*D) || isa<ObjCCategoryImplDecl>(*D) || isa<ObjCCategoryDecl>(*D)) Terminator = nullptr; else if (isa<EnumConstantDecl>(*D)) { DeclContext::decl_iterator Next = D; ++Next; if (Next != DEnd) Terminator = ","; } else Terminator = ";"; if (Terminator) Out << Terminator; if (!Policy.TerseOutput && ((isa<FunctionDecl>(*D) && cast<FunctionDecl>(*D)->doesThisDeclarationHaveABody()) || (isa<FunctionTemplateDecl>(*D) && cast<FunctionTemplateDecl>(*D)->getTemplatedDecl()->doesThisDeclarationHaveABody()))) ; // StmtPrinter already added '\n' after CompoundStmt. else Out << "\n"; // Declare target attribute is special one, natural spelling for the pragma // assumes "ending" construct so print it here. if (D->hasAttr<OMPDeclareTargetDeclAttr>()) Out << "#pragma omp end declare target\n"; } if (!Decls.empty()) ProcessDeclGroup(Decls); if (Indent) Indentation -= Policy.Indentation; }
void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (Policy.TerseOutput) return; if (Indent) Indentation += Policy.Indentation; SmallVector<Decl*, 2> Decls; for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); D != DEnd; ++D) { // Don't print ObjCIvarDecls, as they are printed when visiting the // containing ObjCInterfaceDecl. if (isa<ObjCIvarDecl>(*D)) continue; // Skip over implicit declarations in pretty-printing mode. if (D->isImplicit()) continue; // The next bits of code handles stuff like "struct {int x;} a,b"; we're // forced to merge the declarations because there's no other way to // refer to the struct in question. This limited merging is safe without // a bunch of other checks because it only merges declarations directly // referring to the tag, not typedefs. // // Check whether the current declaration should be grouped with a previous // unnamed struct. QualType CurDeclType = getDeclType(*D); if (!Decls.empty() && !CurDeclType.isNull()) { QualType BaseType = GetBaseType(CurDeclType); if (!BaseType.isNull() && isa<ElaboratedType>(BaseType)) BaseType = cast<ElaboratedType>(BaseType)->getNamedType(); if (!BaseType.isNull() && isa<TagType>(BaseType) && cast<TagType>(BaseType)->getDecl() == Decls[0]) { Decls.push_back(*D); continue; } } // If we have a merged group waiting to be handled, handle it now. if (!Decls.empty()) ProcessDeclGroup(Decls); // If the current declaration is an unnamed tag type, save it // so we can merge it with the subsequent declaration(s) using it. if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) { Decls.push_back(*D); continue; } if (isa<AccessSpecDecl>(*D)) { Indentation -= Policy.Indentation; this->Indent(); Print(D->getAccess()); Out << ":\n"; Indentation += Policy.Indentation; continue; } this->Indent(); Visit(*D); // FIXME: Need to be able to tell the DeclPrinter when const char *Terminator = nullptr; if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D)) Terminator = nullptr; else if (isa<FunctionDecl>(*D) && cast<FunctionDecl>(*D)->isThisDeclarationADefinition()) Terminator = nullptr; else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody()) Terminator = nullptr; else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) || isa<ObjCImplementationDecl>(*D) || isa<ObjCInterfaceDecl>(*D) || isa<ObjCProtocolDecl>(*D) || isa<ObjCCategoryImplDecl>(*D) || isa<ObjCCategoryDecl>(*D)) Terminator = nullptr; else if (isa<EnumConstantDecl>(*D)) { DeclContext::decl_iterator Next = D; ++Next; if (Next != DEnd) Terminator = ","; } else Terminator = ";"; if (Terminator) Out << Terminator; Out << "\n"; // Declare target attribute is special one, natural spelling for the pragma // assumes "ending" construct so print it here. if (D->hasAttr<OMPDeclareTargetDeclAttr>()) Out << "#pragma omp end declare target\n"; } if (!Decls.empty()) ProcessDeclGroup(Decls); if (Indent) Indentation -= Policy.Indentation; }
void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, unsigned Indentation) { // Print DeclContext name. switch (DC->getDeclKind()) { case Decl::TranslationUnit: Out << "[translation unit] " << DC; break; case Decl::Namespace: { Out << "[namespace] "; const NamespaceDecl* ND = cast<NamespaceDecl>(DC); Out << ND->getNameAsString(); break; } case Decl::Enum: { const EnumDecl* ED = cast<EnumDecl>(DC); if (ED->isDefinition()) Out << "[enum] "; else Out << "<enum> "; Out << ED->getNameAsString(); break; } case Decl::Record: { const RecordDecl* RD = cast<RecordDecl>(DC); if (RD->isDefinition()) Out << "[struct] "; else Out << "<struct> "; Out << RD->getNameAsString(); break; } case Decl::CXXRecord: { const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC); if (RD->isDefinition()) Out << "[class] "; else Out << "<class> "; Out << RD->getNameAsString() << " " << DC; break; } case Decl::ObjCMethod: Out << "[objc method]"; break; case Decl::ObjCInterface: Out << "[objc interface]"; break; case Decl::ObjCCategory: Out << "[objc category]"; break; case Decl::ObjCProtocol: Out << "[objc protocol]"; break; case Decl::ObjCImplementation: Out << "[objc implementation]"; break; case Decl::ObjCCategoryImpl: Out << "[objc categoryimpl]"; break; case Decl::LinkageSpec: Out << "[linkage spec]"; break; case Decl::Block: Out << "[block]"; break; case Decl::Function: { const FunctionDecl* FD = cast<FunctionDecl>(DC); if (FD->isThisDeclarationADefinition()) Out << "[function] "; else Out << "<function> "; Out << FD->getNameAsString(); // Print the parameters. Out << "("; bool PrintComma = false; for (FunctionDecl::param_const_iterator I = FD->param_begin(), E = FD->param_end(); I != E; ++I) { if (PrintComma) Out << ", "; else PrintComma = true; Out << (*I)->getNameAsString(); } Out << ")"; break; } case Decl::CXXMethod: { const CXXMethodDecl* D = cast<CXXMethodDecl>(DC); if (D->isOutOfLineDefinition()) Out << "[c++ method] "; else if (D->isImplicit()) Out << "(c++ method) "; else Out << "<c++ method> "; Out << D->getNameAsString(); // Print the parameters. Out << "("; bool PrintComma = false; for (FunctionDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); I != E; ++I) { if (PrintComma) Out << ", "; else PrintComma = true; Out << (*I)->getNameAsString(); } Out << ")"; // Check the semantic DeclContext. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } case Decl::CXXConstructor: { const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC); if (D->isOutOfLineDefinition()) Out << "[c++ ctor] "; else if (D->isImplicit()) Out << "(c++ ctor) "; else Out << "<c++ ctor> "; Out << D->getNameAsString(); // Print the parameters. Out << "("; bool PrintComma = false; for (FunctionDecl::param_const_iterator I = D->param_begin(), E = D->param_end(); I != E; ++I) { if (PrintComma) Out << ", "; else PrintComma = true; Out << (*I)->getNameAsString(); } Out << ")"; // Check the semantic DC. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } case Decl::CXXDestructor: { const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC); if (D->isOutOfLineDefinition()) Out << "[c++ dtor] "; else if (D->isImplicit()) Out << "(c++ dtor) "; else Out << "<c++ dtor> "; Out << D->getNameAsString(); // Check the semantic DC. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } case Decl::CXXConversion: { const CXXConversionDecl* D = cast<CXXConversionDecl>(DC); if (D->isOutOfLineDefinition()) Out << "[c++ conversion] "; else if (D->isImplicit()) Out << "(c++ conversion) "; else Out << "<c++ conversion> "; Out << D->getNameAsString(); // Check the semantic DC. const DeclContext* SemaDC = D->getDeclContext(); const DeclContext* LexicalDC = D->getLexicalDeclContext(); if (SemaDC != LexicalDC) Out << " [[" << SemaDC << "]]"; break; } default: assert(0 && "a decl that inherits DeclContext isn't handled"); } Out << "\n"; // Print decls in the DeclContext. // FIXME: Should not use a NULL DeclContext! ASTContext *Context = 0; for (DeclContext::decl_iterator I = DC->decls_begin(*Context), E = DC->decls_end(*Context); I != E; ++I) { for (unsigned i = 0; i < Indentation; ++i) Out << " "; Decl::Kind DK = I->getKind(); switch (DK) { case Decl::Namespace: case Decl::Enum: case Decl::Record: case Decl::CXXRecord: case Decl::ObjCMethod: case Decl::ObjCInterface: case Decl::ObjCCategory: case Decl::ObjCProtocol: case Decl::ObjCImplementation: case Decl::ObjCCategoryImpl: case Decl::LinkageSpec: case Decl::Block: case Decl::Function: case Decl::CXXMethod: case Decl::CXXConstructor: case Decl::CXXDestructor: case Decl::CXXConversion: { DeclContext* DC = cast<DeclContext>(*I); PrintDeclContext(DC, Indentation+2); break; } case Decl::Field: { FieldDecl* FD = cast<FieldDecl>(*I); Out << "<field> " << FD->getNameAsString() << "\n"; break; } case Decl::Typedef: { TypedefDecl* TD = cast<TypedefDecl>(*I); Out << "<typedef> " << TD->getNameAsString() << "\n"; break; } case Decl::EnumConstant: { EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I); Out << "<enum constant> " << ECD->getNameAsString() << "\n"; break; } case Decl::Var: { VarDecl* VD = cast<VarDecl>(*I); Out << "<var> " << VD->getNameAsString() << "\n"; break; } case Decl::ImplicitParam: { ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I); Out << "<implicit parameter> " << IPD->getNameAsString() << "\n"; break; } case Decl::ParmVar: { ParmVarDecl* PVD = cast<ParmVarDecl>(*I); Out << "<parameter> " << PVD->getNameAsString() << "\n"; break; } case Decl::OriginalParmVar: { OriginalParmVarDecl* OPVD = cast<OriginalParmVarDecl>(*I); Out << "<original parameter> " << OPVD->getNameAsString() << "\n"; break; } case Decl::ObjCProperty: { ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I); Out << "<objc property> " << OPD->getNameAsString() << "\n"; break; } default: fprintf(stderr, "DeclKind: %d \"%s\"\n", DK, I->getDeclKindName()); assert(0 && "decl unhandled"); } } }