Пример #1
0
	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());
		}
Пример #2
0
bool HeaderTagger::isStdLibHeader(const clang::SourceLocation& loc) const {
	if(!loc.isValid()) { return false; }
	auto fit = isStdCache.find(sm.getFileID(loc));
	if(fit != isStdCache.end()) { return fit->second.second; }

	std::string filename = sm.getPresumedLoc(loc).getFilename();
	bool isSys = isStdLibHeader(filename);
	isStdCache[sm.getFileID(loc)] = {filename, isSys};
	return isSys;
}
Пример #3
0
	bool HeaderTagger::isDefinedInSystemHeader (const clang::Decl* decl) const {
		return isStdLibHeader(decl->getLocation());
	}
Пример #4
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 "";
		}