aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaDecl.cpp23
2 files changed, 25 insertions, 0 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index e8eb960a3f..f48e75afb3 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -332,6 +332,8 @@ public:
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS);
+ virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
+
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
return ActOnDeclarator(S, D, false);
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 603b8b31a2..8ce624b788 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -139,6 +139,29 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
return 0;
}
+/// isTagName() - This method is called *for error recovery purposes only*
+/// to determine if the specified name is a valid tag name ("struct foo"). If
+/// so, this returns the TST for the tag corresponding to it (TST_enum,
+/// TST_union, TST_struct, TST_class). This is used to diagnose cases in C
+/// where the user forgot to specify the tag.
+DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
+ // Do a tag name lookup in this scope.
+ LookupResult R = LookupName(S, &II, LookupTagName, false, false);
+ if (R.getKind() == LookupResult::Found)
+ if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsDecl())) {
+ switch (TD->getTagKind()) {
+ case TagDecl::TK_struct: return DeclSpec::TST_struct;
+ case TagDecl::TK_union: return DeclSpec::TST_union;
+ case TagDecl::TK_class: return DeclSpec::TST_class;
+ case TagDecl::TK_enum: return DeclSpec::TST_enum;
+ }
+ }
+
+ return DeclSpec::TST_unspecified;
+}
+
+
+
DeclContext *Sema::getContainingDC(DeclContext *DC) {
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
// A C++ out-of-line method will return to the file declaration context.