Skip to content

Commit b666213

Browse files
committed
Issue 108: Remove logic to find LLVM in linux OSes. Only appears in Darwin. And also add some test cases.
Signed-off-by: Rahul Krishna <[email protected]>
1 parent b9b9eba commit b666213

File tree

17 files changed

+396
-389
lines changed

17 files changed

+396
-389
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ lint: ## Run the linter
3131
.PHONY: test
3232
test: ## Run the unit tests
3333
$(info Running tests...)
34-
pytest --pspec --cov=cldk --cov-fail-under=50 --disable-warnings
34+
pytest --pspec --cov=cldk --cov-fail-under=75 --disable-warnings
3535

3636
##@ Build
3737

cldk/analysis/c/c_analysis.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
Analysis model for C projects
1919
"""
2020

21+
import os
2122
from pathlib import Path
2223
from typing import Dict, List, Optional
2324
import networkx as nx
2425

25-
2626
from cldk.analysis.c.clang import ClangAnalyzer
2727
from cldk.models.c import CApplication, CFunction, CTranslationUnit, CMacro, CTypedef, CStruct, CEnum, CVariable
2828

@@ -36,7 +36,7 @@ def __init__(self, project_dir: Path) -> None:
3636
self.c_application = self._init_application(project_dir)
3737

3838
def _init_application(self, project_dir: Path) -> CApplication:
39-
"""Initializes the C application object.
39+
"""Should initialize the C application object.
4040
4141
Args:
4242
project_dir (Path): Path to the project directory.

cldk/analysis/c/clang/clang_analyzer.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from pdb import set_trace
23
import platform
34
from clang.cindex import Config
45
from pathlib import Path
@@ -19,16 +20,27 @@ class ClangAnalyzer:
1920
"""Analyzes C code using Clang's Python bindings."""
2021

2122
def __init__(self, compilation_database_path: Optional[Path] = None):
23+
# # Let's turn off Address sanitization for parsing code
24+
# # Initialize libclang at module level
25+
# try:
26+
if platform.system() == "Darwin":
27+
possible_paths = [
28+
"/opt/homebrew/opt/llvm/lib/libclang.dylib", # Apple Silicon
29+
"/usr/local/opt/llvm/lib/libclang.dylib", # Intel Mac
30+
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libclang.dylib",
31+
]
2232

23-
# Initialize libclang at module level
24-
try:
25-
Config.set_library_file(self.__find_libclang())
26-
except Exception as e:
27-
logger.error(f"Failed to initialize libclang: {e}")
28-
raise Exception("Failed to initialize libclang")
33+
# We could not find libclang. Raise an error and provide instructions.
34+
if len(possible_paths) == 0:
35+
raise RuntimeError("Install LLVM 18 using: brew install llvm@18")
36+
37+
# Check each possible path and return the first one that exists
38+
for path in possible_paths:
39+
if os.path.exists(path):
40+
logger.info(f"Found libclang at: {path}")
41+
# Configure Clang before creating the Index
42+
Config.set_library_file(path)
2943

30-
logger.info("Successfully initialized libclang")
31-
# Configure Clang before creating the Index
3244
self.index = Index.create()
3345
self.compilation_database = None
3446
# TODO: Implement compilation database for C/C++ projects so that we can get compile arguments for each file
@@ -59,8 +71,8 @@ def __find_libclang(self) -> str:
5971
from pathlib import Path
6072

6173
lib_paths = [Path("/usr/lib"), Path("/usr/lib64")]
62-
possible_paths = [str(p) for base in lib_paths if base.exists() for p in base.rglob("libclang*.so*")]
63-
74+
possible_paths = [str(p) for base in lib_paths if base.exists() for p in base.rglob("libclang*.so.17*")]
75+
print(possible_paths)
6476
install_instructions = "Install libclang development package using your system's package manager"
6577
else:
6678
raise RuntimeError(f"Unsupported operating system: {system}")
@@ -98,7 +110,7 @@ def analyze_file(self, file_path: Path) -> CTranslationUnit:
98110
return translation_unit
99111

100112
def _process_translation_unit(self, cursor, translation_unit: CTranslationUnit):
101-
"""Processes all declarations in a translation unit."""
113+
"""Should process all declarations in a translation unit."""
102114

103115
for child in cursor.get_children():
104116
if child.location.file and str(child.location.file) != translation_unit.file_path:

cldk/analysis/java/codeanalyzer/codeanalyzer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def _get_codeanalyzer_exec(self) -> List[str]:
153153

154154
@staticmethod
155155
def _init_japplication(data: str) -> JApplication:
156-
"""return JApplication giving the stringified JSON as input.
156+
"""Should return JApplication giving the stringified JSON as input.
157157
Returns
158158
-------
159159
JApplication
@@ -165,7 +165,7 @@ def _init_japplication(data: str) -> JApplication:
165165
return JApplication(**json.loads(data))
166166

167167
def _init_codeanalyzer(self, analysis_level=1) -> JApplication:
168-
"""Initializes the Codeanalyzer.
168+
"""Should initialize the Codeanalyzer.
169169
170170
Args:
171171
analysis_level (int): The level of analysis to be performed (1 for symbol table, 2 for call graph).
@@ -657,7 +657,7 @@ def get_class_call_graph_using_symbol_table(self, qualified_class_name: str, met
657657
return graph_edges
658658

659659
def __call_graph_using_symbol_table(self, qualified_class_name: str, method_signature: str, is_target_method: bool = False) -> nx.DiGraph:
660-
"""Generate call graph using symbol table
660+
"""Should generate call graph using symbol table
661661
Args:
662662
qualified_class_name: qualified class name
663663
method_signature: method signature

cldk/analysis/java/codeql/codeql.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def __init__(self, project_dir: Union[str, Path], codeql_db: Union[str, Path, No
7474

7575
@staticmethod
7676
def _init_codeql_db(project_dir: Union[str, Path], codeql_db: Union[str, Path, None]) -> Path:
77-
"""Initializes the CodeQL database.
77+
"""Should initialize the CodeQL database.
7878
7979
Parameters
8080
----------

cldk/analysis/java/treesitter/java_sitter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def safe_ascend(self, node: Node, ascend_count: int) -> Node:
229229
return self.safe_ascend(node.parent, ascend_count - 1)
230230

231231
def get_call_targets(self, method_body: str, declared_methods: dict) -> Set[str]:
232-
"""Generate a list of call targets from the method body.
232+
"""Should generate a list of call targets from the method body.
233233
234234
Uses simple name resolution for finding the call targets. Nothing sophisticated here. Just a simple search
235235
over the AST.

cldk/models/treesitter/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ def __getitem__(self, index: int) -> Capture:
6666
return self.captures[index]
6767

6868
def __iter__(self):
69-
"""return an iterator over the captures."""
69+
"""Should return an iterator over the captures."""
7070
return iter(self.captures)
7171

7272
def __len__(self) -> int:
73-
"""return the number of captures."""
73+
"""Should return the number of captures."""
7474
return len(self.captures)
7575

7676
def __add__(self, other: "Captures") -> "Captures":

0 commit comments

Comments
 (0)