summaryrefslogtreecommitdiffstats
path: root/lib/Parse
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse')
-rw-r--r--lib/Parse/AttributeList.cpp13
-rw-r--r--lib/Parse/ParseExpr.cpp42
-rw-r--r--lib/Parse/ParseExprCXX.cpp3
-rw-r--r--lib/Parse/ParseInit.cpp9
-rw-r--r--lib/Parse/ParseObjc.cpp7
-rw-r--r--lib/Parse/ParseStmt.cpp4
-rw-r--r--lib/Parse/Parser.cpp5
7 files changed, 59 insertions, 24 deletions
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
index 2ee41bc..224a31c 100644
--- a/lib/Parse/AttributeList.cpp
+++ b/lib/Parse/AttributeList.cpp
@@ -45,18 +45,15 @@ AttributeList::~AttributeList() {
}
AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
- const char *Str = Name->getName();
- unsigned Len = Name->getLength();
+ llvm::StringRef AttrName = Name->getName();
// Normalize the attribute name, __foo__ becomes foo.
- if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
- Str[Len - 2] == '_' && Str[Len - 1] == '_') {
- Str += 2;
- Len -= 4;
- }
+ if (AttrName.startswith("__") && AttrName.endswith("__"))
+ AttrName = AttrName.substr(2, AttrName.size() - 4);
// FIXME: Hand generating this is neither smart nor efficient.
- switch (Len) {
+ const char *Str = AttrName.data();
+ switch (AttrName.size()) {
case 4:
if (!memcmp(Str, "weak", 4)) return AT_weak;
if (!memcmp(Str, "pure", 4)) return AT_pure;
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 72e30e3..8be89a8 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -972,13 +972,41 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
return ExprError();
}
- if (!LHS.isInvalid())
- LHS = Actions.ActOnDestructorReferenceExpr(CurScope, move(LHS),
- OpLoc, OpKind,
- Tok.getLocation(),
- Tok.getIdentifierInfo(),
- SS,
- NextToken().is(tok::l_paren));
+ if (NextToken().is(tok::less)) {
+ // class-name:
+ // ~ simple-template-id
+ TemplateTy Template
+ = Actions.ActOnDependentTemplateName(SourceLocation(),
+ *Tok.getIdentifierInfo(),
+ Tok.getLocation(),
+ SS,
+ ObjectType);
+ if (AnnotateTemplateIdToken(Template, TNK_Type_template, &SS,
+ SourceLocation(), true))
+ return ExprError();
+
+ assert(Tok.is(tok::annot_typename) &&
+ "AnnotateTemplateIdToken didn't work?");
+ if (!LHS.isInvalid())
+ LHS = Actions.ActOnDestructorReferenceExpr(CurScope, move(LHS),
+ OpLoc, OpKind,
+ Tok.getAnnotationRange(),
+ Tok.getAnnotationValue(),
+ SS,
+ NextToken().is(tok::l_paren));
+ } else {
+ // class-name:
+ // ~ identifier
+ if (!LHS.isInvalid())
+ LHS = Actions.ActOnDestructorReferenceExpr(CurScope, move(LHS),
+ OpLoc, OpKind,
+ Tok.getLocation(),
+ Tok.getIdentifierInfo(),
+ SS,
+ NextToken().is(tok::l_paren));
+ }
+
+ // Consume the identifier or template-id token.
ConsumeToken();
} else if (getLang().CPlusPlus && Tok.is(tok::kw_operator)) {
// We have a reference to a member operator, e.g., t.operator int or
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 325f085..fa65156 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -356,7 +356,8 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
TemplateId->NumArgs);
OwningExprResult Result
- = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template),
+ = Actions.ActOnTemplateIdExpr(SS,
+ TemplateTy::make(TemplateId->Template),
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 6ab23fd..c4e79ca 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -15,6 +15,7 @@
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -65,9 +66,9 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
if (Tok.is(tok::identifier)) {
const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
- std::string NewSyntax(".");
- NewSyntax += FieldName->getName();
- NewSyntax += " = ";
+ llvm::SmallString<256> NewSyntax;
+ llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName()
+ << " = ";
SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
@@ -77,7 +78,7 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() {
Diag(Tok, diag::ext_gnu_old_style_field_designator)
<< CodeModificationHint::CreateReplacement(SourceRange(NameLoc,
ColonLoc),
- NewSyntax);
+ NewSyntax.str());
Designation D;
D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 1d29f31..2e0cd6d 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -428,7 +428,7 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
return;
}
- if (II->getName()[0] == 's') {
+ if (II->getNameStart()[0] == 's') {
DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
DS.setSetterName(Tok.getIdentifierInfo());
ConsumeToken(); // consume method name
@@ -1371,8 +1371,11 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {
"parsing Objective-C method");
// parse optional ';'
- if (Tok.is(tok::semi))
+ if (Tok.is(tok::semi)) {
+ if (ObjCImpDecl)
+ Diag(Tok, diag::warn_semicolon_before_method_nody);
ConsumeToken();
+ }
// We should have an opening brace now.
if (Tok.isNot(tok::l_brace)) {
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 907ca80..272be2f 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1256,6 +1256,8 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) {
/// asm-string-literal '(' expression ')'
/// '[' identifier ']' asm-string-literal '(' expression ')'
///
+//
+// FIXME: Avoid unnecessary std::string trashing.
bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
llvm::SmallVectorImpl<ExprTy*> &Constraints,
llvm::SmallVectorImpl<ExprTy*> &Exprs) {
@@ -1281,7 +1283,7 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
IdentifierInfo *II = Tok.getIdentifierInfo();
ConsumeToken();
- Names.push_back(std::string(II->getName(), II->getLength()));
+ Names.push_back(II->getName());
MatchRHSPunctuation(tok::r_square, Loc);
} else
Names.push_back(std::string());
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 2f500a4..bc737e9 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -77,7 +77,10 @@ void PrettyStackTraceParserEntry::print(llvm::raw_ostream &OS) const {
const Preprocessor &PP = P.getPreprocessor();
Tok.getLocation().print(OS, PP.getSourceManager());
- OS << ": current parser token '" << PP.getSpelling(Tok) << "'\n";
+ if (Tok.isAnnotation())
+ OS << ": at annotation token \n";
+ else
+ OS << ": current parser token '" << PP.getSpelling(Tok) << "'\n";
}
OpenPOWER on IntegriCloud