Skip to content

Commit 8573b28

Browse files
author
emilio
committed
[libclang] Expose some target information via the C API.
This allows users to query the target triple and target pointer width, which would make me able to fix rust-lang/rust-bindgen#593 and other related bugs in an elegant way (without having to manually parse the target triple in the command line arguments). Differential Revision: https://reviews.llvm.org/D32389 llvm-svn=301648
1 parent add3046 commit 8573b28

File tree

6 files changed

+146
-3
lines changed

6 files changed

+146
-3
lines changed

clang/include/clang-c/Index.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
3333
*/
3434
#define CINDEX_VERSION_MAJOR 0
35-
#define CINDEX_VERSION_MINOR 37
35+
#define CINDEX_VERSION_MINOR 38
3636

3737
#define CINDEX_VERSION_ENCODE(major, minor) ( \
3838
((major) * 10000) \
@@ -80,6 +80,12 @@ extern "C" {
8080
*/
8181
typedef void *CXIndex;
8282

83+
/**
84+
* \brief An opaque type representing target information for a given translation
85+
* unit.
86+
*/
87+
typedef struct CXTargetInfoImpl *CXTargetInfo;
88+
8389
/**
8490
* \brief A single translation unit, which resides in an index.
8591
*/
@@ -1552,6 +1558,36 @@ CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU
15521558

15531559
CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage);
15541560

1561+
/**
1562+
* \brief Get target information for this translation unit.
1563+
*
1564+
* The CXTargetInfo object cannot outlive the CXTranslationUnit object.
1565+
*/
1566+
CINDEX_LINKAGE CXTargetInfo
1567+
clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit);
1568+
1569+
/**
1570+
* \brief Destroy the CXTargetInfo object.
1571+
*/
1572+
CINDEX_LINKAGE void
1573+
clang_TargetInfo_dispose(CXTargetInfo Info);
1574+
1575+
/**
1576+
* \brief Get the normalized target triple as a string.
1577+
*
1578+
* Returns the empty string in case of any error.
1579+
*/
1580+
CINDEX_LINKAGE CXString
1581+
clang_TargetInfo_getTriple(CXTargetInfo Info);
1582+
1583+
/**
1584+
* \brief Get the pointer width of the target in bits.
1585+
*
1586+
* Returns -1 in case of error.
1587+
*/
1588+
CINDEX_LINKAGE int
1589+
clang_TargetInfo_getPointerWidth(CXTargetInfo Info);
1590+
15551591
/**
15561592
* @}
15571593
*/

clang/test/Index/target-info.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: c-index-test -test-print-target-info %s --target=i386-unknown-linux-gnu | FileCheck %s
2+
// RUN: c-index-test -test-print-target-info %s --target=x86_64-unknown-linux-gnu | FileCheck --check-prefix=CHECK-1 %s
3+
// CHECK: TargetTriple: i386-unknown-linux-gnu
4+
// CHECK: PointerWidth: 32
5+
// CHECK-1: TargetTriple: x86_64-unknown-linux-gnu
6+
// CHECK-1: PointerWidth: 64

clang/tools/c-index-test/c-index-test.c

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,51 @@ static enum CXChildVisitResult PrintTypeDeclaration(CXCursor cursor, CXCursor p,
15591559
return CXChildVisit_Recurse;
15601560
}
15611561

