Skip to content

Commit 7113cd9

Browse files
committed
Add C++ instrumentation support
This commit adds the main chunks of C++ instrumentation support. We also use this as an opportunity to refactor parts of the instrumentation process, to avoid quite a lot of code duplication. TN: V816-018 Change-Id: Idaf4be20c0df9b532008a914a7b08f08366fb87c
1 parent 6c7463c commit 7113cd9

15 files changed

+676
-278
lines changed

testsuite/SUITE/tutils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -605,14 +605,14 @@ def xcov(args, out=None, err=None, inp=None, env=None, register_failure=True,
605605
covcmd = args[0]
606606
covargs = args[1:]
607607

608-
# gnatcov testsuite exercises C instrumentation, which is not activated by
609-
# default.
608+
# gnatcov testsuite exercises C/C++ instrumentation, which are not
609+
# activated by default.
610610
if (
611611
auto_languages
612612
and not thistest.options.qualif_level
613613
and covcmd == "instrument"
614614
):
615-
covargs = ['--restricted-to-languages=Ada,C'] + covargs
615+
covargs = ['--restricted-to-languages=Ada,C,C++'] + covargs
616616

617617
if thistest.options.all_warnings:
618618
covargs = ['--all-warnings'] + covargs

tools/gnatcov/clang-wrapper.cc

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
#include "clang-c/Index.h"
3131
#include "clang-c/Rewrite.h"
3232
#include "clang/AST/ASTContext.h"
33+
#include "clang/AST/ExprCXX.h"
3334
#include "clang/AST/ParentMapContext.h"
35+
#include "clang/AST/StmtCXX.h"
3436
#include "clang/Basic/SourceLocation.h"
3537
#include "clang/Basic/SourceManager.h"
3638
#include "clang/Frontend/ASTUnit.h"
@@ -96,24 +98,55 @@ clang_getBody (CXCursor C)
9698
if (clang_isDeclaration (C.kind))
9799
{
98100
if (const Decl *D = cxcursor::getCursorDecl (C))
99-
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
100-
if (FD->doesThisDeclarationHaveABody ())
101-
return MakeCXCursorWithNull (FD->getBody (), C);
101+
switch (D->getKind ())
102+
{
103+
case Decl::FunctionTemplate:
104+
return MakeCXCursorWithNull (
105+
cast<FunctionTemplateDecl> (D)->getTemplatedDecl ()->getBody (),
106+
C);
107+
case Decl::Function:
108+
case Decl::CXXMethod:
109+
case Decl::CXXConstructor:
110+
case Decl::CXXDestructor:
111+
case Decl::CXXConversion:
112+
{
113+
const FunctionDecl *FD = cast<FunctionDecl> (D);
114+
if (FD->doesThisDeclarationHaveABody ())
115+
return MakeCXCursorWithNull (FD->getBody (), C);
116+
break;
117+
}
118+
default:
119+
return MakeCXCursorWithNull (D->getBody (), C);
120+
}
102121
}
103122
else if (clang_isStatement (C.kind))
104-
if (const Stmt *S = cxcursor::getCursorStmt (C))
105-
switch (S->getStmtClass ())
123+
{
124+
if (const Stmt *S = cxcursor::getCursorStmt (C))
125+
switch (S->getStmtClass ())
126+
{
127+
case Stmt::WhileStmtClass:
128+
return MakeCXCursorWithNull (cast<WhileStmt> (S)->getBody (), C);
129+
case Stmt::ForStmtClass:
130+
return MakeCXCursorWithNull (cast<ForStmt> (S)->getBody (), C);
131+
case Stmt::CXXForRangeStmtClass:
132+
return MakeCXCursorWithNull
133+
(cast<CXXForRangeStmt> (S)->getBody (), C);
134+
case Stmt::DoStmtClass:
135+
return MakeCXCursorWithNull (cast<DoStmt> (S)->getBody (), C);
136+
case Stmt::SwitchStmtClass:
137+
return MakeCXCursorWithNull (cast<SwitchStmt> (S)->getBody (), C);
138+
default:
139+
return clang_getNullCursor ();
140+
}
141+
}
142+
else if (clang_isExpression (C.kind))
143+
if (const Expr *E = cxcursor::getCursorExpr (C))
144+
switch (E->getStmtClass ())
106145
{
107-
default:
108-
return clang_getNullCursor ();
109-
case Stmt::WhileStmtClass:
110-
return MakeCXCursorWithNull (cast<WhileStmt> (S)->getBody (), C);
111-
case Stmt::ForStmtClass:
112-
return MakeCXCursorWithNull (cast<ForStmt> (S)->getBody (), C);
113-
case Stmt::DoStmtClass:
114-
return MakeCXCursorWithNull (cast<DoStmt> (S)->getBody (), C);
115-
case Stmt::SwitchStmtClass:
116-
return MakeCXCursorWithNull (cast<SwitchStmt> (S)->getBody (), C);
146+
case Expr::LambdaExprClass:
147+
return MakeCXCursorWithNull (cast<LambdaExpr> (E)->getBody (), C);
148+
default:
149+
return clang_getNullCursor ();
117150
}
118151
return clang_getNullCursor ();
119152
}
@@ -295,17 +328,36 @@ clang_getOperatorLoc (CXCursor C)
295328
return cxloc::translateSourceLocation (CXXUnit->getASTContext (), sloc);
296329
}
297330

