bool TeslaVisitor::VisitFunctionDecl(FunctionDecl *F) { // Only analyse non-deleted definitions (i.e. definitions with bodies). if (!F->doesThisDeclarationHaveABody()) return true; // We only parse functions that return __tesla_automaton_description*. const Type *RetTy = F->getResultType().getTypePtr(); if (!RetTy->isPointerType()) return true; QualType Pointee = RetTy->getPointeeType(); auto TypeID = Pointee.getBaseTypeIdentifier(); if (!TypeID) return true; OwningPtr<Parser> P; StringRef FnName = F->getName(); // Build a Parser appropriate to what we're parsing. string RetTypeName = TypeID->getName(); if (RetTypeName == AUTOMATON_DESC) P.reset(Parser::AutomatonParser(F, *Context)); else if ((RetTypeName == AUTOMATON_USAGE) && (FnName != AUTOMATON_USES)) P.reset(Parser::MappingParser(F, *Context)); else return true; // Actually parse the function. if (!P) return false; OwningPtr<AutomatonDescription> Description; OwningPtr<Usage> Use; if (!P->Parse(Description, Use)) return false; if (Description) Automata.push_back(Description.take()); if (Use) Roots.push_back(Use.take()); return true; }