summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.cpp1
-rw-r--r--clang/lib/Sema/Sema.h7
-rw-r--r--clang/lib/Sema/SemaDecl.cpp31
3 files changed, 38 insertions, 1 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index c289abfea86..ba05a07f265 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -117,6 +117,7 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val,
llvm::raw_string_ostream OS(S);
reinterpret_cast<NestedNameSpecifier*> (Val)->print(OS,
Context.PrintingPolicy);
+ NeedQuotes = false;
} else {
assert(Kind == Diagnostic::ak_declcontext);
DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 465eca70ed3..04addfd3a98 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -523,7 +523,12 @@ public:
Scope *S, const CXXScopeSpec *SS,
bool isClassName = false);
virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
-
+ virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
+ SourceLocation IILoc,
+ Scope *S,
+ const CXXScopeSpec *SS,
+ TypeTy *&SuggestedType);
+
virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9f03cb284ca..606b33f5f74 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -23,6 +23,7 @@
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -199,6 +200,36 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
return DeclSpec::TST_unspecified;
}
+bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
+ SourceLocation IILoc,
+ Scope *S,
+ const CXXScopeSpec *SS,
+ TypeTy *&SuggestedType) {
+ // We don't have anything to suggest (yet).
+ SuggestedType = 0;
+
+ // FIXME: Should we move the logic that tries to recover from a missing tag
+ // (struct, union, enum) from Parser::ParseImplicitInt here, instead?
+
+ if (!SS)
+ Diag(IILoc, diag::err_unknown_typename) << &II;
+ else if (DeclContext *DC = computeDeclContext(*SS, false))
+ Diag(IILoc, diag::err_typename_nested_not_found)
+ << &II << DC << SS->getRange();
+ else if (isDependentScopeSpecifier(*SS)) {
+ Diag(SS->getRange().getBegin(), diag::err_typename_missing)
+ << (NestedNameSpecifier *)SS->getScopeRep() << II.getName()
+ << SourceRange(SS->getRange().getBegin(), IILoc)
+ << CodeModificationHint::CreateInsertion(SS->getRange().getBegin(),
+ "typename ");
+ SuggestedType = ActOnTypenameType(SourceLocation(), *SS, II, IILoc).get();
+ } else {
+ assert(SS && SS->isInvalid() &&
+ "Invalid scope specifier has already been diagnosed");
+ }
+
+ return true;
+}
// Determines the context to return to after temporarily entering a
// context. This depends in an unnecessarily complicated way on the
OpenPOWER on IntegriCloud