Extending Clang with information and code from external source

Hi all,

I’m attempting to build an external tool on top of Clang which is approximately (but not exactly) a C++ interpreter. Unfortunately, many of the terms used in Clang are quite generic and not searchable- seems like every compiler in the world ever made uses VarDecl as a type name, and I’ve had little luck finding documented examples of the C++ API. On top of that, the (not exactly) parts are causing me quite some headache. To begin with, I’ve been looking at how I’d interpret a simple Hello World program. But I’ve been a little stumped by some of the Sema’s functionality, and have a few questions about how it can be used.

Particularly, there is a function ArgumentDependentLookup which I need to use. But it takes expressions as arguments, rather than types? I thought that the C++ Standard defined ADL in terms of the argument types. More specifically,

How do I convert a VarDecl to an Expr* so that it can be passed to this function? Logically, I want to pass this object, not it’s initializer, and the documentation list only appears to allow me to convert the initializer to an Expr*.

More generally, I’m talking about the “approximately (but not exactly) a C++ interpreter”, and we’re talking about arguments which do not originate from C++ source code and do not have a Clang Expr* to be used, and possibly, there is no C++ equivalent expression that could ever exist- although there is a C+±equivalent argument type. How could I perform ADL for operations for which there is no C++ expression?

I’m also facing fun when describing external types to Clang. For example, a RecordType can only be constructed from a RecordDecl, even if I inherited from RecordType, but no RecordDecl exists, because the description of this type did not come from a C++ file parsed by Clang. It was created externally. Even if I created a RecordDecl, it presents no methods to insert data about the type. This isn’t just POD types, but special members, overloaded operators, and the whole shaboodle. In addition, I’m talking about functions, variables, namespaces, and the whole shaboodle. How can I use Clang’s API to inform it of semantic objects that did not originate from a file parsed by Clang?

I’ve looked at LookupOverloadedOperatorName, but apparently the only valid enum is OO_None. I don’t think that operator<< is None. How is it possible to use this function to look up an operator?

Once the function has been looked up, I’m going to be needing to convert the function to an LLVM representation, like llvm::Function*, so that I can generate code which calls into these functions through LLVM. For complex objects, I can read up on the ABI later, but for now, I wanted to focus on simple objects. So far, I figured that once I look up the name, I can use the MangleContext to mangle it, and then request the llvm::Function* from the llvm::Module based on the mangled name. Then I can generate LLVM code, link to the library and done. But where can I obtain the llvm::Module* from?

Thanks for any assistance.

Hi all,

I'm attempting to build an external tool on top of Clang which is
approximately (but not exactly) a C++ interpreter. Unfortunately, many of
the terms used in Clang are quite generic and not searchable- seems like
every compiler in the world ever made uses VarDecl as a type name, and I've
had little luck finding documented examples of the C++ API. On top of that,
the (not exactly) parts are causing me quite some headache. To begin with,
I've been looking at how I'd interpret a simple Hello World program. But
I've been a little stumped by some of the Sema's functionality, and have a
few questions about how it can be used.

Particularly, there is a function ArgumentDependentLookup which I need to
use. But it takes expressions as arguments, rather than types? I thought
that the C++ Standard defined ADL in terms of the argument types. More
specifically,

How do I convert a VarDecl to an Expr* so that it can be passed to this
function? Logically, I want to pass this object, not it's initializer, and
the documentation list only appears to allow me to convert the initializer
to an Expr*.

you might want to play around with Clang's -ast-dump functionality to
explore the form of ASTs that show you what you're interested in
trying to emulate. In this specific case I believe you'd need a
DeclRefExpr to refer to the VarDecl you have.

More generally, I'm talking about the "approximately (but not exactly) a C++
interpreter", and we're talking about arguments which do not originate from
C++ source code and do not have a Clang Expr* to be used, and possibly,
there is no C++ equivalent expression that could ever exist- although there
is a C++-equivalent argument type. How could I perform ADL for operations
for which there is no C++ expression?

I'm also facing fun when describing external types to Clang. For example, a
RecordType can only be constructed from a RecordDecl, even if I inherited
from RecordType, but no RecordDecl exists, because the description of this
type did not come from a C++ file parsed by Clang. It was created
externally. Even if I created a RecordDecl, it presents no methods to insert
data about the type. This isn't just POD types, but special members,
overloaded operators, and the whole shaboodle.

Perhaps you're looking for CXXRecordDecl? (again, looking at AST dumps
of valid C++ code will help you find the right AST nodes to represent
the constructs you want - if Clang can build an AST from source code,
you can build that same AST with a lot of hand-written/explicit code
to describe a source-less construct. Indeed there are some types that
cannot be written in C++ (see certain C++11 traits and
pseudo-intrinsics like std::initializer_list for the various ways the
compiler has to interact with the library))