bool HeaderTagger::isInterceptedLibHeader(const clang::SourceLocation& loc) const { if(!loc.isValid()) { return false; } auto fit = isInterceptedCache.find(sm.getFileID(loc)); if(fit != isInterceptedCache.end()) { return !fit->second.second; } std::string filename = sm.getPresumedLoc(loc).getFilename(); bool isIntercepted = isInterceptedLibHeader(filename); isInterceptedCache[sm.getFileID(loc)] = {filename, !isIntercepted}; return isIntercepted; }
string HeaderTagger::getTopLevelInclude(const clang::SourceLocation& includeLocation) const{ // if it is a dead end if (!includeLocation.isValid()) { return ""; } auto toFilename = [&] (const clang::SourceLocation& loc) { return sm.getPresumedLoc(loc).getFilename(); }; // get the presumed location (whatever this is, ask clang) ... // ~ ploc represents the file were includeLocation is located clang::PresumedLoc ploc = sm.getPresumedLoc(includeLocation); // .. and retrieve the associated include // ~ from where the file ploc represents was included clang::SourceLocation includingLocation = ploc.getIncludeLoc(); // check whether the stack can be continued if (!includingLocation.isValid()) { return ""; // this happens when element is declared in c / cpp file => no header } // ~ pIncludeLoc represents the file were includLoc is located clang::PresumedLoc pIncludeLoc = sm.getPresumedLoc(includingLocation); if( isInjectedHeader(pIncludeLoc) ){ //the header was injected -- has no valid filename ("<command line">) return ""; } //******************* // // travel down until we are at the sourcefile then work up again // if userProvided header, we need to go further // if userSearchPath/systemSearch path we need to include de header // //******************* // descent further as long as we have a header file as presumed include includeLocation if ( isHeaderFile(toFilename(includingLocation) )) { // check if last include was in the search path and next is not, // this case is a system header included inside of a programmer include chain // BUT if both are still in the search path, continue cleaning the include if (isStdLibHeader(includeLocation) && !isStdLibHeader(includingLocation)){ if(!isIntrinsicHeader(toFilename(includingLocation))) { return ploc.getFilename(); } } if (isInterceptedLibHeader(includeLocation) && !isInterceptedLibHeader(includingLocation)){ if(!isIntrinsicHeader(toFilename(includingLocation))) { return ploc.getFilename(); } } if (isUserLibHeader(includeLocation) && !isUserLibHeader(includingLocation)){ if(!isIntrinsicHeader(toFilename(includingLocation))) { return ploc.getFilename(); } } return getTopLevelInclude(includingLocation); } // we already visited all the headers and we are in the .c/.cpp file if (isHeaderFile(ploc.getFilename())) { if(isIntrinsicHeader(ploc.getFilename())) { return ploc.getFilename(); } if (isStdLibHeader(ploc.getFilename()) ) { return ploc.getFilename(); // this happens when header file is included straight in the code } if (isInterceptedLibHeader(ploc.getFilename())) { return ploc.getFilename(); // this happens when header file is included straight in the code } if (isUserLibHeader(ploc.getFilename())) { return ploc.getFilename(); } return ""; // this happens when is declared in a header which is not system header } /* // we already visited all the headers and we are in the .c/.cpp file if (!isHeaderFile(sm.getPresumedLoc(includeLoc).getFilename())) { return ploc.getFilename(); } */ return ""; }