diff options
author | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-07-30 16:47:02 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-07-30 16:47:02 +0000 |
commit | 35f9a196ef897b9559de25aaecd957208f0b4f59 (patch) | |
tree | 40ed53f154273d6c26af74c1ed72c5cb19c83ec4 /lib/Parse/DeclSpec.cpp | |
parent | acc9bf3716be80a19f514f228cb903c0910a1725 (diff) |
Fixed typedef inside extern "C".
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109865 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/DeclSpec.cpp')
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index d2cd74418a..c5072276bc 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -219,8 +219,15 @@ const char *DeclSpec::getSpecifierName(TQ T) { bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { - if (StorageClassSpec != SCS_unspecified) - return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID); + if (StorageClassSpec != SCS_unspecified) { + // Changing storage class is allowed only if the previous one + // was the 'extern' that is part of a linkage specification and + // the new storage class is 'typedef'. + if (!(SCS_extern_in_linkage_spec && + StorageClassSpec == SCS_extern && + S == SCS_typedef)) + return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID); + } StorageClassSpec = S; StorageClassSpecLoc = Loc; assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield"); @@ -240,7 +247,6 @@ bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, return false; } - /// These methods set the specified attribute of the DeclSpec, but return true /// and ignore the request if invalid (e.g. "extern" then "auto" is /// specified). @@ -430,6 +436,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, |