Need template help building clang 3.4.2 on OpenVMS so we can bootstrap

Summary: I need some help building an older clang. I'm getting errors
with casts inside of clang/include/clang/AST/DeclBase.h. I've hit the
limit of my template programming knowledge (not that deep to begin with)
and am looking for workarounds/suggestions. I'm not even sure if it is
the Casting.h support itself or the usage of it inside clang's DeclBase.h

Background: We're porting OpenVMS to x86 using LLVM. Our build
environment is OpenVMS Itanium using an old EDG/Intel C++ compiler
(allegedly C++03). I've been able to build LLVM 3.4.2 just fine (with
only minor tweaks) and we're using that backend with our legacy
frontends. I'm now needing to also build the matching clang 3.4.2 so I
can start the bootstrapping process to get us to a newer version on our
native systems.

Should clang 3.4.2 be buildable by a C++03 compiler like LLVM is?
That's my understanding. Or is it something in LLVM's Support/Casting.h
that only clang exploits?

Any template experts to help me resolve these just so we can bootstrap?
We're looking to use clang/LLVM 3.4.2 to build 3.8.0 as the next step
(we don't have CMake on OpenVMS Itanium due to old C++ compiler)

Thanks for helping!

John

On my first build attempt (we have a bash shell, make, etc. on OpenVMS),
I got errors compiling ParseAST.cpp. Including "incomplete type is not
allowed" and "explicit specialization of class "..." must precede its
first use. Which I resolved with adding an explicit #include
"clang/AST/DeclBase.h" in ParseAST.cpp prior to the other #include's.

Then that yielded

    return To::classof(&Val);
...............^
%CXX-E-NOTMEMBER, class "clang::Decl" has no member "classof"
          detected during:
            instantiation of "bool llvm::isa_impl<To, From,
                      >::doit(const From &) [with To=clang::Decl,

From=llvm::remove_pointer<llvm::simplify_type<clang::Decl
                      Context *const>::NonConstSimpleType>::type,
                      Enabler=void]" at line 98 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa_impl_cl<To, const From
                      *>::doit(const From *) [with To=clang::Decl,

From=llvm::remove_pointer<llvm::simplify_type<clang::Decl
                      Context *const>::NonConstSimpleType>::type]" at
line 124
                      of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa_impl_wrap<To, FromTy,
                      >::doit(const FromTy &) [with To=clang::Decl,
                      FromTy=llvm::simplify_type<clang::DeclContext
                      *const>::SimpleType]" at line 114 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa_impl_wrap<To, From,
                      >::doit(const From &) [with To=clang::Decl,
                      From=clang::DeclContext *const,
                      SimpleFrom=llvm::simplify_type<clang::DeclContext
                      *const>::SimpleType]" at line 135 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa<X,Y>(const Y &) [with
                      X=clang::Decl, Y=clang::DeclContext *]" at line 239 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "llvm::cast_retty<X, Y *>::ret_type
                      llvm::cast<X,Y>(Y *) [with X=clang::Decl,
                      Y=clang::DeclContext]" at line 1064 of

"LLVM$:[REAGAN.llvm-342.tools.clang.include.clang.AST]Dec
                      lBase.h;1"
at line number 55 in file
LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1

The offending source in DeclBase.h is

  /// getParent - Returns the containing DeclContext.
  DeclContext *getParent() {
    return cast<Decl>(this)->getDeclContext();
-----------^^^^^^^^^^^^
  }
  const DeclContext *getParent() const {
    return const_cast<DeclContext*>(this)->getParent();
  }

So I guessed (perhaps wrongly?) that my host compiler wanted to see a
classof() for clang::Decl so I added this to DeclBase.h in Decl's public
section which matches what is done for DeclContext's classof().

  static bool classof(const Decl *D) { return true; }

but that ended up with:

    return To::classof(&Val);
.......................^
%CXX-E-INCOMPATIBLEPRM, argument of type "const
          llvm::remove_pointer<llvm::simplify_type<clang::DeclContext
          *const>::NonConstSimpleType>::type *" is incompatible with
parameter
          of type "const clang::Decl *"
          detected during:
            instantiation of "bool llvm::isa_impl<To, From,
                      >::doit(const From &) [with To=clang::Decl,

From=llvm::remove_pointer<llvm::simplify_type<clang::Decl
                      Context *const>::NonConstSimpleType>::type,
                      Enabler=void]" at line 98 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa_impl_cl<To, const From
                      *>::doit(const From *) [with To=clang::Decl,

From=llvm::remove_pointer<llvm::simplify_type<clang::Decl
                      Context *const>::NonConstSimpleType>::type]" at
line 124
                      of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa_impl_wrap<To, FromTy,
                      >::doit(const FromTy &) [with To=clang::Decl,
                      FromTy=llvm::simplify_type<clang::DeclContext
                      *const>::SimpleType]" at line 114 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa_impl_wrap<To, From,
                      >::doit(const From &) [with To=clang::Decl,
                      From=clang::DeclContext *const,
                      SimpleFrom=llvm::simplify_type<clang::DeclContext
                      *const>::SimpleType]" at line 135 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "bool llvm::isa<X,Y>(const Y &) [with
                      X=clang::Decl, Y=clang::DeclContext *]" at line 239 of

"LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1"
            instantiation of "llvm::cast_retty<X, Y *>::ret_type
                      llvm::cast<X,Y>(Y *) [with X=clang::Decl,
                      Y=clang::DeclContext]" at line 1073 of

"LLVM$:[REAGAN.llvm-342.tools.clang.include.clang.AST]Dec
                      lBase.h;2"
at line number 55 in file
LLVM$:[REAGAN.llvm-342.include.llvm.Support]Casting.h;1

and still lots of other errors of the form

LEAF_TYPE(Enum)
^
%CXX-E-NOCONVERSIONFUN, no suitable conversion function from
          "const clang::EnumType" to "const clang::EnumType *" exists
at line number 115 in file
LLVM$:[REAGAN.llvm-342.tools.clang.include.clang.AST]TypeNodes.def;1

and more "incomplete type is not allowed" errors.

And why is there very different form of non-const vs const for things
like getParent() and getLexicalParent()?

The way it's supposed to work is via template specialization; there's a declaration "struct isa_impl<To, ::clang::DeclContext>" at the bottom of DeclBase.h which is supposed to be used. Not sure why your compiler doesn't like it. Maybe it's instantiating the template before it sees the specialization? Or maybe it's failing to find the specialization when it instantiates the template? Not sure. I guess in that particular context, you could explicitly call Decl::castFromDeclContext, but I'm not sure how many other places would need to be fixed.

Have you considered cross-compiling instead? That seems like less work than porting multiple versions of LLVM to OpenVMS.

-Eli

Thanks. I'll play some more. I suspect our ancient EDG frontend has a
bug. I have a newer EDG drop but there is zero chance I could
cherry-pick the right set of fixes from the hundreds of changes between
the two.

As for cross-compiling, I've been thinking about that too. We were
hoping to get an Itanium-hosted cross-compiler like we have our legacy
C, BLISS, and Macro-32 compilers, but we don't need that for the OS
build/boot path. Our initial customer EAK is with Itanium-hosted
cross-compilers for the above mentioned and our other legacy frontends.
It is C++ that is the odd language out. I'll discuss with my team and
technical director.

We are using the AMD64 ABI with a few minor OpenVMS tweaks. I could
easily build a clang/LLVM 3.4.2 with those changes on Linux and then use
*that* compiler to build something, yank the objects over to an OpenVMS
x86 box (once available and stable), and then link them native. (Our
linker is also tolerant of non-OpenVMS objects too)