void HeaderTagger::addHeaderForDecl(const core::NodePtr& node, const clang::Decl* decl, bool attachUserDefined) const { // check whether there is a declaration at all if (!decl) return; // the node was already annotated, what is the point of doint it again? if (insieme::annotations::c::hasIncludeAttached(node)) return; if (VLOG_IS_ON(2)){ std::string name("UNNAMED"); if (const clang::NamedDecl* nmd = llvm::dyn_cast<clang::NamedDecl>(decl)) name = nmd->getQualifiedNameAsString(); VLOG(2) << "Searching header for: " << node << " of type " << node->getNodeType() << " [clang: " << name << "]" ; } string fileName = getTopLevelInclude(decl->getLocation()); // file must be a header file if (!isHeaderFile(fileName)) { VLOG(2) << "'" << fileName << "' not a headerfile"; return; // not to be attached } // do not add headers for external declarations unless those are within the std-library if (const clang::FunctionDecl* funDecl = llvm::dyn_cast<clang::FunctionDecl>(decl)) { // TODO: this is just based on integration tests - to make them work, no real foundation :( if( funDecl->isExternC() && !(isStdLibHeader(fileName) || isIntrinsicHeader(fileName)) ) return; } // get absolute path of header file fs::path header = fs::canonical(fileName); if (auto oclHeader = isOCLHeader(header)){ VLOG(2) << "OCL header to be attached: " << oclHeader; insieme::annotations::c::attachInclude(node, *oclHeader); return; }if( auto stdLibHeader = toStdLibHeader(header) ) { header = *stdLibHeader; } else if (auto interceptedLibHeader = toInterceptedLibHeader(header) ) { header = *interceptedLibHeader; } else if( auto intrinsicHeader = toIntrinsicHeader(header) ) { header = *intrinsicHeader; } else if (auto userLibHeader = toUserLibHeader(header) ) { if(attachUserDefined ) { header = *userLibHeader; } else { return; } } VLOG(2) << " header to be attached: " << header.string(); // use resulting header insieme::annotations::c::attachInclude(node, header.string()); }
boost::optional<fs::path> HeaderTagger::toUserLibHeader(const fs::path& path) const { static const boost::optional<fs::path> fail; if(userIncludeDirs.empty()) { return fail; } if(contains(userIncludeDirs, fs::canonical(path))) { return fs::path(); } if(!path.has_parent_path()) { return fail; } // if it is within the user-added-include directory, build relative path auto res = toUserLibHeader(path.parent_path()); return (res) ? (*res / path.filename()) : fail; }
bool HeaderTagger::isUserLibHeader(const fs::path& path) const{ return toUserLibHeader(path); }