Reland the rest of "Add AIX Target Info"

llvm-svn 356197 relanded previously failing test case max_align.c.
This commit will reland the rest of llvm-svn 356060 commit.

Differential Revision: https://reviews.llvm.org/D59048

llvm-svn: 356208
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 43302c6..e6fcf93 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -332,6 +332,8 @@
       return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
     case llvm::Triple::RTEMS:
       return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts);
+    case llvm::Triple::AIX:
+      return new AIXPPC32TargetInfo(Triple, Opts);
     default:
       return new PPC32TargetInfo(Triple, Opts);
     }
@@ -348,6 +350,8 @@
       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+    case llvm::Triple::AIX:
+      return new AIXPPC64TargetInfo(Triple, Opts);
     default:
       return new PPC64TargetInfo(Triple, Opts);
     }
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index c8d4aaa..e8715dc 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -613,6 +613,53 @@
   }
 };
 
+// AIX Target
+template <typename Target>
+class AIXTargetInfo : public OSTargetInfo<Target> {
+protected:
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
+    DefineStd(Builder, "unix", Opts);
+    Builder.defineMacro("_IBMR2");
+    Builder.defineMacro("_POWER");
+
+    // FIXME: Define AIX OS-Version Macros.
+    Builder.defineMacro("_AIX");
+
+    // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
+    Builder.defineMacro("_LONG_LONG");
+
+    if (Opts.POSIXThreads) {
+      Builder.defineMacro("_THREAD_SAFE");
+    }
+
+    if (this->PointerWidth == 64) {
+      Builder.defineMacro("__64BIT__");
+    }
+
+    // Define _WCHAR_T when it is a fundamental type
+    // (i.e., for C++ without -fno-wchar).
+    if (Opts.CPlusPlus && Opts.WChar) {
+      Builder.defineMacro("_WCHAR_T");
+    }
+  }
+
+public:
+  AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+      : OSTargetInfo<Target>(Triple, Opts) {
+    if (this->PointerWidth == 64) {
+      this->WCharType = this->UnsignedInt;
+    } else {
+      this->WCharType = this->UnsignedShort;
+    }
+    this->UseZeroLengthBitfieldAlignment = true;
+  }
+
+  // AIX sets FLT_EVAL_METHOD to be 1.
+  unsigned getFloatEvalMethod() const override { return 1; }
+  bool hasInt128Type() const override { return false; }
+};
+
 // Windows target
 template <typename Target>
 class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 160c5d4..0f99f81 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -100,7 +100,9 @@
     Builder.defineMacro("_CALL_LINUX", "1");
 
   // Subtarget options.
-  Builder.defineMacro("__NATURAL_ALIGNMENT__");
+  if (!getTriple().isOSAIX()){
+    Builder.defineMacro("__NATURAL_ALIGNMENT__");
+  }
   Builder.defineMacro("__REGISTER_PREFIX__", "");
 
   // FIXME: Should be controlled by command line option.
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index ecfc1bc..ace7eb3 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -325,6 +325,12 @@
       PtrDiffType = SignedInt;
       IntPtrType = SignedInt;
       break;
+    case llvm::Triple::AIX:
+      SizeType = UnsignedLong;
+      PtrDiffType = SignedLong;
+      IntPtrType = SignedLong;
+      SuitableAlign = 64;
+      break;
     default:
       break;
     }
@@ -333,6 +339,8 @@
     case llvm::Triple::FreeBSD:
     case llvm::Triple::NetBSD:
     case llvm::Triple::OpenBSD:
+    // FIXME: -mlong-double-128 is not yet supported on AIX.
+    case llvm::Triple::AIX:
       LongDoubleWidth = LongDoubleAlign = 64;
       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
       break;
@@ -373,6 +381,12 @@
       LongDoubleWidth = LongDoubleAlign = 64;
       LongDoubleFormat = &llvm::APFloat::IEEEdouble();
       break;
+    case llvm::Triple::AIX:
+      // FIXME: -mlong-double-128 is not yet supported on AIX.
+      LongDoubleWidth = LongDoubleAlign = 64;
+      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+      SuitableAlign = 64;
+      break;
     default:
       break;
     }
@@ -431,6 +445,21 @@
   }
 };
 
+class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo :
+  public AIXTargetInfo<PPC32TargetInfo> {
+public:
+  using AIXTargetInfo::AIXTargetInfo;
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::CharPtrBuiltinVaList;
+  }
+};
+
+class LLVM_LIBRARY_VISIBILITY AIXPPC64TargetInfo :
+  public AIXTargetInfo<PPC64TargetInfo> {
+public:
+  using AIXTargetInfo::AIXTargetInfo;
+};
+
 } // namespace targets
 } // namespace clang
 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H