예제 #1
0
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;
}
예제 #2
0
		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 "";
		}