void DeclCollector::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { assert(D->isImplicit()); // We need to mark the decls coming from the modules if (comesFromASTReader(RD) || comesFromASTReader(D)) { Decl* implicitD = const_cast<Decl*>(D); implicitD->addAttr(UsedAttr::CreateImplicit(implicitD->getASTContext())); } }
bool Transaction::comesFromASTReader(DeclGroupRef DGR) const { assert(!DGR.isNull() && "DeclGroupRef is Null!"); if (getCompilationOpts().CodeGenerationForModule) return true; // Take the first/only decl in the group. Decl* D = *DGR.begin(); return D->isFromASTFile(); }
// o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o bool BRTReduceKernelDef::CheckSemantics() const { FunctionType *fType; Decl *streamArg = NULL, *reduceArg = NULL; assert (decl->form->type == TT_Function); fType = (FunctionType *) decl->form; for (unsigned int i = 0; i < fType->nArgs; i++) { if (fType->args[i]->isReduce()) { if (reduceArg != NULL) { std::cerr << location << "Multiple reduce arguments in " << *FunctionName() << ": "; reduceArg->print(std::cerr, true); std::cerr << ", "; fType->args[i]->print(std::cerr, true); std::cerr << ".\n"; return false; } reduceArg = fType->args[i]; } else if (fType->args[i]->isStream()) { if (streamArg != NULL) { std::cerr << location << "Multiple non-reduce streams in " << *FunctionName() << ": "; streamArg->print(std::cerr, true); std::cerr << ", "; fType->args[i]->print(std::cerr, true); std::cerr << ".\n"; return false; } streamArg = fType->args[i]; } if ((fType->args[i]->form->getQualifiers() & TQ_Out) != 0) { std::cerr << location << "Non-reduce output in reduction kernel " << *FunctionName() << ".\n"; return false; } } if (reduceArg == NULL) { std::cerr << location << "Reduction kernel " << *FunctionName() << " has no reduce argument.\n"; return false; } if (streamArg == NULL) { std::cerr << location << "Reduction kernel " << *FunctionName() << " has no stream argument.\n"; return false; } return true; }
static Decl *findExplicitParentForImplicitDecl(ValueDecl *decl) { if (!decl->getLoc().isValid() && decl->getDeclContext()->isTypeContext()) { Decl *parentDecl = dyn_cast<ExtensionDecl>(decl->getDeclContext()); if (!parentDecl) parentDecl = cast<NominalTypeDecl>(decl->getDeclContext()); if (parentDecl->getLoc().isValid()) return parentDecl; } return nullptr; }
bool DeclCollector::comesFromASTReader(DeclGroupRef DGR) const { assert(!DGR.isNull() && "DeclGroupRef is Null!"); assert(m_CurTransaction && "No current transaction when deserializing"); if (m_CurTransaction->getCompilationOpts().CodeGenerationForModule) return true; // Take the first/only decl in the group. Decl* D = *DGR.begin(); return D->isFromASTFile(); }
bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) { storeTopLevelDecls(DG); for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; i++) { Decl *D = *i; string ssStart = D->getLocStart().printToString(Mgr->getASTContext().getSourceManager()); //std::cout<<"HandleTopLevelDecl: "<<ssStart<<std::endl; } return true; }
void C2Sema::addSymbol(Decl* d) { Decl* Old = ast.findSymbol(d->getName()); if (Old) { Diag(d->getLocation(), diag::err_redefinition) << d->getName(); Diag(Old->getLocation(), diag::note_previous_definition); } else { ast.addSymbol(d); } }
String Decls::typeCheck() { String str = ""; for(int i=0; i<decls->getSize();i++) { Decl *decl = this->decls->getValue(i); str += decl->typeCheck(); } return str; }
const Decl* Slice::getBoogieDecl(Naming& naming, SmackRep& rep) { if (name == "") return 0; Naming localNaming(naming); vector< pair<string,string> > params; for (unordered_set<Value*>::iterator V = inputs.begin(), E = inputs.end(); V != E; ++V) params.push_back(getParameter(*V,localNaming,rep)); Decl* D = Decl::function(getName(),params,"bool",getCode(localNaming,rep)); D->addAttr(Attr::attr("inline")); return D; }
void ASTConsumerHTML::HandleInterestingDecl(DeclGroupRef D) { for (DeclGroupRef::iterator it = D.begin(); it != D.end(); ++it) { Decl *decl = *it; if (decl) { log << "\n" << decl << " HandleInterestingDecl" << "\n"; decl->print(log); log << "\n"; } } }
String Decls::dump() { String str = ""; for(int i=0; i<decls->getSize(); i++) { Decl *decl = this->decls->getValue(i); str += decl->dump(); str += "; "; } return str; }
/**@brief *******************************************************************************/ template<class Decl> inline void check_declaration(const Node_id nid, const Decl d, Triple_store const& ts) { const Decl nt = declaration<Decl>(nid, ts); if( nt != d ) BOOST_THROW_EXCEPTION( Logic_err() << Logic_err::msg_t( "node is " + nt.to_string() + "; should be " + d.to_string() ) << Logic_err::str1_t(to_string(nid, ts)) ); }
void IncrementalParser::markWholeTransactionAsUsed(Transaction* T) const { for (size_t Idx = 0; Idx < T->size() /*can change in the loop!*/; ++Idx) { Transaction::DelayCallInfo I = (*T)[Idx]; // FIXME: implement for multiple decls in a DGR. assert(I.m_DGR.isSingleDecl()); Decl* D = I.m_DGR.getSingleDecl(); if (!D->hasAttr<clang::UsedAttr>()) D->addAttr(::new (D->getASTContext()) clang::UsedAttr(D->getSourceRange(), D->getASTContext(), 0/*AttributeSpellingListIndex*/)); } }
static CXString getDeclCursorUSR(const CXCursor &C) { Decl *D = cxcursor::getCursorDecl(C); // Don't generate USRs for things with invalid locations. if (!D || D->getLocStart().isInvalid()) return createCXString(""); // Check if the cursor has 'NoLinkage'. if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) switch (ND->getLinkage()) { case ExternalLinkage: // Generate USRs for all entities with external linkage. break; case NoLinkage: case UniqueExternalLinkage: // We allow enums, typedefs, and structs that have no linkage to // have USRs that are anchored to the file they were defined in // (e.g., the header). This is a little gross, but in principal // enums/anonymous structs/etc. defined in a common header file // are referred to across multiple translation units. if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) || isa<EnumConstantDecl>(ND) || isa<FieldDecl>(ND) || isa<VarDecl>(ND) || isa<NamespaceDecl>(ND)) break; // Fall-through. case InternalLinkage: if (isa<FunctionDecl>(ND)) break; } CXTranslationUnit TU = cxcursor::getCursorTU(C); if (!TU) return createCXString(""); CXStringBuf *buf = cxstring::getCXStringBuf(TU); if (!buf) return createCXString(""); { USRGenerator UG(&C, &buf->Data); UG->Visit(D); if (UG->ignoreResults()) { disposeCXStringBuf(buf); return createCXString(""); } } // Return the C-string, but don't make a copy since it is already in // the string buffer. buf->Data.push_back('\0'); return createCXString(buf); }
// o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o bool BRTMapKernelDef::CheckSemantics() const { FunctionType *fType; Decl *outArg = NULL; assert (decl->form->type == TT_Function); fType = (FunctionType *) decl->form; for (unsigned int i = 0; i < fType->nArgs; i++) { if (fType->args[i]->isReduce()) { std::cerr << location << "Reduce arguments are not allowed in " << *FunctionName() << ": "; fType->args[i]->print(std::cerr, true); std::cerr << ".\n"; return false; } if ((fType->args[i]->form->getQualifiers() & TQ_Out) != 0) { /* if (outArg) { std::cerr << location << "Multiple outputs not supported: "; outArg->print(std::cerr, true); std::cerr << ", "; fType->args[i]->print(std::cerr, true); std::cerr << ".\n"; return false; }*/ outArg = fType->args[i]; if (!recursiveIsStream(outArg->form)) { std::cerr << location << "Output is not a stream: "; outArg->print(std::cerr, true); std::cerr << ".\n"; return false; } if ((outArg->form->getQualifiers() & TQ_Iter) != 0) { std::cerr << location << "Output cannot be an iterator: "; outArg->print(std::cerr, true); std::cerr << ".\n"; return false; } } } if (outArg == NULL&&returnsVoid()) { std::cerr << location << "Warning: " << *FunctionName() << " has no output.\n"; } return true; }
void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Recoverable) { assert(this == getPrimaryContext() && "expected a primary DC"); // Skip declarations within functions. // FIXME: We shouldn't need to build lookup tables for function declarations // ever, and we can't do so correctly because we can't model the nesting of // scopes which occurs within functions. We use "qualified" lookup into // function declarations when handling friend declarations inside nested // classes, and consequently accept the following invalid code: // // void f() { void g(); { int g; struct S { friend void g(); }; } } if (isFunctionOrMethod() && !isa<FunctionDecl>(D)) return; // Skip declarations which should be invisible to name lookup. if (shouldBeHidden(D)) return; // If we already have a lookup data structure, perform the insertion into // it. If we might have externally-stored decls with this name, look them // up and perform the insertion. If this decl was declared outside its // semantic context, buildLookup won't add it, so add it now. // // FIXME: As a performance hack, don't add such decls into the translation // unit unless we're in C++, since qualified lookup into the TU is never // performed. if (LookupPtr.getPointer() || hasExternalVisibleStorage() || ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) && (getParentASTContext().getLangOpts().CPlusPlus || !isTranslationUnit()))) { // If we have lazily omitted any decls, they might have the same name as // the decl which we are adding, so build a full lookup table before adding // this decl. buildLookup(); makeDeclVisibleInContextImpl(D, Internal); } else { LookupPtr.setInt(true); } // If we are a transparent context or inline namespace, insert into our // parent context, too. This operation is recursive. if (isTransparentContext() || isInlineNamespace()) getParent()->getPrimaryContext()-> makeDeclVisibleInContextWithFlags(D, Internal, Recoverable); Decl *DCAsDecl = cast<Decl>(this); // Notify that a decl was made visible unless we are a Tag being defined. if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined())) if (ASTMutationListener *L = DCAsDecl->getASTMutationListener()) L->AddedVisibleDecl(this, 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; }
void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) { // Build the Call Graph by adding all the top level declarations to the graph. // Note: CallGraph can trigger deserialization of more items from a pch // (though HandleInterestingDecl); triggering additions to LocalTUDecls. // We rely on random access to add the initially processed Decls to CG. CallGraph CG; for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) { CG.addToCallGraph(LocalTUDecls[i]); } // Walk over all of the call graph nodes in topological order, so that we // analyze parents before the children. Skip the functions inlined into // the previously processed functions. Use external Visited set to identify // inlined functions. The topological order allows the "do not reanalyze // previously inlined function" performance heuristic to be triggered more // often. SetOfConstDecls Visited; SetOfConstDecls VisitedAsTopLevel; llvm::ReversePostOrderTraversal<clang::CallGraph*> RPOT(&CG); for (llvm::ReversePostOrderTraversal<clang::CallGraph*>::rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I) { NumFunctionTopLevel++; CallGraphNode *N = *I; Decl *D = N->getDecl(); string ssStart = D->getLocStart().printToString(Mgr->getASTContext().getSourceManager()); // Skip the abstract root node. if (!D) continue; // Skip the functions which have been processed already or previously // inlined. if (shouldSkipFunction(D, Visited, VisitedAsTopLevel)) continue; // Analyze the function. SetOfConstDecls VisitedCallees; HandleCode(D, AM_Path, (Mgr->options.InliningMode == All ? nullptr : &VisitedCallees)); // Add the visited callees to the global visited set. for (SetOfConstDecls::iterator I = VisitedCallees.begin(), E = VisitedCallees.end(); I != E; ++I) { Visited.insert(*I); } VisitedAsTopLevel.insert(D); } }
inline Decl declaration(const Node_id nid, Triple_store const& ts) { using namespace owlcpp::terms; Decl d; try { if( ts.is_standard(nid) ) d.set(nid); BOOST_FOREACH( Triple const& t, ts.find_triple(nid, any, any, any) ) { if( t.pred_ == rdf_type::id() ) { d.set(t.obj_); continue; } d.set(t.pred_); } BOOST_FOREACH( Triple const& t, ts.find_triple(any, owl_annotatedSource::id(), nid, any) ) { const Node_id x = t.subj_; if( ts[x].ns_id() != blank::id() ) BOOST_THROW_EXCEPTION( Logic_err() << Logic_err::msg_t("non-blank subject in _:x owl:annotatedSource y") << Logic_err::node_id_t(x) ); BOOST_FOREACH( Triple const& t, ts.find_triple(x, owl_annotatedTarget::id(), any, any) ) { d.set(t.obj_); } } } catch( Logic_err const& e) { if( Node_id const* nidp = boost::get_error_info<Logic_err::node_id_t>(e) ) { e << Logic_err::str1_t(to_string(*nidp, ts)); } Logic_err e2; e2 << Logic_err::msg_t("node declaration error") << Logic_err::str1_t(to_string(nid, ts)) << Logic_err::nested_t(boost::copy_exception(e)) ; BOOST_THROW_EXCEPTION(e2); } return d; }
Decl* StructTypeDecl::find(const char* name_) const { // normal members for (unsigned i=0; i<numMembers(); i++) { Decl* D = members[i]; if (strcmp(D->getName(), name_) == 0) return D; if (D->hasEmptyName()) { // empty string assert(isa<StructTypeDecl>(D)); StructTypeDecl* sub = cast<StructTypeDecl>(D); D = sub->find(name_); if (D) return D; } } return findFunction(name_); }
// Given declarations d1 and d2, a declaration error occurs when: // // - d2 changes the meaning of the name declared by d1, or if not that, then // - d1 and d2 are both objects, or // - d1 and d2 are functions that cannot be overloaded, or // - d1 and d2 are types having different kinds. // // Note that d1 precedes d2 in lexical order. // // TODO: Would it make sense to poison the declaration so that it's not // analyzed in subsequent passes? We could essentially replace the existing // overload set with one containing a poisoned declaration. Any expression // that uses that name would have an invalid type. We could then use this // to list the places where the error affects use. void check_declarations(Context& cxt, Decl const& d1, Decl const& d2) { struct fn { Context& cxt; Decl const& d2; void operator()(Decl const& d) { lingo_unhandled(d); } void operator()(Variable_decl const& d1) { return check_declarations(cxt, d1, cast_as(d1, d2)); } void operator()(Function_decl const& d1) { return check_declarations(cxt, d1, cast_as(d1, d2)); } void operator()(Type_decl const& d1) { return check_declarations(cxt, d1, cast_as(d1, d2)); } }; if (typeid(d1) != typeid(d2)) { // TODO: Get the source location right. error(cxt, "declaration changes the meaning of '{}'", d1.name()); // note("'{}' previously declared as:", d1.name()); // TODO: Don't print the definition. It's not germaine to // the error. If we have source locations, I wonder if we // can just point at the line. // note("{}", d1); throw Declaration_error(); } apply(d1, fn{cxt, d2}); }
ScopeResult Scope::findSymbol(const std::string& symbol) const { // search this scope ScopeResult result; for (DeclsConstIter iter = decls.begin(); iter != decls.end(); ++iter) { Decl* D = *iter; if (D->getName() == symbol) { result.decl = D; // TODO fill other result fields return result; } } // search parent or globals if (parent) return parent->findSymbol(symbol); else return globals->findSymbol(symbol); }
void ExternalASTMerger::FindExternalLexicalDecls( const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, SmallVectorImpl<Decl *> &Result) { ForEachMatchingDC( DC, Importers, [&](const ImporterPair &IP, Source<const DeclContext *> SourceDC) { for (const Decl *SourceDecl : SourceDC.get()->decls()) { if (IsKindWeWant(SourceDecl->getKind())) { Decl *ImportedDecl = IP.Forward->Import(const_cast<Decl *>(SourceDecl)); assert(ImportedDecl->getDeclContext() == DC); (void)ImportedDecl; } } }); }
inline Decl check_seq_declaration(Range& r, Triple_store const& ts) { boost::sub_range<Range> bsr(r); if( ! bsr ) BOOST_THROW_EXCEPTION( Logic_err() << Logic_err::msg_t("empty sequence") ); const Decl d = declaration<Decl>(bsr.front(), ts); if( d.is_none() ) BOOST_THROW_EXCEPTION( Logic_err() << Logic_err::msg_t("node " + Decl::name() + " declaration not found") << Logic_err::str1_t(to_string(bsr.front(), ts)) ); bsr.advance_begin(1); check_seq_declaration(bsr, d, ts); return d; }
void CodeGenFunction::EmitDecl(const Decl &D) { switch (D.getKind()) { default: CGM.ErrorUnsupported(&D, "decl"); return; case Decl::ParmVar: assert(0 && "Parmdecls should not be in declstmts!"); case Decl::Function: // void X(); case Decl::Record: // struct/union/class X; case Decl::Enum: // enum X; case Decl::EnumConstant: // enum ? { X = ? } case Decl::CXXRecord: // struct/union/class X; [C++] case Decl::Using: // using X; [C++] case Decl::UsingShadow: case Decl::UsingDirective: // using namespace X; [C++] case Decl::StaticAssert: // static_assert(X, ""); [C++0x] // None of these decls require codegen support. return; case Decl::Var: { const VarDecl &VD = cast<VarDecl>(D); assert(VD.isBlockVarDecl() && "Should not see file-scope variables inside a function!"); return EmitBlockVarDecl(VD); } case Decl::Typedef: { // typedef int X; const TypedefDecl &TD = cast<TypedefDecl>(D); QualType Ty = TD.getUnderlyingType(); if (Ty->isVariablyModifiedType()) EmitVLASize(Ty); } } }
/**@brief *******************************************************************************/ template<class Decl> inline Decl check_same_declaration(const Node_id n1, const Node_id n2, Triple_store const& ts) { const Decl d1 = declaration<Decl>(n1, ts); if( d1.is_none() ) BOOST_THROW_EXCEPTION( Logic_err() << Logic_err::msg_t("node " + Decl::name() + " declaration not found") << Logic_err::str1_t(to_string(n1, ts)) ); const Decl d2 = declaration<Decl>(n2, ts); if( d1 != d2 ) BOOST_THROW_EXCEPTION( Logic_err() << Logic_err::msg_t("node type mismatch") << Logic_err::str1_t(d1.to_string()) << Logic_err::str2_t(d2.to_string()) ); return d1; }
// Add the declaration d to the given scope. void declare(Context& cxt, Scope& scope, Decl& decl) { if (Overload_set* ovl = scope.lookup(decl.name())) declare(cxt, *ovl, decl); else scope.bind(decl); }
bool StructDef::printStructureStreamShape(std::ostream& out) { for (int j=0; j < nComponents; j++) { if(!components[j]->printStructureStreamShapeInternals(out)) return false; Decl *decl = components[j]->next; while (decl != NULL) { if(!decl->printStructureStreamShapeInternals(out)) return false; decl = decl->next; } } return true; }
// Add the declaration d to the given scope. // // Note that this does not currently check to see if the declaration is // valid i.e., that it does not conflict a previous declaration. This is // only checkable if all declarations are fully elaborated (i.e., typed). void declare(Context& cxt, Scope& scope, Decl& decl) { if (Overload_set* ovl = scope.lookup(decl.name())) ovl->push_back(decl); else scope.bind(decl); }
static void ScanCodeDecls(DeclContext *DC, BugReporter &BR) { for (DeclContext::decl_iterator I=DC->decls_begin(), E=DC->decls_end(); I!=E ; ++I) { Decl *D = *I; if (D->getBody()) CheckStringRefAssignedTemporary(D, BR); if (CXXRecordDecl *R = dyn_cast<CXXRecordDecl>(D)) if (R->isDefinition()) CheckASTMemory(R, BR); if (DeclContext *DC_child = dyn_cast<DeclContext>(D)) ScanCodeDecls(DC_child, BR); } }