Fix a couple of bugs, add some new cool stuff.

1. Fix a todo in Parser::ParseTag, to recover better.  On code like
   that in test/Sema/decl-invalid.c it causes us to return a single
   error instead of multiple.
2. Fix an error in Sema::ParseDeclarator, where it would crash if the
   declarator didn't have an identifier.  Instead, diagnose the problem.
3. Start adding infrastructure to track the range of locations covered
   by a declspec or declarator.  This is mostly implemented for declspec,
   but could be improved, it is missing for declarator.

Thanks to Neil for pointing out this crash.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40482 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Builtins.cpp b/AST/Builtins.cpp
new file mode 100644
index 0000000..454085b
--- /dev/null
+++ b/AST/Builtins.cpp
@@ -0,0 +1,125 @@
+//===--- Builtins.cpp - Builtin function implementation -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements various things for builtin functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Builtins.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Lex/IdentifierTable.h"
+#include "clang/Basic/TargetInfo.h"
+using namespace clang;
+
+static const Builtin::Info BuiltinInfo[] = {
+  { "not a builtin function", 0, 0 },
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
+#include "clang/AST/Builtins.def"
+};
+
+const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
+  if (ID < Builtin::FirstTSBuiltin)
+    return BuiltinInfo[ID];
+  assert(ID - Builtin::FirstTSBuiltin < NumTSRecords && "Invalid builtin ID!");
+  return TSRecords[ID - Builtin::FirstTSBuiltin];
+}
+
+
+/// InitializeBuiltins - Mark the identifiers for all the builtins with their
+/// appropriate builtin ID # and mark any non-portable builtin identifiers as
+/// such.
+void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
+                                          const TargetInfo &Target) {
+  // Step #1: mark all target-independent builtins with their ID's.
+  for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
+    Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
+  
+  // Step #2: handle target builtins.
+  std::vector<const char *> NonPortableBuiltins;
+  Target.getTargetBuiltins(TSRecords, NumTSRecords, NonPortableBuiltins);
+
+  // Step #2a: Register target-specific builtins.
+  for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
+    Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
+  
+  // Step #2b: Mark non-portable builtins as such.
+  for (unsigned i = 0, e = NonPortableBuiltins.size(); i != e; ++i)
+    Table.get(NonPortableBuiltins[i]).setNonPortableBuiltin(true);
+}
+
+/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
+/// pointer over the consumed characters.  This returns the resultant type.
+static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context) {
+  // Modifiers.
+  bool Long = false, LongLong = false, Signed = false, Unsigned = false;
+  
+  // Read the modifiers first.
+  bool Done = false;
+  while (!Done) {
+    switch (*Str++) {
+    default: Done = true; --Str; break; 
+    case 'S':
+      assert(!Unsigned && "Can't use both 'S' and 'U' modifiers!");
+      assert(!Signed && "Can't use 'S' modifier multiple times!");
+      Signed = true;
+      break;
+    case 'U':
+      assert(!Signed && "Can't use both 'S' and 'U' modifiers!");
+      assert(!Unsigned && "Can't use 'S' modifier multiple times!");
+      Unsigned = true;
+      break;
+    case 'L':
+      assert(!LongLong && "Can't have LLL modifier");
+      if (Long) 
+        LongLong = true;
+      else
+        Long = true;
+      break;
+    }
+  }
+
+  // Read the base type.
+  switch (*Str++) {
+  default: assert(0 && "Unknown builtin type letter!");
+  case 'v':
+    assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
+    return Context.VoidTy;
+  case 'f':
+    assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
+    return Context.FloatTy;
+  case 'd':
+    assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!");
+    if (Long)
+      return Context.LongDoubleTy;
+    return Context.DoubleTy;
+  case 's':
+    assert(!LongLong && "Bad modifiers used with 's'!");
+    if (Unsigned)
+      return Context.UnsignedShortTy;
+    return Context.ShortTy;
+  //case 'i':
+  }
+}
+
+/// GetBuiltinType - Return the type for the specified builtin.
+QualType Builtin::Context::GetBuiltinType(unsigned id, ASTContext &Context)const{
+  const char *TypeStr = GetRecord(id).Type;
+  
+  llvm::SmallVector<QualType, 8> ArgTypes;
+  
+  QualType ResType = DecodeTypeFromStr(TypeStr, Context);
+  while (TypeStr[0] && TypeStr[0] != '.')
+    ArgTypes.push_back(DecodeTypeFromStr(TypeStr, Context));
+  
+  assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
+         "'.' should only occur at end of builtin type list!");
+  
+  return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
+                                 TypeStr[0] == '.');
+}