298-
/* If the given expression is a paren expression, return the outermost
299-
expression inside that is not a paren expression. */
331+
/* If the given expression is a wrapping expression (i.e. a parenthesized
332+
expression, a cast expression etc.), return the outermost expression inside
333+
that is not a wrapping expression. */
300334

301335
extern "C" CXCursor
302336
clang_unwrap (CXCursor C)
303337
{
304338
if (clang_isExpression (C.kind))
305339
if (const Stmt *S = cxcursor::getCursorStmt (C))
306-
if (S->getStmtClass () == Stmt::ParenExprClass)
307-
return clang_unwrap (
308-
MakeCXCursorWithNull (cast<ParenExpr> (S)->getSubExpr (), C));
340+
switch (S->getStmtClass ())
341+
{
342+
case Stmt::ParenExprClass:
343+
return clang_unwrap
344+
(MakeCXCursorWithNull (cast<ParenExpr> (S)->getSubExpr (), C));
345+
case Expr::ConstantExprClass:
346+
case Expr::ExprWithCleanupsClass:
347+
return clang_unwrap
348+
(MakeCXCursorWithNull (cast<FullExpr> (S)->getSubExpr (), C));
349+
case Expr::ImplicitCastExprClass:
350+
case Expr::CStyleCastExprClass:
351+
case Expr::CXXFunctionalCastExprClass:
352+
case Expr::CXXStaticCastExprClass:
353+
case Expr::CXXDynamicCastExprClass:
354+
case Expr::CXXReinterpretCastExprClass:
355+
case Expr::CXXConstCastExprClass:
356+
case Expr::CXXAddrspaceCastExprClass:
357+
return clang_unwrap
358+
(MakeCXCursorWithNull (cast<CastExpr> (S)->getSubExpr (), C));
359+
360+
}
309361
return C;
310362
}
311363

tools/gnatcov/command_line.ads

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ package Command_Line is
143143
Opt_Shared_Object,
144144
Opt_Restricted_To_Languages,
145145
Opt_Annotation_Format,
146-
Opt_C_Opts);
146+
Opt_C_Opts,
147+
Opt_CPP_Opts);
147148
-- Set of string list options we support. More complete descriptions below.
148149

149150
package Parser is new Argparse
@@ -1088,7 +1089,16 @@ package Command_Line is
10881089
"List of additional compiler switches to analayze C source"
10891090
& " files.",
10901091
Commands => (Cmd_Instrument => True, others => False),
1091-
Internal => False)
1092+
Internal => False),
1093+
1094+
Opt_CPP_Opts => Create
1095+
(Long_Name => "--c++-opts",
1096+
Pattern => "[COMMA-SEPARATED-OPTIONS]",
1097+
Help =>
1098+
"List of additional compiler switches to analayze C++ source"
1099+
& " files.",
1100+
Commands => (Cmd_Instrument => True, others => False),
1101+
Internal => False)
10921102
);
10931103

10941104
procedure Bool_Callback

tools/gnatcov/instrument-ada_unit.adb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ with SCOs;
4646
with Slocs;
4747
with Snames; use Snames;
4848
with Strings; use Strings;
49-
with Switches;
5049
with Table;
5150
with Text_Files; use Text_Files;
5251

tools/gnatcov/instrument-ada_unit.ads

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ with Libadalang.Rewriting; use Libadalang.Rewriting;
3131
with Instrument.Base_Types; use Instrument.Base_Types;
3232
with Instrument.Common; use Instrument.Common;
3333
with SC_Obligations; use SC_Obligations;
34+
with Switches;
3435
with Types; use Types;
3536

3637
package Instrument.Ada_Unit is
@@ -39,6 +40,10 @@ package Instrument.Ada_Unit is
3940
null record;
4041
-- Instrumentation primitives for Ada
4142

43+
overriding function Language
44+
(Self : Ada_Instrumenter_Type) return Switches.Src_Supported_Language
45+
is (Switches.Ada_Language);
46+
4247
overriding procedure Instrument_Unit
4348
(Self : Ada_Instrumenter_Type;
4449
CU_Name : Compilation_Unit_Name;

tools/gnatcov/instrument-base_types.adb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ package body Instrument.Base_Types is
3535
begin
3636
return (case Language is
3737
when Ada_Language => Unit_Based_Language,
38-
when C_Language => File_Based_Language);
38+
when C_Language
39+
| CPP_Language => File_Based_Language);
3940
end Language_Kind;
4041

4142
------------

0 commit comments

Comments
 (0)