1562+
/******************************************************************************/
1563+
/* Target information testing. */
1564+
/******************************************************************************/
1565+
1566+
static int print_target_info(int argc, const char **argv) {
1567+
CXIndex Idx;
1568+
CXTranslationUnit TU;
1569+
CXTargetInfo TargetInfo;
1570+
CXString Triple;
1571+
const char *FileName;
1572+
enum CXErrorCode Err;
1573+
int PointerWidth;
1574+
1575+
if (argc == 0) {
1576+
fprintf(stderr, "No filename specified\n");
1577+
return 1;
1578+
}
1579+
1580+
FileName = argv[1];
1581+
1582+
Idx = clang_createIndex(0, 1);
1583+
Err = clang_parseTranslationUnit2(Idx, FileName, argv, argc, NULL, 0,
1584+
getDefaultParsingOptions(), &TU);
1585+
if (Err != CXError_Success) {
1586+
fprintf(stderr, "Couldn't parse translation unit!\n");
1587+
describeLibclangFailure(Err);
1588+
clang_disposeIndex(Idx);
1589+
return 1;
1590+
}
1591+
1592+
TargetInfo = clang_getTranslationUnitTargetInfo(TU);
1593+
1594+
Triple = clang_TargetInfo_getTriple(TargetInfo);
1595+
printf("TargetTriple: %s\n", clang_getCString(Triple));
1596+
clang_disposeString(Triple);
1597+
1598+
PointerWidth = clang_TargetInfo_getPointerWidth(TargetInfo);
1599+
printf("PointerWidth: %d\n", PointerWidth);
1600+
1601+
clang_TargetInfo_dispose(TargetInfo);
1602+
clang_disposeTranslationUnit(TU);
1603+
clang_disposeIndex(Idx);
1604+
return 0;
1605+
}
1606+
15621607
/******************************************************************************/
15631608
/* Loading ASTs/source. */
15641609
/******************************************************************************/
@@ -4301,11 +4346,12 @@ static void print_usage(void) {
43014346
" c-index-test -test-print-type {<args>}*\n"
43024347
" c-index-test -test-print-type-size {<args>}*\n"
43034348
" c-index-test -test-print-bitwidth {<args>}*\n"
4349+
" c-index-test -test-print-target-info {<args>}*\n"
43044350
" c-index-test -test-print-type-declaration {<args>}*\n"
43054351
" c-index-test -print-usr [<CursorKind> {<args>}]*\n"
4306-
" c-index-test -print-usr-file <file>\n"
4307-
" c-index-test -write-pch <file> <compiler arguments>\n");
4352+
" c-index-test -print-usr-file <file>\n");
43084353
fprintf(stderr,
4354+
" c-index-test -write-pch <file> <compiler arguments>\n"
43094355
" c-index-test -compilation-db [lookup <filename>] database\n");
43104356
fprintf(stderr,
43114357
" c-index-test -print-build-session-timestamp\n");
@@ -4411,6 +4457,8 @@ int cindextest_main(int argc, const char **argv) {
44114457
return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL);
44124458
else if (argc > 2 && strcmp(argv[1], "-test-print-manglings") == 0)
44134459
return perform_test_load_tu(argv[2], "all", NULL, PrintManglings, NULL);
4460+
else if (argc > 2 && strcmp(argv[1], "-test-print-target-info") == 0)
4461+
return print_target_info(argc - 2, argv + 2);
44144462
else if (argc > 1 && strcmp(argv[1], "-print-usr") == 0) {
44154463
if (argc > 2)
44164464
return print_usrs(argv + 2, argv + argc);

clang/tools/libclang/CIndex.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "clang/Basic/Diagnostic.h"
2727
#include "clang/Basic/DiagnosticCategories.h"
2828
#include "clang/Basic/DiagnosticIDs.h"
29+
#include "clang/Basic/TargetInfo.h"
2930
#include "clang/Basic/Version.h"
3031
#include "clang/Frontend/ASTUnit.h"
3132
#include "clang/Frontend/CompilerInstance.h"
@@ -4018,6 +4019,50 @@ CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
40184019
return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
40194020
}
40204021

4022+
CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4023+
if (isNotUsableTU(CTUnit)) {
4024+
LOG_BAD_TU(CTUnit);
4025+
return nullptr;
4026+
}
4027+
4028+
CXTargetInfoImpl* impl = new CXTargetInfoImpl();
4029+
impl->TranslationUnit = CTUnit;
4030+
return impl;
4031+
}
4032+
4033+
CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4034+
if (!TargetInfo)
4035+
return cxstring::createEmpty();
4036+
4037+
CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4038+
assert(!isNotUsableTU(CTUnit) &&
4039+
"Unexpected unusable translation unit in TargetInfo");
4040+
4041+
ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4042+
std::string Triple =
4043+
CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
4044+
return cxstring::createDup(Triple);
4045+
}
4046+
4047+
int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4048+
if (!TargetInfo)
4049+
return -1;
4050+
4051+
CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4052+
assert(!isNotUsableTU(CTUnit) &&
4053+
"Unexpected unusable translation unit in TargetInfo");
4054+
4055+
ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4056+
return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4057+
}
4058+
4059+
void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4060+
if (!TargetInfo)
4061+
return;
4062+
4063+
delete TargetInfo;
4064+
}
4065+
40214066
//===----------------------------------------------------------------------===//
40224067
// CXFile Operations.
40234068
//===----------------------------------------------------------------------===//

clang/tools/libclang/CXTranslationUnit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ struct CXTranslationUnitImpl {
3535
clang::index::CommentToXMLConverter *CommentToXML;
3636
};
3737

38+
struct CXTargetInfoImpl {
39+
CXTranslationUnit TranslationUnit;
40+
};
41+
3842
namespace clang {
3943
namespace cxtu {
4044

clang/tools/libclang/libclang.exports

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ clang_TParamCommandComment_getParamName
7979
clang_TParamCommandComment_isParamPositionValid
8080
clang_TParamCommandComment_getDepth
8181
clang_TParamCommandComment_getIndex
82+
clang_TargetInfo_dispose
83+
clang_TargetInfo_getPointerWidth
84+
clang_TargetInfo_getTriple
8285
clang_Type_getAlignOf
8386
clang_Type_getClassType
8487
clang_Type_getSizeOf
@@ -250,6 +253,7 @@ clang_getTokenLocation
250253
clang_getTokenSpelling
251254
clang_getTranslationUnitCursor
252255
clang_getTranslationUnitSpelling
256+
clang_getTranslationUnitTargetInfo
253257
clang_getTypeDeclaration
254258
clang_getTypeKindSpelling
255259
clang_getTypeSpelling

0 commit comments

Comments
 (0)