Keep track of the actual storage specifier written on a variable or
function declaration, since it may end up being changed (e.g.,
"extern" can become "static" if a prior declaration was static). Patch
by Enea Zaffanella and Paolo Bolzoni.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101826 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index b13e7f9..5651121 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1905,6 +1905,7 @@
   } else {
     ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, Loc, 
                                       Name, T, TInfo, D->getStorageClass(), 
+                                      D->getStorageClassAsWritten(),
                                       D->isInlineSpecified(),
                                       D->hasWrittenPrototype());
   }
@@ -2125,7 +2126,8 @@
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc, 
                                    Name.getAsIdentifierInfo(), T, TInfo,
-                                   D->getStorageClass());
+                                   D->getStorageClass(),
+                                   D->getStorageClassAsWritten());
   // Import the qualifier, if any.
   if (D->getQualifier()) {
     NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
@@ -2197,6 +2199,7 @@
   ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
                                             Loc, Name.getAsIdentifierInfo(),
                                             T, TInfo, D->getStorageClass(),
+                                             D->getStorageClassAsWritten(),
                                             /*FIXME: Default argument*/ 0);
   ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
   return Importer.Imported(D, ToParm);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index d4cc945..b02cbde 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -586,8 +586,8 @@
 
 VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                          IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
-                         StorageClass S) {
-  return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S);
+                         StorageClass S, StorageClass SCAsWritten) {
+  return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten);
 }
 
 void VarDecl::Destroy(ASTContext& C) {
@@ -811,8 +811,10 @@
 ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation L, IdentifierInfo *Id,
                                  QualType T, TypeSourceInfo *TInfo,
-                                 StorageClass S, Expr *DefArg) {
-  return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg);
+                                 StorageClass S, StorageClass SCAsWritten,
+                                 Expr *DefArg) {
+  return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo,
+                             S, SCAsWritten, DefArg);
 }
 
 Expr *ParmVarDecl::getDefaultArg() {
@@ -1658,10 +1660,10 @@
                                    SourceLocation L,
                                    DeclarationName N, QualType T,
                                    TypeSourceInfo *TInfo,
-                                   StorageClass S, bool isInline,
-                                   bool hasWrittenPrototype) {
-  FunctionDecl *New
-    = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline);
+                                   StorageClass S, StorageClass SCAsWritten,
+                                   bool isInline, bool hasWrittenPrototype) {
+  FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+                                           S, SCAsWritten, isInline);
   New->HasWrittenPrototype = hasWrittenPrototype;
   return New;
 }
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 28489d3..eef067b 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -587,9 +587,9 @@
 CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                       SourceLocation L, DeclarationName N,
                       QualType T, TypeSourceInfo *TInfo,
-                      bool isStatic, bool isInline) {
+                      bool isStatic, StorageClass SCAsWritten, bool isInline) {
   return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, TInfo,
-                               isStatic, isInline);
+                               isStatic, SCAsWritten, isInline);
 }
 
 bool CXXMethodDecl::isUsualDeallocationFunction() const {
@@ -745,11 +745,12 @@
                            SourceLocation L, DeclarationName N,
                            QualType T, TypeSourceInfo *TInfo,
                            bool isExplicit,
-                           bool isInline, bool isImplicitlyDeclared) {
+                           bool isInline,
+                           bool isImplicitlyDeclared) {
   assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
          "Name must refer to a constructor");
-  return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit, isInline,
-                                      isImplicitlyDeclared);
+  return new (C) CXXConstructorDecl(RD, L, N, T, TInfo, isExplicit,
+                                    isInline, isImplicitlyDeclared);
 }
 
 bool CXXConstructorDecl::isDefaultConstructor() const {
@@ -848,8 +849,7 @@
                           bool isImplicitlyDeclared) {
   assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
          "Name must refer to a destructor");
-  return new (C) CXXDestructorDecl(RD, L, N, T, isInline,
-                                   isImplicitlyDeclared);
+  return new (C) CXXDestructorDecl(RD, L, N, T, isInline, isImplicitlyDeclared);
 }
 
 void