diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-03 19:22:20 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-03 19:22:20 +0000 |
commit | 4f8a3eb2ce5d4ba422483439e20c8cbb4d953a41 (patch) | |
tree | da183dd16cf78a8e3e464f1e041cd33f425ab580 | |
parent | f9f30791dd20472675de012105219cd975ad1076 (diff) | |
download | clang-4f8a3eb2ce5d4ba422483439e20c8cbb4d953a41.tar.gz clang-4f8a3eb2ce5d4ba422483439e20c8cbb4d953a41.tar.bz2 clang-4f8a3eb2ce5d4ba422483439e20c8cbb4d953a41.tar.xz |
Revert 178663.
Looks like it broke http://lab.llvm.org:8011/builders/clang-x86_64-darwin10-gdb
Revert "Don't compute a patched/semantic storage class."
This reverts commit 8f187f62cb0487d31bc4afdfcd47e11fe9a51d05.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178681 91177308-0d34-0410-b5e6-96231b3b80d8
38 files changed, 339 insertions, 220 deletions
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index d9a3364606..504553c17a 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -111,14 +111,9 @@ succeeded). Essentially all previous 'cast' usage should be replaced with 'castAs' and 'dyn_cast' should be replaced with 'getAs'. See r175462 for the first example of such a change along with many examples of how code was migrated to the new API. - -Storage Class -^^^^^^^^^^^^^ - -For each variable and function Clang used to keep the storage class as written -in the source, the linkage and a semantic storage class. This was a bit -redundant and the semantic storage class has been removed. The method -getStorageClass now returns what is written it the source code for that decl. + +API change 1 +^^^^^^^^^^^^ ... diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 0294b9fde8..c89c73134c 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -660,6 +660,7 @@ private: friend class ASTDeclReader; unsigned SClass : 3; + unsigned SClassAsWritten : 3; unsigned ThreadSpecified : 1; unsigned InitStyle : 2; @@ -726,12 +727,14 @@ protected: VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, StorageClass SC) + QualType T, TypeSourceInfo *TInfo, StorageClass SC, + StorageClass SCAsWritten) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() { assert(sizeof(VarDeclBitfields) <= sizeof(unsigned)); assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned)); AllBits = 0; VarDeclBits.SClass = SC; + VarDeclBits.SClassAsWritten = SCAsWritten; // Everything else is implicitly initialized to false. } @@ -754,18 +757,23 @@ public: static VarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S); + StorageClass S, StorageClass SCAsWritten); static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); virtual SourceRange getSourceRange() const LLVM_READONLY; - /// \brief Returns the storage class as written in the source. For the - /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return (StorageClass) VarDeclBits.SClass; } + StorageClass getStorageClassAsWritten() const { + return (StorageClass) VarDeclBits.SClassAsWritten; + } void setStorageClass(StorageClass SC); + void setStorageClassAsWritten(StorageClass SC) { + assert(isLegalForVariable(SC)); + VarDeclBits.SClassAsWritten = SC; + } void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; } bool isThreadSpecified() const { @@ -797,6 +805,13 @@ public: getStorageClass() == SC_PrivateExtern; } + /// \brief Returns true if a variable was written with extern or + /// __private_extern__ storage. + bool hasExternalStorageAsWritten() const { + return getStorageClassAsWritten() == SC_Extern || + getStorageClassAsWritten() == SC_PrivateExtern; + } + /// hasGlobalStorage - Returns true for all variables that do not /// have local storage. This includs all global variables as well /// as static variables declared within a function. @@ -1130,7 +1145,7 @@ public: ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType Type) : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type, - /*tinfo*/ 0, SC_None) { + /*tinfo*/ 0, SC_None, SC_None) { setImplicit(); } @@ -1149,8 +1164,8 @@ protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg) - : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) { + StorageClass S, StorageClass SCAsWritten, Expr *DefArg) + : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S, SCAsWritten) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); @@ -1162,7 +1177,8 @@ public: SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg); + StorageClass S, StorageClass SCAsWritten, + Expr *DefArg); static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1367,6 +1383,7 @@ private: // FIXME: This can be packed into the bitfields in Decl. // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum unsigned SClass : 2; + unsigned SClassAsWritten : 2; bool IsInline : 1; bool IsInlineSpecified : 1; bool IsVirtualAsWritten : 1; @@ -1456,13 +1473,13 @@ protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass S, bool isInlineSpecified, + StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified, bool isConstexprSpecified) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), DeclContext(DK), ParamInfo(0), Body(), - SClass(S), + SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), @@ -1494,12 +1511,13 @@ public: DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, + StorageClass SCAsWritten, bool isInlineSpecified = false, bool hasWrittenPrototype = true, bool isConstexprSpecified = false) { DeclarationNameInfo NameInfo(N, NLoc); return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, - SC, + SC, SCAsWritten, isInlineSpecified, hasWrittenPrototype, isConstexprSpecified); } @@ -1509,6 +1527,7 @@ public: const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, + StorageClass SCAsWritten, bool isInlineSpecified, bool hasWrittenPrototype, bool isConstexprSpecified = false); @@ -1760,9 +1779,12 @@ public: return getType()->getAs<FunctionType>()->getCallResultType(getASTContext()); } - /// \brief Returns the storage class as written in the source. For the - /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return StorageClass(SClass); } + void setStorageClass(StorageClass SC); + + StorageClass getStorageClassAsWritten() const { + return StorageClass(SClassAsWritten); + } /// \brief Determine whether the "inline" keyword was specified for this /// function. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 05ff49c64c..430e6d8cc5 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1573,10 +1573,11 @@ protected: CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass SC, bool isInline, + bool isStatic, StorageClass SCAsWritten, bool isInline, bool isConstexpr, SourceLocation EndLocation) : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo, - SC, isInline, isConstexpr) { + (isStatic ? SC_Static : SC_None), + SCAsWritten, isInline, isConstexpr) { if (EndLocation.isValid()) setRangeEnd(EndLocation); } @@ -1586,14 +1587,15 @@ public: SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass SC, + bool isStatic, + StorageClass SCAsWritten, bool isInline, bool isConstexpr, SourceLocation EndLocation); static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - bool isStatic() const; + + bool isStatic() const { return getStorageClass() == SC_Static; } bool isInstance() const { return !isStatic(); } bool isConst() const { return getType()->castAs<FunctionType>()->isConst(); } @@ -2001,7 +2003,7 @@ class CXXConstructorDecl : public CXXMethodDecl { QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, bool isConstexpr) - : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, + : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo, false, SC_None, isInline, isConstexpr, SourceLocation()), IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false), CtorInitializers(0), NumCtorInitializers(0) { @@ -2220,7 +2222,7 @@ class CXXDestructorDecl : public CXXMethodDecl { const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isImplicitlyDeclared) - : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, + : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo, false, SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), ImplicitlyDefined(false), OperatorDelete(0) { setImplicit(isImplicitlyDeclared); @@ -2287,7 +2289,7 @@ class CXXConversionDecl : public CXXMethodDecl { QualType T, TypeSourceInfo *TInfo, bool isInline, bool isExplicitSpecified, bool isConstexpr, SourceLocation EndLocation) - : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, + : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo, false, SC_None, isInline, isConstexpr, EndLocation), IsExplicitSpecified(isExplicitSpecified) { } diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 5b90784dcf..48cd4d14f8 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -338,6 +338,8 @@ private: // constexpr-specifier unsigned Constexpr_specified : 1; + /*SCS*/unsigned StorageClassSpecAsWritten : 3; + union { UnionParsedType TypeRep; Decl *DeclRep; @@ -376,6 +378,7 @@ private: WrittenBuiltinSpecs writtenBS; void SaveWrittenBuiltinSpecs(); + void SaveStorageSpecifierAsWritten(); ObjCDeclSpec *ObjCQualifiers; @@ -415,6 +418,7 @@ public: FS_noreturn_specified(false), Friend_specified(false), Constexpr_specified(false), + StorageClassSpecAsWritten(SCS_unspecified), Attrs(attrFactory), ProtocolQualifiers(0), NumProtocolQualifiers(0), @@ -549,6 +553,10 @@ public: /// DeclSpec includes. unsigned getParsedSpecifiers() const; + SCS getStorageClassSpecAsWritten() const { + return (SCS)StorageClassSpecAsWritten; + } + /// isEmpty - Return true if this declaration specifier is completely empty: /// no tokens were parsed in the production of it. bool isEmpty() const { diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index d17557260e..7b07352d3c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1402,7 +1402,7 @@ public: ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, - StorageClass SC); + StorageClass SC, StorageClass SCAsWritten); void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg); diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index b1d174b855..740153029b 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -749,7 +749,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { dumpName(D); dumpType(D->getType()); - StorageClass SC = D->getStorageClass(); + StorageClass SC = D->getStorageClassAsWritten(); if (SC != SC_None) OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); if (D->isInlineSpecified()) @@ -850,7 +850,7 @@ void ASTDumper::VisitFieldDecl(const FieldDecl *D) { void ASTDumper::VisitVarDecl(const VarDecl *D) { dumpName(D); dumpType(D->getType()); - StorageClass SC = D->getStorageClass(); + StorageClass SC = D->getStorageClassAsWritten(); if (SC != SC_None) OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); if (D->isThreadSpecified()) diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index d2e6d29705..01d1a1e917 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -2716,7 +2716,8 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { cast<CXXRecordDecl>(DC), D->getInnerLocStart(), NameInfo, T, TInfo, - Method->getStorageClass(), + Method->isStatic(), + Method->getStorageClassAsWritten(), Method->isInlineSpecified(), D->isConstexpr(), Importer.Import(D->getLocEnd())); @@ -2724,6 +2725,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { ToFunction = FunctionDecl::Create(Importer.getToContext(), DC, D->getInnerLocStart(), NameInfo, T, TInfo, D->getStorageClass(), + D->getStorageClassAsWritten(), D->isInlineSpecified(), D->hasWrittenPrototype(), D->isConstexpr()); @@ -3074,7 +3076,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) { Importer.Import(D->getInnerLocStart()), Loc, Name.getAsIdentifierInfo(), T, TInfo, - D->getStorageClass()); + D->getStorageClass(), + D->getStorageClassAsWritten()); ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc())); ToVar->setAccess(D->getAccess()); ToVar->setLexicalDeclContext(LexicalDC); @@ -3142,6 +3145,7 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) { Importer.Import(D->getInnerLocStart()), 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 9505d299ab..4b92069762 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -498,24 +498,26 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // declared to have external linkage; or (there is no equivalent in C99) if (Context.getLangOpts().CPlusPlus && Var->getType().isConstQualified() && - !Var->getType().isVolatileQualified()) { - const VarDecl *PrevVar = Var->getPreviousDecl(); - if (PrevVar) - return PrevVar->getLinkageAndVisibility(); - - if (Var->getStorageClass() != SC_Extern && - Var->getStorageClass() != SC_PrivateExtern) + !Var->getType().isVolatileQualified() && + Var->getStorageClass() != SC_Extern && + Var->getStorageClass() != SC_PrivateExtern) { + bool FoundExtern = false; + for (const VarDecl *PrevVar = Var->getPreviousDecl(); + PrevVar && !FoundExtern; + PrevVar = PrevVar->getPreviousDecl()) + if (isExternalLinkage(PrevVar->getLinkage())) + FoundExtern = true; + + if (!FoundExtern) return LinkageInfo::internal(); } - - for (const VarDecl *PrevVar = Var->getPreviousDecl(); PrevVar; - PrevVar = PrevVar->getPreviousDecl()) { - if (PrevVar->getStorageClass() == SC_PrivateExtern && - Var->getStorageClass() == SC_None) + if (Var->getStorageClass() == SC_None) { + const VarDecl *PrevVar = Var->getPreviousDecl(); + for (; PrevVar; PrevVar = PrevVar->getPreviousDecl()) + if (PrevVar->getStorageClass() == SC_PrivateExtern) + break; + if (PrevVar) return PrevVar->getLinkageAndVisibility(); - // Explicitly declared static. - if (PrevVar->getStorageClass() == SC_Static) - return LinkageInfo::internal(); } } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) { // C++ [temp]p4: @@ -529,7 +531,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, Function = cast<FunctionDecl>(D); // Explicitly declared static. - if (Function->getCanonicalDecl()->getStorageClass() == SC_Static) + if (Function->getStorageClass() == SC_Static) return LinkageInfo(InternalLinkage, DefaultVisibility, false); } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) { // - a data member of an anonymous union. @@ -993,7 +995,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D, return LinkageInfo::uniqueExternal(); // This is a "void f();" which got merged with a file static. - if (Function->getCanonicalDecl()->getStorageClass() == SC_Static) + if (Function->getStorageClass() == SC_Static) return LinkageInfo::internal(); LinkageInfo LV; @@ -1011,11 +1013,15 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D, } if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { - if (Var->hasExternalStorage()) { + if (Var->hasExternalStorageAsWritten()) { if (Var->isInAnonymousNamespace() && !Var->getDeclContext()->isExternCContext()) return LinkageInfo::uniqueExternal(); + // This is an "extern int foo;" which got merged with a file static. + if (Var->getStorageClass() == SC_Static) + return LinkageInfo::internal(); + LinkageInfo LV; if (Var->getStorageClass() == SC_PrivateExtern) LV.mergeVisibility(HiddenVisibility, true); @@ -1024,13 +1030,9 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D, LV.mergeVisibility(*Vis, true); } - if (const VarDecl *Prev = Var->getPreviousDecl()) { - LinkageInfo PrevLV = getLVForDecl(Prev, computation); - if (PrevLV.getLinkage()) - LV.setLinkage(PrevLV.getLinkage()); - LV.mergeVisibility(PrevLV); - } - + // Note that Sema::MergeVarDecl already takes care of implementing + // C99 6.2.2p4 and propagating the visibility attribute, so we don't + // have to do it here. return LV; } } @@ -1465,18 +1467,21 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) { VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, SourceLocation IdL, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S) { - return new (C) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S); + StorageClass S, StorageClass SCAsWritten) { + return new (C) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S, SCAsWritten); } VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarDecl)); return new (Mem) VarDecl(Var, 0, SourceLocation(), SourceLocation(), 0, - QualType(), 0, SC_None); + QualType(), 0, SC_None, SC_None); } void VarDecl::setStorageClass(StorageClass SC) { assert(isLegalForVariable(SC)); + if (getStorageClass() != SC) + assert(isLinkageValid()); + VarDeclBits.SClass = SC; } @@ -1576,7 +1581,7 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition( if (hasExternalStorage()) return DeclarationOnly; - if (hasExternalStorage()) { + if (hasExternalStorageAsWritten()) { for (const VarDecl *PrevVar = getPreviousDecl(); PrevVar; PrevVar = PrevVar->getPreviousDecl()) { if (PrevVar->getLinkage() == InternalLinkage) @@ -1874,15 +1879,16 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg) { + StorageClass S, StorageClass SCAsWritten, + Expr *DefArg) { return new (C) ParmVarDecl(ParmVar, DC, StartLoc, IdLoc, Id, T, TInfo, - S, DefArg); + S, SCAsWritten, DefArg); } ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ParmVarDecl)); return new (Mem) ParmVarDecl(ParmVar, 0, SourceLocation(), SourceLocation(), - 0, QualType(), 0, SC_None, 0); + 0, QualType(), 0, SC_None, SC_None, 0); } SourceRange ParmVarDecl::getSourceRange() const { @@ -2061,7 +2067,7 @@ bool FunctionDecl::isGlobal() const { if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this)) return Method->isStatic(); - if (getCanonicalDecl()->getStorageClass() == SC_Static) + if (getStorageClass() == SC_Static) return false; for (const DeclContext *DC = getDeclContext(); @@ -2106,6 +2112,14 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDeclaration(); } +void FunctionDecl::setStorageClass(StorageClass SC) { + assert(isLegalForFunction(SC)); + if (getStorageClass() != SC) + assert(isLinkageValid()); + + SClass = SC; +} + /// \brief Returns a value indicating whether this function /// corresponds to a builtin function. /// @@ -2256,7 +2270,7 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { // // FIXME: What happens if gnu_inline gets added on after the first // declaration? - if (!isInlineSpecified() || getStorageClass() == SC_Extern) + if (!isInlineSpecified() || getStorageClassAsWritten() == SC_Extern) return false; const FunctionDecl *Prev = this; @@ -2268,10 +2282,10 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const { // If it's not the case that both 'inline' and 'extern' are // specified on the definition, then it is always externally visible. if (!Prev->isInlineSpecified() || - Prev->getStorageClass() != SC_Extern) + Prev->getStorageClassAsWritten() != SC_Extern) return false; } else if (Prev->isInlineSpecified() && - Prev->getStorageClass() != SC_Extern) { + Prev->getStorageClassAsWritten() != SC_Extern) { return false; } } @@ -2326,7 +2340,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { // If it's not the case that both 'inline' and 'extern' are // specified on the definition, then this inline definition is // externally visible. - if (!(isInlineSpecified() && getStorageClass() == SC_Extern)) + if (!(isInlineSpecified() && getStorageClassAsWritten() == SC_Extern)) return true; // If any declaration is 'inline' but not 'extern', then this definition @@ -2335,7 +2349,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { Redecl != RedeclEnd; ++Redecl) { if (Redecl->isInlineSpecified() && - Redecl->getStorageClass() != SC_Extern) + Redecl->getStorageClassAsWritten() != SC_Extern) return true; } @@ -3198,12 +3212,12 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass SC, + StorageClass SC, StorageClass SCAsWritten, bool isInlineSpecified, bool hasWrittenPrototype, bool isConstexprSpecified) { FunctionDecl *New = new (C) FunctionDecl(Function, DC, StartLoc, NameInfo, - T, TInfo, SC, + T, TInfo, SC, SCAsWritten, isInlineSpecified, isConstexprSpecified); New->HasWrittenPrototype = hasWrittenPrototype; @@ -3214,7 +3228,7 @@ FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionDecl)); return new (Mem) FunctionDecl(Function, 0, SourceLocation(), DeclarationNameInfo(), QualType(), 0, - SC_None, false, false); + SC_None, SC_None, false, false); } BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index bd6d99cd59..1e60560485 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -435,7 +435,7 @@ bool Decl::canBeWeakImported(bool &IsDefinition) const { // Variables, if they aren't definitions. if (const VarDecl *Var = dyn_cast<VarDecl>(this)) { - if (Var->isThisDeclarationADefinition()) { + if (!Var->hasExternalStorage() || Var->getInit()) { IsDefinition = true; return false; } diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index ffad9ae93c..9ed9b7d363 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -1251,42 +1251,6 @@ bool CXXRecordDecl::mayBeAbstract() const { void CXXMethodDecl::anchor() { } -bool CXXMethodDecl::isStatic() const { - const CXXMethodDecl *MD = this; - for (;;) { - const CXXMethodDecl *C = MD->getCanonicalDecl(); - if (C != MD) { - MD = C; - continue; - } - - FunctionTemplateSpecializationInfo *Info = - MD->getTemplateSpecializationInfo(); - if (!Info) - break; - MD = cast<CXXMethodDecl>(Info->getTemplate()->getTemplatedDecl()); - } - - if (MD->getStorageClass() == SC_Static) - return true; - - DeclarationName Name = getDeclName(); - // [class.free]p1: - // Any allocation function for a class T is a static member - // (even if not explicitly declared static). - if (Name.getCXXOverloadedOperator() == OO_New || - Name.getCXXOverloadedOperator() == OO_Array_New) - return true; - - // [class.free]p6 Any deallocation function for a class X is a static member - // (even if not explicitly declared static). - if (Name.getCXXOverloadedOperator() == OO_Delete || - Name.getCXXOverloadedOperator() == OO_Array_Delete) - return true; - - return false; -} - static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD, const CXXMethodDecl *BaseMD) { for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(), @@ -1348,10 +1312,10 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - StorageClass SC, bool isInline, + bool isStatic, StorageClass SCAsWritten, bool isInline, bool isConstexpr, SourceLocation EndLocation) { return new (C) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo, - SC, isInline, isConstexpr, + isStatic, SCAsWritten, isInline, isConstexpr, EndLocation); } @@ -1359,7 +1323,7 @@ CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXMethodDecl)); return new (Mem) CXXMethodDecl(CXXMethod, 0, SourceLocation(), DeclarationNameInfo(), QualType(), - 0, SC_None, false, false, + 0, false, SC_None, false, false, SourceLocation()); } diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index c3bf8f89b2..54fa9ca589 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -393,7 +393,7 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) { void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D); if (!Policy.SuppressSpecifiers) { - switch (D->getStorageClass()) { + switch (D->getStorageClassAsWritten()) { case SC_None: break; case SC_Extern: Out << "extern "; break; case SC_Static: Out << "static "; break; @@ -641,9 +641,9 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) { void DeclPrinter::VisitVarDecl(VarDecl *D) { - StorageClass SC = D->getStorageClass(); - if (!Policy.SuppressSpecifiers && SC != SC_None) - Out << VarDecl::getStorageClassSpecifierString(SC) << " "; + StorageClass SCAsWritten = D->getStorageClassAsWritten(); + if (!Policy.SuppressSpecifiers && SCAsWritten != SC_None) + Out << VarDecl::getStorageClassSpecifierString(SCAsWritten) << " "; if (!Policy.SuppressSpecifiers && D->isThreadSpecified()) Out << "__thread "; diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 227ee2d024..374c824a20 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -1316,6 +1316,7 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { SourceLocation(), SourceLocation(), II, C.VoidTy, 0, SC_Static, + SC_None, false, false); StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); @@ -1490,6 +1491,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { SourceLocation(), SourceLocation(), II, C.VoidTy, 0, SC_Static, + SC_None, false, false); StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation()); @@ -1780,6 +1782,7 @@ generateByrefCopyHelper(CodeGenFunction &CGF, SourceLocation(), SourceLocation(), II, R, 0, SC_Static, + SC_None, false, false); // Initialize debug info if necessary. @@ -1854,6 +1857,7 @@ generateByrefDisposeHelper(CodeGenFunction &CGF, SourceLocation(), SourceLocation(), II, R, 0, SC_Static, + SC_None, false, false); // Initialize debug info if necessary. CGF.maybeInitializeDebugInfo(); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 5375c5e18f..1255e654dc 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -109,7 +109,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { /// EmitVarDecl - This method handles emission of any variable declaration /// inside a function, including static vars etc. void CodeGenFunction::EmitVarDecl(const VarDecl &D) { - switch (D.getStorageClass()) { + switch (D.getStorageClassAsWritten()) { case SC_None: case SC_Auto: case SC_Register: diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 2e3bd5f7f1..e8378becf1 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -2848,6 +2848,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( SourceLocation(), SourceLocation(), II, C.VoidTy, 0, SC_Static, + SC_None, false, false); @@ -2932,6 +2933,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( SourceLocation(), SourceLocation(), II, C.VoidTy, 0, SC_Static, + SC_None, false, false); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 6d85a8835b..9f604e860e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1602,7 +1602,7 @@ CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D, D->getDeclContext()), D->getLocStart(), D->getLocation(), name, arrayType, sourceInfo, - SC_Static); + SC_Static, SC_Static); // Now clone the InitListExpr to initialize the array instead. // Incredible hack: we want to use the existing InitListExpr here, so we need diff --git a/lib/Rewrite/Frontend/RewriteModernObjC.cpp b/lib/Rewrite/Frontend/RewriteModernObjC.cpp index 0e59b113c9..c05e8a6d69 100644 --- a/lib/Rewrite/Frontend/RewriteModernObjC.cpp +++ b/lib/Rewrite/Frontend/RewriteModernObjC.cpp @@ -2365,7 +2365,7 @@ void RewriteModernObjC::SynthSelGetUidFunctionDecl() { SourceLocation(), SourceLocation(), SelGetUidIdent, getFuncType, 0, - SC_Extern); + SC_Extern, SC_None); } void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) { @@ -2463,7 +2463,7 @@ void RewriteModernObjC::SynthSuperContructorFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, - 0, SC_Extern); + 0, SC_Extern, SC_None); } // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); @@ -2482,7 +2482,7 @@ void RewriteModernObjC::SynthMsgSendFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void); @@ -2496,7 +2496,7 @@ void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); @@ -2515,7 +2515,7 @@ void RewriteModernObjC::SynthMsgSendStretFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendSuperStretFunctionDecl - @@ -2532,7 +2532,7 @@ void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() { SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); @@ -2551,7 +2551,7 @@ void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthGetClassFunctionDecl - Class objc_getClass(const char *name); @@ -2565,7 +2565,7 @@ void RewriteModernObjC::SynthGetClassFunctionDecl() { SourceLocation(), SourceLocation(), getClassIdent, getClassType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); @@ -2581,7 +2581,7 @@ void RewriteModernObjC::SynthGetSuperClassFunctionDecl() { SourceLocation(), getSuperClassIdent, getClassType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name); @@ -2595,7 +2595,7 @@ void RewriteModernObjC::SynthGetMetaClassFunctionDecl() { SourceLocation(), SourceLocation(), getClassIdent, getClassType, - 0, SC_Extern); + 0, SC_Extern, SC_None); } Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { @@ -2628,7 +2628,7 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(S), - strType, 0, SC_Static); + strType, 0, SC_Static, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, SourceLocation()); Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, @@ -3139,7 +3139,7 @@ static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R, if (!LSD->getRBraceLoc().isValid()) return LSD->getExternLoc(); } - if (FD->getStorageClass() != SC_None) + if (FD->getStorageClassAsWritten() != SC_None) R.RewriteBlockLiteralFunctionDecl(FD); return FD->getTypeSpecStartLoc(); } @@ -3250,7 +3250,7 @@ Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFla IdentifierInfo *ID = &Context->Idents.get(name); FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), ID, castType, 0, - SC_Extern, false, false); + SC_Extern, SC_None, false, false); DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue, SourceLocation()); CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs, @@ -3723,7 +3723,7 @@ Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { IdentifierInfo *ID = &Context->Idents.get(Name); VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), ID, getProtocolType(), 0, - SC_Extern); + SC_Extern, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), VK_LValue, SourceLocation()); Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, @@ -5403,7 +5403,7 @@ FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) { QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), ID, FType, 0, SC_Extern, - false, false); + SC_None, false, false); } Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, @@ -5504,7 +5504,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, SourceLocation(), SourceLocation(), &Context->Idents.get(DescData.c_str()), Context->VoidPtrTy, 0, - SC_Static); + SC_Static, SC_None); UnaryOperator *DescRefExpr = new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, Context->VoidPtrTy, @@ -7768,7 +7768,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { BaseExpr); VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(IvarOffsetName), - Context->UnsignedLongTy, 0, SC_Extern); + Context->UnsignedLongTy, 0, SC_Extern, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, Context->UnsignedLongTy, VK_LValue, SourceLocation()); diff --git a/lib/Rewrite/Frontend/RewriteObjC.cpp b/lib/Rewrite/Frontend/RewriteObjC.cpp index 2f5cd0f6c6..108041753d 100644 --- a/lib/Rewrite/Frontend/RewriteObjC.cpp +++ b/lib/Rewrite/Frontend/RewriteObjC.cpp @@ -2267,7 +2267,7 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() { SourceLocation(), SourceLocation(), SelGetUidIdent, getFuncType, 0, - SC_Extern); + SC_Extern, SC_None); } void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { @@ -2363,7 +2363,7 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, - 0, SC_Extern); + 0, SC_Extern, SC_None); } // SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...); @@ -2382,7 +2382,7 @@ void RewriteObjC::SynthMsgSendFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...); @@ -2404,7 +2404,7 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...); @@ -2423,7 +2423,7 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendSuperStretFunctionDecl - @@ -2448,7 +2448,7 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...); @@ -2467,7 +2467,7 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() { SourceLocation(), SourceLocation(), msgSendIdent, msgSendType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthGetClassFunctionDecl - id objc_getClass(const char *name); @@ -2481,7 +2481,7 @@ void RewriteObjC::SynthGetClassFunctionDecl() { SourceLocation(), SourceLocation(), getClassIdent, getClassType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls); @@ -2497,7 +2497,7 @@ void RewriteObjC::SynthGetSuperClassFunctionDecl() { SourceLocation(), getSuperClassIdent, getClassType, 0, - SC_Extern); + SC_Extern, SC_None); } // SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name); @@ -2511,7 +2511,7 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() { SourceLocation(), SourceLocation(), getClassIdent, getClassType, - 0, SC_Extern); + 0, SC_Extern, SC_None); } Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { @@ -2544,7 +2544,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(S), - strType, 0, SC_Static); + strType, 0, SC_Static, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue, SourceLocation()); Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, @@ -3112,7 +3112,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { IdentifierInfo *ID = &Context->Idents.get(Name); VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), ID, getProtocolType(), 0, - SC_Extern); + SC_Extern, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(), VK_LValue, SourceLocation()); Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, @@ -4448,7 +4448,7 @@ FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) { QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SourceLocation(), ID, FType, 0, SC_Extern, - false, false); + SC_None, false, false); } Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, @@ -4532,7 +4532,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, SourceLocation(), SourceLocation(), &Context->Idents.get(DescData.c_str()), Context->VoidPtrTy, 0, - SC_Static); + SC_Static, SC_None); UnaryOperator *DescRefExpr = new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false, Context->VoidPtrTy, diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index e1d55dbddc..45f524b97b 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -815,6 +815,15 @@ void DeclSpec::SaveWrittenBuiltinSpecs() { } } +void DeclSpec::SaveStorageSpecifierAsWritten() { + if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern) + // If 'extern' is part of a linkage specification, + // then it is not a storage class "as written". + StorageClassSpecAsWritten = SCS_unspecified; + else + StorageClassSpecAsWritten = StorageClassSpec; +} + /// Finish - This does final analysis of the declspec, rejecting things like /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, @@ -822,6 +831,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() { void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { // Before possibly changing their values, save specs as written. SaveWrittenBuiltinSpecs(); + SaveStorageSpecifierAsWritten(); // Check the type specifier components first. @@ -931,7 +941,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt && TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { TypeSpecType = TST_auto; - StorageClassSpec = SCS_unspecified; + StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified; TSTLoc = TSTNameLoc = StorageClassSpecLoc; StorageClassSpecLoc = SourceLocation(); } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 6bab9e80cb..8b17c123fd 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -728,7 +728,7 @@ void Sema::ActOnEndOfTranslationUnit() { Diag(DiagD->getLocation(), diag::warn_unneeded_member_function) << DiagD->getDeclName(); else { - if (FD->getStorageClass() == SC_Static && + if (FD->getStorageClassAsWritten() == SC_Static && !FD->isInlineSpecified() && !SourceMgr.isFromMainFile( SourceMgr.getExpansionLoc(FD->getLocation()))) diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 2db1e2afa2..9c77e3f154 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -3349,7 +3349,7 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, // the initial opening bracket '[' missing. Add appropriate completions. if (AllowNonIdentifiers && !AllowNestedNameSpecifiers && DS.getTypeSpecType() == DeclSpec::TST_typename && - DS.getStorageClassSpec() == DeclSpec::SCS_unspecified && + DS.getStorageClassSpecAsWritten() == DeclSpec::SCS_unspecified && !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() && DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified && DS.getTypeSpecSign() == DeclSpec::TSS_unspecified && diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a6ba68060d..16887da457 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1557,7 +1557,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Context.getTranslationUnitDecl(), Loc, Loc, II, R, /*TInfo=*/0, SC_Extern, - false, + SC_None, false, /*hasPrototype=*/true); New->setImplicit(); @@ -1570,7 +1570,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), 0, FT->getArgType(i), /*TInfo=*/0, - SC_None, 0); + SC_None, SC_None, 0); parm->setScopeInfo(0, i); Params.push_back(parm); } @@ -2306,12 +2306,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // Don't complain about this if we're in GNU89 mode and the old function // is an extern inline function. - // Don't complain about specializations. They are not supposed to have - // storage classes. if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) && New->getStorageClass() == SC_Static && Old->getStorageClass() != SC_Static && - !New->getTemplateSpecializationInfo() && !canRedefineFunction(Old, getLangOpts())) { if (getLangOpts().MicrosoftExt) { Diag(New->getLocation(), diag::warn_static_non_static) << New; @@ -2603,7 +2600,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { SourceLocation(), SourceLocation(), 0, *ParamType, /*TInfo=*/0, - SC_None, + SC_None, SC_None, 0); Param->setScopeInfo(0, Params.size()); Param->setImplicit(); @@ -2719,6 +2716,11 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, // Merge the attributes mergeDeclAttributes(New, Old); + // Merge the storage class. + if (Old->getStorageClass() != SC_Extern && + Old->getStorageClass() != SC_None) + New->setStorageClass(Old->getStorageClass()); + // Merge "pure" flag. if (Old->isPure()) New->setPure(); @@ -2896,8 +2898,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, // identifier has external linkage. if (New->hasExternalStorage() && Old->hasLinkage()) /* Okay */; - else if (New->getCanonicalDecl()->getStorageClass() != SC_Static && - Old->getCanonicalDecl()->getStorageClass() == SC_Static) { + else if (New->getStorageClass() != SC_Static && + Old->getStorageClass() == SC_Static) { Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); @@ -2957,6 +2959,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, return; } + // c99 6.2.2 P4. + // For an identifier declared with the storage-class specifier extern in a + // scope in which a prior declaration of that identifier is visible, if + // the prior declaration specifies internal or external linkage, the linkage + // of the identifier at the later declaration is the same as the linkage + // specified at the prior declaration. + // FIXME. revisit this code. + if (New->hasExternalStorage() && + Old->getLinkage() == InternalLinkage) + New->setStorageClass(Old->getStorageClass()); + // Merge "used" flag. if (Old->isUsed(false)) New->setUsed(); @@ -3328,6 +3341,25 @@ StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) { llvm_unreachable("unknown storage class specifier"); } +/// StorageClassSpecToFunctionDeclStorageClass - Maps a DeclSpec::SCS to +/// a StorageClass. Any error reporting is up to the caller: +/// illegal input values are mapped to SC_None. +static StorageClass +StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) { + switch (StorageClassSpec) { + case DeclSpec::SCS_unspecified: return SC_None; + case DeclSpec::SCS_extern: return SC_Extern; + case DeclSpec::SCS_static: return SC_Static; + case DeclSpec::SCS_private_extern: return SC_PrivateExtern; + // Illegal SCSs map to None: error reporting is up to the caller. + case DeclSpec::SCS_auto: // Fall through. + case DeclSpec::SCS_mutable: // Fall through. + case DeclSpec::SCS_register: // Fall through. + case DeclSpec::SCS_typedef: return SC_None; + } + llvm_unreachable("unknown storage class specifier"); +} + /// BuildAnonymousStructOrUnion - Handle the declaration of an /// anonymous structure or union. Anonymous unions are a C++ feature /// (C++ [class.union]) and a C11 feature; anonymous structures @@ -3524,12 +3556,15 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Invalid = true; SC = SC_None; } + SCSpec = DS.getStorageClassSpecAsWritten(); + VarDecl::StorageClass SCAsWritten + = StorageClassSpecToVarDeclStorageClass(SCSpec); Anon = VarDecl::Create(Context, Owner, DS.getLocStart(), Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), - TInfo, SC); + TInfo, SC, SCAsWritten); // Default-initialize the implicit variable. This initialization will be // trivial in almost all cases, except if a union member has an in-class @@ -4644,7 +4679,7 @@ static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) { static bool shouldConsiderLinkage(const VarDecl *VD) { const DeclContext *DC = VD->getDeclContext()->getRedeclContext(); if (DC->isFunctionOrMethod()) - return VD->hasExternalStorage(); + return VD->hasExternalStorageAsWritten(); if (DC->isFileContext()) return true; if (DC->isRecord()) @@ -4691,6 +4726,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, SC = SC_None; } + SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten(); + VarDecl::StorageClass SCAsWritten + = StorageClassSpecToVarDeclStorageClass(SCSpec); + IdentifierInfo *II = Name.getAsIdentifierInfo(); if (!II) { Diag(D.getIdentifierLoc(), diag::err_bad_variable_name) @@ -4720,6 +4759,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // OpenCL __local address space. if (R.getAddressSpace() == LangAS::opencl_local) { SC = SC_OpenCLWorkGroupLocal; + SCAsWritten = SC_OpenCLWorkGroupLocal; } // OpenCL v1.2 s6.9.b p4: @@ -4752,7 +4792,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!getLangOpts().CPlusPlus) { NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, - R, TInfo, SC); + R, TInfo, SC, SCAsWritten); if (D.isInvalidType()) NewVD->setInvalidDecl(); @@ -4822,7 +4862,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, - R, TInfo, SC); + R, TInfo, SC, SCAsWritten); // If this decl has an auto type in need of deduction, make a note of the // Decl so we can diagnose uses of it in its own initializer. @@ -4904,6 +4944,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, (NewVD->hasAttr<CUDASharedAttr>() || NewVD->hasAttr<CUDAConstantAttr>())) { NewVD->setStorageClass(SC_Static); + NewVD->setStorageClassAsWritten(SC_Static); } } @@ -5643,6 +5684,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, FunctionDecl *NewFD = 0; bool isInline = D.getDeclSpec().isInlineSpecified(); + DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten(); + FunctionDecl::StorageClass SCAsWritten + = StorageClassSpecToFunctionDeclStorageClass(SCSpec); if (!SemaRef.getLangOpts().CPlusPlus) { // Determine whether the function was written with a @@ -5656,8 +5700,8 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), NameInfo, R, - TInfo, SC, isInline, - HasPrototype, false); + TInfo, SC, SCAsWritten, isInline, + HasPrototype); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -5724,7 +5768,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, return FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), D.getIdentifierLoc(), Name, R, TInfo, - SC, isInline, + SC, SCAsWritten, isInline, /*hasPrototype=*/true, isConstexpr); } @@ -5755,21 +5799,36 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, return 0; } + bool isStatic = SC == SC_Static; + + // [class.free]p1: + // Any allocation function for a class T is a static member + // (even if not explicitly declared static). + if (Name.getCXXOverloadedOperator() == OO_New || + Name.getCXXOverloadedOperator() == OO_Array_New) + isStatic = true; + + // [class.free]p6 Any deallocation function for a class X is a static member + // (even if not explicitly declared static). + if (Name.getCXXOverloadedOperator() == OO_Delete || + Name.getCXXOverloadedOperator() == OO_Array_Delete) + isStatic = true; + + IsVirtualOkay = !isStatic; + // This is a C++ method declaration. - CXXMethodDecl *Ret = CXXMethodDecl::Create(SemaRef.Context, - cast<CXXRecordDecl>(DC), - D.getLocStart(), NameInfo, R, - TInfo, SC, isInline, - isConstexpr, SourceLocation()); - IsVirtualOkay = !Ret->isStatic(); - return Ret; + return CXXMethodDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), + D.getLocStart(), NameInfo, R, + TInfo, isStatic, SCAsWritten, isInline, + isConstexpr, SourceLocation()); + } else { // Determine whether the function was written with a // prototype. This true when: // - we're in C++ (where every function has a prototype), return FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), - NameInfo, R, TInfo, SC, isInline, + NameInfo, R, TInfo, SC, SCAsWritten, isInline, true/*HasPrototype*/, isConstexpr); } } @@ -6335,7 +6394,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // A storage-class-specifier shall not be specified in an explicit // specialization (14.7.3) if (SC != SC_None) { - if (SC != NewFD->getTemplateSpecializationInfo()->getTemplate()->getTemplatedDecl()->getStorageClass()) + if (SC != NewFD->getStorageClass()) Diag(NewFD->getLocation(), diag::err_explicit_specialization_inconsistent_storage_class) << SC @@ -7588,7 +7647,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); } } else if (VDecl->isFileVarDecl()) { - if (VDecl->getStorageClass() == SC_Extern && + if (VDecl->getStorageClassAsWritten() == SC_Extern && (!getLangOpts().CPlusPlus || !(Context.getBaseElementType(VDecl->getType()).isConstQualified() || VDecl->isExternC()))) @@ -7878,7 +7937,7 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { // for-range-declaration cannot be given a storage class specifier. int Error = -1; - switch (VD->getStorageClass()) { + switch (VD->getStorageClassAsWritten()) { case SC_None: break; case SC_Extern: @@ -8192,11 +8251,14 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'. // C++03 [dcl.stc]p2 also permits 'auto'. VarDecl::StorageClass StorageClass = SC_None; + VarDecl::StorageClass StorageClassAsWritten = SC_None; if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { StorageClass = SC_Register; + StorageClassAsWritten = SC_Register; } else if (getLangOpts().CPlusPlus && DS.getStorageClassSpec() == DeclSpec::SCS_auto) { StorageClass = SC_Auto; + StorageClassAsWritten = SC_Auto; } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) { Diag(DS.getStorageClassSpecLoc(), diag::err_invalid_storage_class_in_func_decl); @@ -8269,7 +8331,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { D.getLocStart(), D.getIdentifierLoc(), II, parmDeclType, TInfo, - StorageClass); + StorageClass, StorageClassAsWritten); if (D.isInvalidType()) New->setInvalidDecl(); @@ -8308,7 +8370,7 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC, location for the unnamed parameters, embedding the parameter's type? */ ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, 0, T, Context.getTrivialTypeSourceInfo(T, Loc), - SC_None, 0); + SC_None, SC_None, 0); Param->setImplicit(); return Param; } @@ -8361,7 +8423,8 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param, ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, - VarDecl::StorageClass StorageClass) { + VarDecl::StorageClass StorageClass, + VarDecl::StorageClass StorageClassAsWritten) { // In ARC, infer a lifetime qualifier for appropriate parameter types. if (getLangOpts().ObjCAutoRefCount && T.getObjCLifetime() == Qualifiers::OCL_None && @@ -8388,7 +8451,8 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name, Context.getAdjustedParameterType(T), TSInfo, - StorageClass, 0); + StorageClass, StorageClassAsWritten, + 0); // Parameters can not be abstract class types. // For record types, this is done by the AbstractClassUsageDiagnoser once diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 982e7a5dd8..77c7dc59c8 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -5092,7 +5092,8 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), Loc, Loc, DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), - SC_None, false/*isInlineSpecified*/, + SC_None, SC_None, + false/*isInlineSpecified*/, FD->hasPrototype(), false/*isConstexprSpecified*/); NewD = NewFD; @@ -5117,7 +5118,8 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), VD->getInnerLocStart(), VD->getLocation(), II, VD->getType(), VD->getTypeSourceInfo(), - VD->getStorageClass()); + VD->getStorageClass(), + VD->getStorageClassAsWritten()); if (VD->getQualifier()) { VarDecl *NewVD = cast<VarDecl>(NewD); NewVD->setQualifierInfo(VD->getQualifierLoc()); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 35890e6deb..989edc6a45 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2852,7 +2852,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, = VarDecl::Create(SemaRef.Context, SemaRef.CurContext, Loc, Loc, IterationVarName, SizeType, SemaRef.Context.getTrivialTypeSourceInfo(SizeType, Loc), - SC_None); + SC_None, SC_None); IndexVariables.push_back(IterationVar); // Create a reference to the iteration variable. @@ -7822,7 +7822,7 @@ void Sema::DeclareInheritingConstructors(CXXRecordDecl *ClassDecl) { /*IdentifierInfo=*/0, BaseCtorType->getArgType(i), /*TInfo=*/0, SC_None, - /*DefaultArg=*/0); + SC_None, /*DefaultArg=*/0); PD->setScopeInfo(0, i); PD->setImplicit(); ParamDecls.push_back(PD); @@ -8275,7 +8275,7 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T, VarDecl *IterationVar = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, IterationVarName, SizeType, S.Context.getTrivialTypeSourceInfo(SizeType, Loc), - SC_None); + SC_None, SC_None); // Initialize the iteration variable to zero. llvm::APInt Zero(S.Context.getTypeSize(SizeType), 0); @@ -8439,8 +8439,8 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { DeclarationNameInfo NameInfo(Name, ClassLoc); CXXMethodDecl *CopyAssignment = CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(), - /*TInfo=*/0, - /*StorageClass=*/SC_None, + /*TInfo=*/0, /*isStatic=*/false, + /*StorageClassAsWritten=*/SC_None, /*isInline=*/true, /*isConstexpr=*/false, SourceLocation()); CopyAssignment->setAccess(AS_public); @@ -8457,6 +8457,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment, ClassLoc, ClassLoc, /*Id=*/0, ArgType, /*TInfo=*/0, + SC_None, SC_None, 0); CopyAssignment->setParams(FromParam); @@ -8887,8 +8888,8 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { DeclarationNameInfo NameInfo(Name, ClassLoc); CXXMethodDecl *MoveAssignment = CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(), - /*TInfo=*/0, - /*StorageClass=*/SC_None, + /*TInfo=*/0, /*isStatic=*/false, + /*StorageClassAsWritten=*/SC_None, /*isInline=*/true, /*isConstexpr=*/false, SourceLocation()); @@ -8906,6 +8907,7 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveAssignment, ClassLoc, ClassLoc, /*Id=*/0, ArgType, /*TInfo=*/0, + SC_None, SC_None, 0); MoveAssignment->setParams(FromParam); @@ -9260,6 +9262,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( ClassLoc, ClassLoc, /*IdentifierInfo=*/0, ArgType, /*TInfo=*/0, + SC_None, SC_None, 0); CopyConstructor->setParams(FromParam); @@ -9446,6 +9449,7 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( ClassLoc, ClassLoc, /*IdentifierInfo=*/0, ArgType, /*TInfo=*/0, + SC_None, SC_None, 0); MoveConstructor->setParams(FromParam); @@ -10277,7 +10281,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, } VarDecl *ExDecl = VarDecl::Create(Context, CurContext, StartLoc, Loc, Name, - ExDeclType, TInfo, SC_None); + ExDeclType, TInfo, SC_None, SC_None); ExDecl->setExceptionVariable(true); // In ARC, infer 'retaining' for variables of retainable type. diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 5d16f3eae6..1e2e4843ba 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -2930,7 +2930,7 @@ Decl *Sema::ActOnMethodDeclaration( ParmVarDecl* Param = CheckParameter(ObjCMethod, StartLoc, ArgInfo[i].NameLoc, ArgInfo[i].Name, - ArgType, DI, SC_None); + ArgType, DI, SC_None, SC_None); Param->setObjCMethodScopeInfo(i); @@ -3161,7 +3161,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType T, } VarDecl *New = VarDecl::Create(Context, CurContext, StartLoc, IdLoc, Id, - T, TInfo, SC_None); + T, TInfo, SC_None, SC_None); New->setExceptionVariable(true); // In ARC, infer 'retaining' for variables of retainable type. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bcf5b78c34..5459d74016 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -162,7 +162,7 @@ static bool hasAnyExplicitStorageClass(const FunctionDecl *D) { for (FunctionDecl::redecl_iterator I = D->redecls_begin(), E = D->redecls_end(); I != E; ++I) { - if (I->getStorageClass() != SC_None) + if (I->getStorageClassAsWritten() != SC_None) return true; } return false; @@ -10854,7 +10854,7 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, IterationVarName, SizeType, S.Context.getTrivialTypeSourceInfo(SizeType, Loc), - SC_None); + SC_None, SC_None); IndexVariables.push_back(IterationVar); LSI->ArrayIndexVars.push_back(IterationVar); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 3f2cb02673..b586fd70b0 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1946,7 +1946,8 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, FunctionDecl *Alloc = FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, - FnType, /*TInfo=*/0, SC_None, false, true); + FnType, /*TInfo=*/0, SC_None, + SC_None, false, true); Alloc->setImplicit(); if (AddMallocAttr) @@ -1955,7 +1956,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(), SourceLocation(), 0, Argument, /*TInfo=*/0, - SC_None, 0); + SC_None, SC_None, 0); Alloc->setParams(Param); // FIXME: Also add this declaration to the IdentifierResolver, but diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 51a190651e..af8380df18 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -238,7 +238,7 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc, SourceLocation(), SourceLocation(), &CX.Idents.get("value"), NumberType, /*TInfo=*/0, SC_None, - 0); + SC_None, 0); Method->setMethodParams(S.Context, value, ArrayRef<SourceLocation>()); } @@ -489,7 +489,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { &Context.Idents.get("value"), Context.getPointerType(ConstCharType), /*TInfo=*/0, - SC_None, 0); + SC_None, SC_None, 0); M->setMethodParams(Context, value, ArrayRef<SourceLocation>()); BoxingMethod = M; } @@ -656,14 +656,16 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) { SourceLocation(), &Context.Idents.get("objects"), Context.getPointerType(IdT), - /*TInfo=*/0, SC_None, 0); + /*TInfo=*/0, SC_None, SC_None, + 0); Params.push_back(objects); ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method, SourceLocation(), SourceLocation(), &Context.Idents.get("cnt"), Context.UnsignedLongTy, - /*TInfo=*/0, SC_None, 0); + /*TInfo=*/0, SC_None, SC_None, + 0); Params.push_back(cnt); Method->setMethodParams(Context, Params, ArrayRef<SourceLocation>()); } @@ -772,21 +774,24 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, SourceLocation(), &Context.Idents.get("objects"), Context.getPointerType(IdT), - /*TInfo=*/0, SC_None, 0); + /*TInfo=*/0, SC_None, SC_None, + 0); Params.push_back(objects); ParmVarDecl *keys = ParmVarDecl::Create(Context, Method, SourceLocation(), SourceLocation(), &Context.Idents.get("keys"), Context.getPointerType(IdT), - /*TInfo=*/0, SC_None, 0); + /*TInfo=*/0, SC_None, SC_None, + 0); Params.push_back(keys); ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method, SourceLocation(), SourceLocation(), &Context.Idents.get("cnt"), Context.UnsignedLongTy, - /*TInfo=*/0, SC_None, 0); + /*TInfo=*/0, SC_None, SC_None, + 0); Params.push_back(cnt); Method->setMethodParams(Context, Params, ArrayRef<SourceLocation>()); } diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 53fa6dafdd..468fa0251e 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -74,6 +74,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, IntroducerRange.getBegin(), MethodNameLoc), MethodType->getType(), MethodType, + /*isStatic=*/false, SC_None, /*isInline=*/true, /*isConstExpr=*/false, @@ -737,7 +738,7 @@ static void addFunctionPointerConversion(Sema &S, = CXXMethodDecl::Create(S.Context, Class, Loc, DeclarationNameInfo(Name, Loc), FunctionTy, CallOperator->getTypeSourceInfo(), - SC_Static, /*IsInline=*/true, + /*IsStatic=*/true, SC_Static, /*IsInline=*/true, /*IsConstexpr=*/false, CallOperator->getBody()->getLocEnd()); SmallVector<ParmVarDecl *, 4> InvokeParams; @@ -750,6 +751,7 @@ static void addFunctionPointerConversion(Sema &S, From->getType(), From->getTypeSourceInfo(), From->getStorageClass(), + From->getStorageClassAsWritten(), /*DefaultArg=*/0)); } Invoke->setParams(InvokeParams); @@ -1008,6 +1010,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, From->getType(), From->getTypeSourceInfo(), From->getStorageClass(), + From->getStorageClassAsWritten(), /*DefaultArg=*/0)); } Block->setParams(BlockParams); @@ -1022,7 +1025,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation, ConvLocation, 0, Src->getType(), CapVarTSI, - SC_None); + SC_None, SC_None); BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false, /*Nested=*/false, /*Copy=*/Init.take()); Block->setCaptures(Context, &Capture, &Capture + 1, diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 824a249084..7ad8bc722d 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -1973,6 +1973,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, property->getType().getUnqualifiedType(), /*TInfo=*/0, SC_None, + SC_None, 0); SetterMethod->setMethodParams(Context, Argument, ArrayRef<SourceLocation>()); diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index b135507b1a..57706759f3 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -1087,6 +1087,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() { : S.Context.getObjCIdType(), /*TInfo=*/0, SC_None, + SC_None, 0); AtIndexGetter->setMethodParams(S.Context, Argument, ArrayRef<SourceLocation>()); @@ -1201,6 +1202,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { S.Context.getObjCIdType(), /*TInfo=*/0, SC_None, + SC_None, 0); Params.push_back(object); ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter, @@ -1211,6 +1213,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() { : S.Context.getObjCIdType(), /*TInfo=*/0, SC_None, + SC_None, 0); Params.push_back(key); AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>()); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index ff1db821b6..a2dc616deb 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1665,7 +1665,7 @@ VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc, IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, - TInfo, SC_None); + TInfo, SC_Auto, SC_None); Decl->setImplicit(); return Decl; } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 990626189e..adf25ce3ae 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -6057,7 +6057,8 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, TemplArgs, /*InsertPos=*/0, SpecInfo->getTemplateSpecializationKind(), ExplicitTemplateArgs); - + FD->setStorageClass(Specialization->getStorageClass()); + // The "previous declaration" for this function template specialization is // the prior function template specialization. Previous.clear(); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index f755b8ca45..255df80d66 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1682,7 +1682,8 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, OldParm->getLocation(), OldParm->getIdentifier(), NewDI->getType(), NewDI, - OldParm->getStorageClass()); + OldParm->getStorageClass(), + OldParm->getStorageClassAsWritten()); if (!NewParm) return 0; diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 33e83d07d6..55725b603e 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -338,7 +338,8 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { D->getInnerLocStart(), D->getLocation(), D->getIdentifier(), DI->getType(), DI, - D->getStorageClass()); + D->getStorageClass(), + D->getStorageClassAsWritten()); Var->setThreadSpecified(D->isThreadSpecified()); Var->setInitStyle(D->getInitStyle()); Var->setCXXForRangeDecl(D->isCXXForRangeDecl()); @@ -1162,7 +1163,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, FunctionDecl *Function = FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, - D->getStorageClass(), + D->getStorageClass(), D->getStorageClassAsWritten(), D->isInlineSpecified(), D->hasWrittenPrototype(), D->isConstexpr()); @@ -1528,7 +1529,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, } else { Method = CXXMethodDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - D->getStorageClass(), + D->isStatic(), + D->getStorageClassAsWritten(), D->isInlineSpecified(), D->isConstexpr(), D->getLocEnd()); } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 7169eeab9b..136de7c221 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2301,7 +2301,7 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D, if (!D.isFunctionDeclarator() || D.getFunctionDefinitionKind() != FDK_Declaration || !S.CurContext->isFunctionOrMethod() || - D.getDeclSpec().getStorageClassSpec() + D.getDeclSpec().getStorageClassSpecAsWritten() != DeclSpec::SCS_unspecified) return; diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index bdd68a7bde..e228d7a0f2 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3994,6 +3994,7 @@ ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam( NewDI->getType(), NewDI, OldParm->getStorageClass(), + OldParm->getStorageClassAsWritten(), /* DefArg */ NULL); newParm->setScopeInfo(OldParm->getFunctionScopeDepth(), OldParm->getFunctionScopeIndex() + indexAdjustment); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 3dcae6fe6a..12114336b2 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -504,8 +504,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // FunctionDecl's body is handled last at ASTDeclReader::Visit, // after everything else is read. - + FD->SClass = (StorageClass)Record[Idx++]; + FD->SClassAsWritten = (StorageClass)Record[Idx++]; FD->IsInline = Record[Idx++]; FD->IsInlineSpecified = Record[Idx++]; FD->IsVirtualAsWritten = Record[Idx++]; @@ -893,8 +894,9 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { void ASTDeclReader::VisitVarDecl(VarDecl *VD) { RedeclarableResult Redecl = VisitRedeclarable(VD); VisitDeclaratorDecl(VD); - + VD->VarDeclBits.SClass = (StorageClass)Record[Idx++]; + VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++]; VD->VarDeclBits.ThreadSpecified = Record[Idx++]; VD->VarDeclBits.InitStyle = Record[Idx++]; VD->VarDeclBits.ExceptionVar = Record[Idx++]; diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 023599d0db..1e1e12ee5a 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -319,6 +319,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { // after everything else is written. Record.push_back(D->getStorageClass()); // FIXME: stable encoding + Record.push_back(D->getStorageClassAsWritten()); Record.push_back(D->IsInline); Record.push_back(D->isInlineSpecified()); Record.push_back(D->isVirtualAsWritten()); @@ -676,7 +677,8 @@ void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VisitRedeclarable(D); VisitDeclaratorDecl(D); - Record.push_back(D->getStorageClass()); + Record.push_back(D->getStorageClass()); // FIXME: stable encoding + Record.push_back(D->getStorageClassAsWritten()); Record.push_back(D->isThreadSpecified()); Record.push_back(D->getInitStyle()); Record.push_back(D->isExceptionVariable()); @@ -1515,6 +1517,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo // VarDecl Abv->Add(BitCodeAbbrevOp(0)); // StorageClass + Abv->Add(BitCodeAbbrevOp(0)); // StorageClassAsWritten Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer Abv->Add(BitCodeAbbrevOp(0)); // isExceptionVariable @@ -1594,6 +1597,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo // VarDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClassAsWritten Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isThreadSpecified Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CXXDirectInitializer Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable |