Fix alignment issues in Clang.

Some const-correctness changes snuck in here too, since they were in the
area of code I was modifying.

This seems to make Clang actually work without Bus Error on
32bit-sparc.

Follow-up patches will factor out a trailing-object helper class, to
make classes using the idiom of appending objects to other objects
easier to understand, and to ensure (with static_assert) that required
alignment guarantees continue to hold.

Differential Revision: http://reviews.llvm.org/D10272

llvm-svn: 242554
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 4fcec53..e772f19 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -45,10 +45,19 @@
   getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
 }
 
+#define DECL(DERIVED, BASE)                                                    \
+  static_assert(Decl::DeclObjAlignment >=                                      \
+                    llvm::AlignOf<DERIVED##Decl>::Alignment,                   \
+                "Alignment sufficient after objects prepended to " #DERIVED);
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
+
 void *Decl::operator new(std::size_t Size, const ASTContext &Context,
                          unsigned ID, std::size_t Extra) {
   // Allocate an extra 8 bytes worth of storage, which ensures that the
-  // resulting pointer will still be 8-byte aligned. 
+  // resulting pointer will still be 8-byte aligned.
+  static_assert(sizeof(unsigned) * 2 >= DeclObjAlignment,
+                "Decl won't be misaligned");
   void *Start = Context.Allocate(Size + Extra + 8);
   void *Result = (char*)Start + 8;
 
@@ -69,7 +78,13 @@
   // With local visibility enabled, we track the owning module even for local
   // declarations.
   if (Ctx.getLangOpts().ModulesLocalVisibility) {
-    void *Buffer = ::operator new(sizeof(Module *) + Size + Extra, Ctx);
+    // Ensure required alignment of the resulting object by adding extra
+    // padding at the start if required.
+    size_t ExtraAlign =
+        llvm::OffsetToAlignment(sizeof(Module *), DeclObjAlignment);
+    char *Buffer = reinterpret_cast<char *>(
+        ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));
+    Buffer += ExtraAlign;
     return new (Buffer) Module*(nullptr) + 1;
   }
   return ::operator new(Size + Extra, Ctx);