From: Abramo Bagnara Date: Wed, 16 Mar 2011 20:16:18 +0000 (+0000) Subject: Use ElaboratedType also for C. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0daaf32723ac78549c507c2a68a5300502703673;p=clang Use ElaboratedType also for C. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127755 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index a59c302ffc..5d52cde4b1 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -38,7 +38,7 @@ struct PrintingPolicy { /// \brief Create a default printing policy for C. PrintingPolicy(const LangOptions &LO) : Indentation(2), LangOpts(LO), SuppressSpecifiers(false), - SuppressTag(false), SuppressScope(false), + SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), Dump(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true) { } @@ -64,6 +64,16 @@ struct PrintingPolicy { /// "const int" type specifier and instead only print the "*y". bool SuppressSpecifiers : 1; + /// \brief Whether type printing should skip printing the tag keyword. + /// + /// This is used when printing the inner type of elaborated types, + /// (as the tag keyword is part of the elaborated type): + /// + /// \code + /// struct Geometry::Point; + /// \endcode + bool SuppressTagKeyword : 1; + /// \brief Whether type printing should skip printing the actual tag type. /// /// This is used when the caller needs to print a tag definition in front diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 2757daa673..03573b02a3 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -329,6 +329,11 @@ private: SourceLocation StorageClassSpecLoc, SCS_threadLoc; SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc; + /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, + /// typename, then this is the location of the named type (if present); + /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and + /// TSTNameLoc provides source range info for tag types. + SourceLocation TSTNameLoc; SourceRange TypeofParensRange; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; @@ -431,6 +436,11 @@ public: SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } SourceLocation getAltiVecLoc() const { return AltiVecLoc; } + SourceLocation getTypeSpecTypeNameLoc() const { + assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename); + return TSTNameLoc; + } + SourceRange getTypeofParensRange() const { return TypeofParensRange; } void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } @@ -522,6 +532,13 @@ public: unsigned &DiagID, ParsedType Rep); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned); + bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, + SourceLocation TagNameLoc, const char *&PrevSpec, + unsigned &DiagID, ParsedType Rep); + bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, + SourceLocation TagNameLoc, const char *&PrevSpec, + unsigned &DiagID, Decl *Rep, bool Owned); + bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Expr *Rep); bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index d0267caabd..e287c46fa9 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -557,9 +557,13 @@ void TypePrinter::printTag(TagDecl *D, std::string &InnerString) { std::string Buffer; bool HasKindDecoration = false; + // bool SuppressTagKeyword + // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; + // We don't print tags unless this is an elaborated type. // In C, we just assume every RecordType is an elaborated type. - if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) { + if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || + D->getTypedefForAnonDecl())) { HasKindDecoration = true; Buffer += D->getKindName(); Buffer += ' '; @@ -701,6 +705,7 @@ void TypePrinter::printElaborated(const ElaboratedType *T, std::string &S) { std::string TypeStr; PrintingPolicy InnerPolicy(Policy); + InnerPolicy.SuppressTagKeyword = true; InnerPolicy.SuppressScope = true; TypePrinter(InnerPolicy).print(T->getNamedType(), TypeStr); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d0e410f9bf..42083803b6 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2123,7 +2123,6 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, bool Owned = false; bool IsDependent = false; - SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; const char *PrevSpec = 0; unsigned DiagID; Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, @@ -2150,8 +2149,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, return; } - if (DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, PrevSpec, DiagID, - Type.get())) + if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, + NameLoc.isValid() ? NameLoc : StartLoc, + PrevSpec, DiagID, Type.get())) Diag(StartLoc, DiagID) << PrevSpec; return; @@ -2172,10 +2172,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, if (Tok.is(tok::l_brace)) ParseEnumBody(StartLoc, TagDecl); - // FIXME: The DeclSpec should keep the locations of both the keyword - // and the name (if there is one). - if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID, - TagDecl, Owned)) + if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc, + NameLoc.isValid() ? NameLoc : StartLoc, + PrevSpec, DiagID, TagDecl, Owned)) Diag(StartLoc, DiagID) << PrevSpec; } diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 2cd2398157..ee8690fc69 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1017,19 +1017,17 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); } - // FIXME: The DeclSpec should keep the locations of both the keyword and the - // name (if there is one). - SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; - const char *PrevSpec = 0; unsigned DiagID; bool Result; if (!TypeResult.isInvalid()) { - Result = DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, + Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, + NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec, DiagID, TypeResult.get()); } else if (!TagOrTempResult.isInvalid()) { - Result = DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID, - TagOrTempResult.get(), Owned); + Result = DS.SetTypeSpecType(TagType, StartLoc, + NameLoc.isValid() ? NameLoc : StartLoc, + PrevSpec, DiagID, TagOrTempResult.get(), Owned); } else { DS.SetTypeSpecError(); return; diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 825d1afa0b..8cbf9d9fed 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -421,6 +421,14 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ParsedType Rep) { + return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep); +} + +bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, + SourceLocation TagNameLoc, + const char *&PrevSpec, + unsigned &DiagID, + ParsedType Rep) { assert(isTypeRep(T) && "T does not store a type"); assert(Rep && "no type provided!"); if (TypeSpecType != TST_unspecified) { @@ -430,7 +438,8 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, } TypeSpecType = T; TypeRep = Rep; - TSTLoc = Loc; + TSTLoc = TagKwLoc; + TSTNameLoc = TagNameLoc; TypeSpecOwned = false; return false; } @@ -449,6 +458,7 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, TypeSpecType = T; ExprRep = Rep; TSTLoc = Loc; + TSTNameLoc = Loc; TypeSpecOwned = false; return false; } @@ -457,6 +467,14 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned) { + return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned); +} + +bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc, + SourceLocation TagNameLoc, + const char *&PrevSpec, + unsigned &DiagID, + Decl *Rep, bool Owned) { assert(isDeclRep(T) && "T does not store a decl"); // Unlike the other cases, we don't assert that we actually get a decl. @@ -467,7 +485,8 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, } TypeSpecType = T; DeclRep = Rep; - TSTLoc = Loc; + TSTLoc = TagKwLoc; + TSTNameLoc = TagNameLoc; TypeSpecOwned = Owned; return false; } @@ -482,13 +501,13 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, DiagID = diag::err_invalid_decl_spec_combination; return true; } + TSTLoc = Loc; + TSTNameLoc = Loc; if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { TypeAltiVecBool = true; - TSTLoc = Loc; return false; } TypeSpecType = T; - TSTLoc = Loc; TypeSpecOwned = false; if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); @@ -520,6 +539,7 @@ bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, } TypeAltiVecPixel = isAltiVecPixel; TSTLoc = Loc; + TSTNameLoc = Loc; return false; } @@ -527,6 +547,7 @@ bool DeclSpec::SetTypeSpecError() { TypeSpecType = TST_error; TypeSpecOwned = false; TSTLoc = SourceLocation(); + TSTNameLoc = SourceLocation(); return false; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index e766ced1b6..b78c21bbb6 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -728,7 +728,7 @@ static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) { } // If the type is deprecated or unavailable, diagnose it. - S.DiagnoseUseOfDecl(D, DS.getTypeSpecTypeLoc()); + S.DiagnoseUseOfDecl(D, DS.getTypeSpecTypeNameLoc()); assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 && DS.getTypeSpecSign() == 0 && "No qualifiers on tag names!"); @@ -736,12 +736,11 @@ static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) { // TypeQuals handled by caller. Result = Context.getTypeDeclType(D); - // In C++, make an ElaboratedType. - if (S.getLangOptions().CPlusPlus) { - ElaboratedTypeKeyword Keyword - = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType()); - Result = S.getElaboratedType(Keyword, DS.getTypeSpecScope(), Result); - } + // In both C and C++, make an ElaboratedType. + ElaboratedTypeKeyword Keyword + = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType()); + Result = S.getElaboratedType(Keyword, DS.getTypeSpecScope(), Result); + if (D->isInvalidDecl()) declarator.setInvalidType(true); break; @@ -2300,7 +2299,7 @@ namespace { // If we got no declarator info from previous Sema routines, // just fill with the typespec loc. if (!TInfo) { - TL.initialize(Context, DS.getTypeSpecTypeLoc()); + TL.initialize(Context, DS.getTypeSpecTypeNameLoc()); return; } @@ -2377,7 +2376,7 @@ namespace { : SourceLocation()); const CXXScopeSpec& SS = DS.getTypeSpecScope(); TL.setQualifierLoc(SS.getWithLocInContext(Context)); - TL.setNameLoc(DS.getTypeSpecTypeLoc()); + TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); } void VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc TL) { @@ -2398,7 +2397,10 @@ namespace { : SourceLocation()); const CXXScopeSpec& SS = DS.getTypeSpecScope(); TL.setQualifierLoc(SS.getWithLocInContext(Context)); - TL.setNameLoc(DS.getTypeSpecTypeLoc()); + TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); + } + void VisitTagTypeLoc(TagTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeNameLoc()); } void VisitTypeLoc(TypeLoc TL) { diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp index cddc5d6c0a..a785f21b73 100644 --- a/test/Index/annotate-nested-name-specifier.cpp +++ b/test/Index/annotate-nested-name-specifier.cpp @@ -149,13 +149,13 @@ struct X9 : X8 { // Base specifiers // CHECK: Identifier: "outer_alias" [16:19 - 16:30] NamespaceRef=outer_alias:10:11 -// CHECK: Punctuation: "::" [16:30 - 16:32] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] +// CHECK: Punctuation: "::" [16:30 - 16:32] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] // CHECK: Identifier: "inner" [16:32 - 16:37] NamespaceRef=inner:2:13 -// CHECK: Punctuation: "::" [16:37 - 16:39] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] +// CHECK: Punctuation: "::" [16:37 - 16:39] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] // CHECK: Identifier: "vector" [16:39 - 16:45] TemplateRef=vector:4:12 -// CHECK: Punctuation: "<" [16:45 - 16:46] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] +// CHECK: Punctuation: "<" [16:45 - 16:46] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] // CHECK: Identifier: "X" [16:46 - 16:47] TypeRef=struct X:12:8 -// CHECK: Punctuation: ">" [16:47 - 16:48] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] +// CHECK: Punctuation: ">" [16:47 - 16:48] C++ base class specifier=outer_alias::inner::vector:4:12 [access=public isVirtual=false] // CHECK: Keyword: "using" [17:3 - 17:8] UsingDeclaration=iterator[5:18] diff --git a/test/Index/annotate-tokens.c b/test/Index/annotate-tokens.c index fc26b679f8..162a224ed6 100644 --- a/test/Index/annotate-tokens.c +++ b/test/Index/annotate-tokens.c @@ -53,7 +53,7 @@ enum Color g(int i, ...) { // CHECK: Punctuation: ")" [5:17 - 5:18] UnexposedExpr= // CHECK: Punctuation: ";" [5:18 - 5:19] UnexposedStmt= // CHECK: Comment: "/* A comment */" [6:3 - 6:18] UnexposedStmt= -// CHECK: Keyword: "struct" [7:3 - 7:9] UnexposedStmt= +// CHECK: Keyword: "struct" [7:3 - 7:9] VarDecl=x:7:12 (Definition) // CHECK: Identifier: "X" [7:10 - 7:11] TypeRef=struct X:2:8 // CHECK: Identifier: "x" [7:12 - 7:13] VarDecl=x:7:12 (Definition) // CHECK: Punctuation: "=" [7:14 - 7:15] VarDecl=x:7:12 (Definition) @@ -91,7 +91,7 @@ enum Color g(int i, ...) { // CHECK: Identifier: "Int" [16:38 - 16:41] TypeRef=Int:12:13 // CHECK: Punctuation: "," [16:41 - 16:42] UnexposedExpr= // CHECK: Identifier: "Int" [16:43 - 16:46] TypeRef=Int:12:13 -// CHECK: Keyword: "struct" [18:3 - 18:9] UnexposedStmt= +// CHECK: Keyword: "struct" [18:3 - 18:9] VarDecl=x:18:12 (Definition) // CHECK: Identifier: "X" [18:10 - 18:11] TypeRef=struct X:2:8 // CHECK: Identifier: "x" [18:12 - 18:13] VarDecl=x:18:12 (Definition) // CHECK: Keyword: "do" [19:3 - 19:5] UnexposedStmt= @@ -107,7 +107,7 @@ enum Color g(int i, ...) { // CHECK: Punctuation: "." [21:13 - 21:14] MemberRefExpr=a:2:16 // CHECK: Identifier: "a" [21:14 - 21:15] MemberRefExpr=a:2:16 -// CHECK: Keyword: "enum" [23:3 - 23:7] UnexposedStmt= +// CHECK: Keyword: "enum" [23:3 - 23:7] VarDecl=c:23:14 (Definition) // CHECK: Identifier: "Color" [23:8 - 23:13] TypeRef=enum Color:11:6 // CHECK: Identifier: "c" [23:14 - 23:15] VarDecl=c:23:14 (Definition) // CHECK: Punctuation: ";" [23:15 - 23:16] UnexposedStmt= diff --git a/test/Index/recursive-member-access.c b/test/Index/recursive-member-access.c index 6e95efe9b2..87855ca361 100644 --- a/test/Index/recursive-member-access.c +++ b/test/Index/recursive-member-access.c @@ -257,7 +257,7 @@ int test_rdar8650865(struct rdar8650865 *s) { // CHECK-tokens: Keyword: "struct" [1:1 - 1:7] StructDecl=rdar8650865:1:8 (Definition) // CHECK-tokens: Identifier: "rdar8650865" [1:8 - 1:19] StructDecl=rdar8650865:1:8 (Definition) // CHECK-tokens: Punctuation: "{" [1:20 - 1:21] StructDecl=rdar8650865:1:8 (Definition) -// CHECK-tokens: Keyword: "struct" [2:3 - 2:9] StructDecl=rdar8650865:1:8 (Definition) +// CHECK-tokens: Keyword: "struct" [2:3 - 2:9] FieldDecl=first:2:23 (Definition) // CHECK-tokens: Identifier: "rdar8650865" [2:10 - 2:21] TypeRef=struct rdar8650865:1:8 // CHECK-tokens: Punctuation: "*" [2:22 - 2:23] FieldDecl=first:2:23 (Definition) // CHECK-tokens: Identifier: "first" [2:23 - 2:28] FieldDecl=first:2:23 (Definition) @@ -270,7 +270,7 @@ int test_rdar8650865(struct rdar8650865 *s) { // CHECK-tokens: Keyword: "int" [6:1 - 6:4] FunctionDecl=test_rdar8650865:6:5 (Definition) // CHECK-tokens: Identifier: "test_rdar8650865" [6:5 - 6:21] FunctionDecl=test_rdar8650865:6:5 (Definition) // CHECK-tokens: Punctuation: "(" [6:21 - 6:22] FunctionDecl=test_rdar8650865:6:5 (Definition) -// CHECK-tokens: Keyword: "struct" [6:22 - 6:28] FunctionDecl=test_rdar8650865:6:5 (Definition) +// CHECK-tokens: Keyword: "struct" [6:22 - 6:28] ParmDecl=s:6:42 (Definition) // CHECK-tokens: Identifier: "rdar8650865" [6:29 - 6:40] TypeRef=struct rdar8650865:1:8 // CHECK-tokens: Punctuation: "*" [6:41 - 6:42] ParmDecl=s:6:42 (Definition) // CHECK-tokens: Identifier: "s" [6:42 - 6:43] ParmDecl=s:6:42 (Definition) diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp index 602d76baa9..0537aa20d5 100644 --- a/test/SemaCXX/sourceranges.cpp +++ b/test/SemaCXX/sourceranges.cpp @@ -13,15 +13,15 @@ typedef int C; } int main() { - // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} 'foo::class A *' + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} 'foo::A *' P p14 = new foo::A; - // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} 'foo::enum B *' + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} 'foo::B *' P p24 = new foo::B; // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} 'foo::C *' P pr4 = new foo::C; } foo::A getName() { - // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} 'foo::class A' + // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} 'foo::A' return foo::A(); }