Beginning of the Great Exception Handling Rewrite.

* Add a "landing pad" attribute to the BasicBlock.
* Modify the bitcode reader and writer to handle said attribute.

Later: The verifier will ensure that the landing pad attribute is used in the
appropriate manner. I.e., not applied to the entry block, and applied only to
basic blocks that are branched to via a `dispatch' instruction.

(This is a work-in-progress.)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129235 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 857fa1e..da26cb8 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -587,6 +587,8 @@
 
   KEYWORD(x);
   KEYWORD(blockaddress);
+
+  KEYWORD(landingpad);
 #undef KEYWORD
 
   // Keywords for types.
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 0c3237a..afd10a0 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -2918,6 +2918,11 @@
   BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
   if (BB == 0) return true;
 
+  if (Lex.getKind() == lltok::kw_landingpad) {
+    BB->setIsLandingPad();
+    Lex.Lex();
+  }
+
   std::string NameStr;
 
   // Parse the instructions in this block until we get a terminator.
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 576da19..53cf8d8 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -125,6 +125,9 @@
     kw_extractelement, kw_insertelement, kw_shufflevector, kw_getresult,
     kw_extractvalue, kw_insertvalue, kw_blockaddress,
 
+    // Basic block attribute.
+    kw_landingpad,
+
     // Unsigned Valued tokens (UIntVal).
     GlobalID,          // @42
     LocalVarID,        // %42
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 8223f76..2355198 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -714,7 +714,8 @@
 
     // Read a record.
     Record.clear();
-    switch (Stream.ReadRecord(Code, Record)) {
+    unsigned VSTCode = Stream.ReadRecord(Code, Record);
+    switch (VSTCode) {
     default:  // Default behavior: unknown type.
       break;
     case bitc::VST_CODE_ENTRY: {  // VST_ENTRY: [valueid, namechar x N]
@@ -729,13 +730,17 @@
       ValueName.clear();
       break;
     }
-    case bitc::VST_CODE_BBENTRY: {
+    case bitc::VST_CODE_BBENTRY:
+    case bitc::VST_CODE_LPADENTRY: {
       if (ConvertToString(Record, 1, ValueName))
         return Error("Invalid VST_BBENTRY record");
       BasicBlock *BB = getBasicBlock(Record[0]);
       if (BB == 0)
         return Error("Invalid BB ID in VST_BBENTRY record");
 
+      if (VSTCode == bitc::VST_CODE_LPADENTRY)
+        BB->setIsLandingPad(true);
+
       BB->setName(StringRef(ValueName.data(), ValueName.size()));
       ValueName.clear();
       break;
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index e34137f..51c13bd 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -40,6 +40,7 @@
   VST_ENTRY_7_ABBREV,
   VST_ENTRY_6_ABBREV,
   VST_BBENTRY_6_ABBREV,
+  VST_LPADENTRY_6_ABBREV,
 
   // CONSTANTS_BLOCK abbrev id's.
   CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV,
@@ -1179,13 +1180,20 @@
 
     unsigned AbbrevToUse = VST_ENTRY_8_ABBREV;
 
-    // VST_ENTRY:   [valueid, namechar x N]
-    // VST_BBENTRY: [bbid, namechar x N]
+    // VST_ENTRY:     [valueid, namechar x N]
+    // VST_BBENTRY:   [bbid, namechar x N]
+    // VST_LPADENTRY: [lpadid, namechar x N]
     unsigned Code;
-    if (isa<BasicBlock>(SI->getValue())) {
-      Code = bitc::VST_CODE_BBENTRY;
-      if (isChar6)
-        AbbrevToUse = VST_BBENTRY_6_ABBREV;
+    if (const BasicBlock *BB = dyn_cast<BasicBlock>(SI->getValue())) {
+      if (BB->isLandingPad()) {
+        Code = bitc::VST_CODE_LPADENTRY;
+        if (isChar6)
+          AbbrevToUse = VST_LPADENTRY_6_ABBREV;
+      } else {
+        Code = bitc::VST_CODE_BBENTRY;
+        if (isChar6)
+          AbbrevToUse = VST_BBENTRY_6_ABBREV;
+      }
     } else {
       Code = bitc::VST_CODE_ENTRY;
       if (isChar6)
@@ -1366,8 +1374,16 @@
                                    Abbv) != VST_BBENTRY_6_ABBREV)
       llvm_unreachable("Unexpected abbrev ordering!");
   }
-
-
+  { // 6-bit char6 VST_LPADENTRY strings.
+    BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+    Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_LPADENTRY));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
+    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6));
+    if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID,
+                                   Abbv) != VST_LPADENTRY_6_ABBREV)
+      llvm_unreachable("Unexpected abbrev ordering!");
+  }
 
   { // SETTYPE abbrev for CONSTANTS_BLOCK.
     BitCodeAbbrev *Abbv = new BitCodeAbbrev();
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index ffd367a..a92c9bc 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -1687,8 +1687,13 @@
     Out << "\n";
     PrintLLVMName(Out, BB->getName(), LabelPrefix);
     Out << ':';
+    if (BB->isLandingPad())
+      Out << " landingpad";
   } else if (!BB->use_empty()) {      // Don't print block # of no uses...
-    Out << "\n; <label>:";
+    Out << '\n';
+    if (BB->isLandingPad())
+      Out << "landingpad ";
+    Out << "; <label>:";
     int Slot = Machine.getLocalSlot(BB);
     if (Slot != -1)
       Out << Slot;
diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp
index 955a028..b46fab5 100644
--- a/lib/VMCore/BasicBlock.cpp
+++ b/lib/VMCore/BasicBlock.cpp
@@ -38,10 +38,10 @@
 // are not in the public header file...
 template class llvm::SymbolTableListTraits<Instruction, BasicBlock>;
 
-
 BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
                        BasicBlock *InsertBefore)
-  : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0) {
+  : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0),
+    IsLandingPad(false) {
 
   // Make sure that we get added to a function
   LeakDetector::addGarbageObject(this);
@@ -57,7 +57,6 @@
   setName(Name);
 }
 
-
 BasicBlock::~BasicBlock() {
   // If the address of the block is taken and it is being deleted (e.g. because
   // it is dead), this means that there is either a dangling constant expr