Fixed source range for StaticAssertDecl and LinkageSpecDecl. Fixed source range for declarations using postfix types.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127251 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c6d9391..a7f6c45 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -975,6 +975,55 @@
   return getTemplateOrInnerLocStart(this);
 }
 
+namespace {
+
+// Helper function: returns true if QT is or contains a type
+// having a postfix component.
+bool typeIsPostfix(clang::QualType QT) {
+  while (true) {
+    const Type* T = QT.getTypePtr();
+    switch (T->getTypeClass()) {
+    default:
+      return false;
+    case Type::Pointer:
+      QT = cast<PointerType>(T)->getPointeeType();
+      break;
+    case Type::BlockPointer:
+      QT = cast<BlockPointerType>(T)->getPointeeType();
+      break;
+    case Type::MemberPointer:
+      QT = cast<MemberPointerType>(T)->getPointeeType();
+      break;
+    case Type::LValueReference:
+    case Type::RValueReference:
+      QT = cast<ReferenceType>(T)->getPointeeType();
+      break;
+    case Type::PackExpansion:
+      QT = cast<PackExpansionType>(T)->getPattern();
+      break;
+    case Type::Paren:
+    case Type::ConstantArray:
+    case Type::DependentSizedArray:
+    case Type::IncompleteArray:
+    case Type::VariableArray:
+    case Type::FunctionProto:
+    case Type::FunctionNoProto:
+      return true;
+    }
+  }
+}
+
+} // namespace
+
+SourceRange DeclaratorDecl::getSourceRange() const {
+  SourceLocation RangeEnd = getLocation();
+  if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
+    if (typeIsPostfix(TInfo->getType()))
+      RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
+  }
+  return SourceRange(getOuterLocStart(), RangeEnd);
+}
+
 void
 QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
                                              unsigned NumTPLists,
@@ -1035,7 +1084,7 @@
 SourceRange VarDecl::getSourceRange() const {
   if (getInit())
     return SourceRange(getOuterLocStart(), getInit()->getLocEnd());
-  return SourceRange(getOuterLocStart(), getLocation());
+  return DeclaratorDecl::getSourceRange();
 }
 
 bool VarDecl::isExternC() const {
@@ -1927,6 +1976,10 @@
   return false;
 }
 
+SourceRange FunctionDecl::getSourceRange() const {
+  return SourceRange(getOuterLocStart(), EndRangeLoc);
+}
+
 //===----------------------------------------------------------------------===//
 // FieldDecl Implementation
 //===----------------------------------------------------------------------===//
@@ -1969,8 +2022,9 @@
 }
 
 SourceRange FieldDecl::getSourceRange() const {
-  return SourceRange(getInnerLocStart(),
-                     isBitField() ? BitWidth->getLocEnd() : getLocation());
+  if (isBitField())
+    return SourceRange(getInnerLocStart(), BitWidth->getLocEnd());
+  return DeclaratorDecl::getSourceRange();
 }
 
 //===----------------------------------------------------------------------===//
@@ -2284,6 +2338,15 @@
   return new (C) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo);
 }
 
+SourceRange TypedefDecl::getSourceRange() const {
+  SourceLocation RangeEnd = getLocation();
+  if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
+    if (typeIsPostfix(TInfo->getType()))
+      RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
+  }
+  return SourceRange(getLocStart(), RangeEnd);
+}
+
 FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
                                            StringLiteral *Str,
                                            SourceLocation AsmLoc,
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index abed12d..14e8123 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1273,10 +1273,11 @@
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
                                          DeclContext *DC,
-                                         SourceLocation L,
+                                         SourceLocation ExternLoc,
+                                         SourceLocation LangLoc,
                                          LanguageIDs Lang,
                                          SourceLocation RBraceLoc) {
-  return new (C) LinkageSpecDecl(DC, L, Lang, RBraceLoc);
+  return new (C) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, RBraceLoc);
 }
 
 UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
@@ -1379,9 +1380,12 @@
 }
 
 StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
-                                           SourceLocation L, Expr *AssertExpr,
-                                           StringLiteral *Message) {
-  return new (C) StaticAssertDecl(DC, L, AssertExpr, Message);
+                                           SourceLocation StaticAssertLoc,
+                                           Expr *AssertExpr,
+                                           StringLiteral *Message,
+                                           SourceLocation RParenLoc) {
+  return new (C) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
+                                  RParenLoc);
 }
 
 static const char *getAccessName(AccessSpecifier AS) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 6fd4d7e..de0e71e 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -508,10 +508,10 @@
 }
 
 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
-  SourceLocation End = getLocation();
   if (hasDefaultArgument() && !defaultArgumentWasInherited())
-    End = getDefaultArgument()->getSourceRange().getEnd();
-  return SourceRange(getOuterLocStart(), End);
+    return SourceRange(getOuterLocStart(),
+                       getDefaultArgument()->getSourceRange().getEnd());
+  return DeclaratorDecl::getSourceRange();
 }
 
 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index d42f42e..0873e83 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -118,18 +118,37 @@
 
 SourceLocation TypeLoc::getEndLoc() const {
   TypeLoc Cur = *this;
+  TypeLoc Last;
   while (true) {
     switch (Cur.getTypeLocClass()) {
     default:
+      if (!Last)
+	Last = Cur;
+      return Last.getLocalSourceRange().getEnd();
+    case Paren:
+    case ConstantArray:
+    case DependentSizedArray:
+    case IncompleteArray:
+    case VariableArray:
+    case FunctionProto:
+    case FunctionNoProto:
+      Last = Cur;
+      break;
+    case Pointer:
+    case BlockPointer:
+    case MemberPointer:
+    case LValueReference:
+    case RValueReference:
+    case PackExpansion:
+      if (!Last)
+	Last = Cur;
       break;
     case Qualified:
     case Elaborated:
-      Cur = Cur.getNextTypeLoc();
-      continue;
+      break;
     }
-    break;
+    Cur = Cur.getNextTypeLoc();
   }
-  return Cur.getLocalSourceRange().getEnd();
 }