{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} -- | Functions for manipulating 'FFI.SourceLocation's, which map a location in a -- translation unit to a location in on-disk or in-memory files. -- -- This module is intended to be imported qualified. module Clang.Location ( -- * Creating locations create , createForOffset , createInvalid -- * Mapping locations to files , getExpansionLocation , getPresumedLocation , getSpellingLocation , getFileLocation -- * Analyzing locations , getCursor , isInSystemHeader , isFromMainFile ) where import Control.Monad.IO.Class import qualified Clang.Internal.FFI as FFI import Clang.Internal.Monad import System.IO.Unsafe (unsafePerformIO) -- | Retrieves a 'FFI.SourceLocation' representing the given location in the source code. create :: ClangBase m => FFI.TranslationUnit s' -- ^ The translation unit. -> FFI.File s'' -- ^ The file. -> Int -- ^ The line. -> Int -- ^ The column. -> ClangT s m (FFI.SourceLocation s) -- ^ A 'FFI.SourceLocation' value representing -- the location. create tu f line col = liftIO $ FFI.getLocation mkProxy tu f line col -- | Like 'create', but uses an offset instead of a line and column. createForOffset :: ClangBase m => FFI.TranslationUnit s' -- ^ The translation unit. -> FFI.File s'' -- ^ The file. -> Int -- ^ The offset. -> ClangT s m (FFI.SourceLocation s) -- ^ A 'FFI.SourceLocation' value -- representing the location. createForOffset tu f off = liftIO $ FFI.getLocationForOffset mkProxy tu f off -- | Creates an invalid 'FFI.SourceLocation'. createInvalid :: ClangBase m => ClangT s m (FFI.SourceLocation s) createInvalid = liftIO $ FFI.getNullLocation mkProxy -- | Retrieves the 'FFI.File', line, column, and offset associated with the given location. -- -- If the location points into a macro expansion, retrieves the location of the macro expansion. -- This may be a position that doesn't exist in the original source. getExpansionLocation :: ClangBase m => FFI.SourceLocation s' -> ClangT s m (Maybe (FFI.File s), Int, Int, Int) getExpansionLocation l = liftIO $ FFI.getExpansionLocation mkProxy l -- | Retrieves the 'FFI.File', line, and column associated with the given location, as -- interpreted by the C preprocessor. -- -- This may differ from the results given by 'getExpansionLocation' because it takes '#line' -- directives into account, which 'getExpansionLocation' ignores. getPresumedLocation :: ClangBase m => FFI.SourceLocation s' -> ClangT s m (FFI.ClangString s, Int, Int) getPresumedLocation = FFI.getPresumedLocation -- | Retrieves the 'FFI.File', line, column, and offset associated with the given location. -- -- If the location points into a macro expansion, returns the corresponding position in the -- original source. This may be where the macro was defined or where it was instantiated, -- depending on what exactly the location points to. getSpellingLocation :: ClangBase m => FFI.SourceLocation s' -> ClangT s m (Maybe (FFI.File s), Int, Int, Int) getSpellingLocation l = liftIO $ FFI.getSpellingLocation mkProxy l -- | Retrieves the 'FFI.File', line, column, and offset associated with the given location. -- -- If the location points into a macro expansion, returns the position where the macro was -- expanded or the position of the macro argument, if the cursor points at a macro argument. getFileLocation :: ClangBase m => FFI.SourceLocation s' -> ClangT s m (Maybe (FFI.File s), Int, Int, Int) getFileLocation l = liftIO $ FFI.getFileLocation mkProxy l -- | Retrieves an AST cursor at the given source location. -- -- The cursor can be traversed using the functions in "Clang.Cursor". getCursor :: ClangBase m => FFI.TranslationUnit s' -> FFI.SourceLocation s'' -> ClangT s m (FFI.Cursor s) getCursor tu sl = liftIO $ FFI.getCursor mkProxy tu sl -- | Returns 'True' if the given location is inside a system header. isInSystemHeader :: FFI.SourceLocation s' -> Bool isInSystemHeader l = unsafePerformIO $ FFI.location_isInSystemHeader l -- | Returns 'True' if the given location is from the main file of the associated translation -- unit. isFromMainFile :: FFI.SourceLocation s' -> Bool isFromMainFile l = unsafePerformIO $ FFI.location_isFromMainFile l