diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 33 | ||||
-rw-r--r-- | clang/lib/AST/ExprClassification.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 25 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 4 |
7 files changed, 71 insertions, 2 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index e35091a1017..0fdca5a33b1 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1681,7 +1681,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1, // Fallthrough for generic call handling. } case CallExprClass: - case CXXMemberCallExprClass: { + case CXXMemberCallExprClass: + case UserDefinedLiteralClass: { // If this is a direct call, get the callee. const CallExpr *CE = cast<CallExpr>(this); if (const Decl *FD = CE->getCalleeDecl()) { @@ -2014,7 +2015,8 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const { // exception-specification case CallExprClass: case CXXMemberCallExprClass: - case CXXOperatorCallExprClass: { + case CXXOperatorCallExprClass: + case UserDefinedLiteralClass: { const CallExpr *CE = cast<CallExpr>(this); CanThrowResult CT; if (isTypeDependent()) diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index dc559f0940f..039d70cfc56 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -624,6 +624,39 @@ CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) { return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize); } +UserDefinedLiteral::LiteralOperatorKind +UserDefinedLiteral::getLiteralOperatorKind() const { + if (getNumArgs() == 0) + return LOK_Template; + if (getNumArgs() == 2) + return LOK_String; + + assert(getNumArgs() == 1 && "unexpected #args in literal operator call"); + QualType ParamTy = + cast<FunctionDecl>(getCalleeDecl())->getParamDecl(0)->getType(); + if (ParamTy->isPointerType()) + return LOK_Raw; + if (ParamTy->isAnyCharacterType()) + return LOK_Character; + if (ParamTy->isIntegerType()) + return LOK_Integer; + if (ParamTy->isFloatingType()) + return LOK_Floating; + + llvm_unreachable("unknown kind of literal operator"); +} + +Expr *UserDefinedLiteral::getCookedLiteral() { +#ifndef NDEBUG + LiteralOperatorKind LOK = getLiteralOperatorKind(); + assert(LOK != LOK_Template && LOK != LOK_Raw && "not a cooked literal"); +#endif + return getArg(0); +} + +const IdentifierInfo *UserDefinedLiteral::getUDSuffix() const { + return cast<FunctionDecl>(getCalleeDecl())->getLiteralIdentifier(); +} CXXDefaultArgExpr * CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 693e28c8a45..00160a00737 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -269,6 +269,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::CallExprClass: case Expr::CXXOperatorCallExprClass: case Expr::CXXMemberCallExprClass: + case Expr::UserDefinedLiteralClass: case Expr::CUDAKernelCallExprClass: return ClassifyUnnamed(Ctx, cast<CallExpr>(E)->getCallReturnType()); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 08794f355f7..947f661c2ca 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6243,6 +6243,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::CXXTypeidExprClass: case Expr::CXXUuidofExprClass: case Expr::CXXNullPtrLiteralExprClass: + case Expr::UserDefinedLiteralClass: case Expr::CXXThisExprClass: case Expr::CXXThrowExprClass: case Expr::CXXNewExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index ea6e8b2e23c..c4eed7c34d6 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2439,6 +2439,9 @@ recurse: Arity); break; + case Expr::UserDefinedLiteralClass: + // We follow g++'s approach of mangling a UDL as a call to the literal + // operator. case Expr::CXXMemberCallExprClass: // fallthrough case Expr::CallExprClass: { const CallExpr *CE = cast<CallExpr>(E); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index cd8b6bb5c23..b8e68d8574a 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1222,6 +1222,31 @@ void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { OS << ")"; } +void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { + switch (Node->getLiteralOperatorKind()) { + case UserDefinedLiteral::LOK_Raw: + OS << cast<StringLiteral>(Node->getArg(0))->getString(); + break; + case UserDefinedLiteral::LOK_Template: { + DeclRefExpr *DRE = cast<DeclRefExpr>(Node->getCallee()); + assert(DRE->hasExplicitTemplateArgs()); + const TemplateArgumentLoc *Args = DRE->getTemplateArgs(); + for (unsigned i = 0, e = DRE->getNumTemplateArgs(); i != e; ++i) { + char C = (char)Args[i].getArgument().getAsIntegral()->getZExtValue(); + OS << C; + } + break; + } + case UserDefinedLiteral::LOK_Integer: + case UserDefinedLiteral::LOK_Floating: + case UserDefinedLiteral::LOK_String: + case UserDefinedLiteral::LOK_Character: + PrintExpr(Node->getCookedLiteral()); + break; + } + OS << Node->getUDSuffix()->getName(); +} + void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { OS << (Node->getValue() ? "true" : "false"); } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 7935d6d44d1..db27f821f5b 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -738,6 +738,10 @@ void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) { VisitCXXNamedCastExpr(S); } +void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) { + VisitCallExpr(S); +} + void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) { VisitExpr(S); ID.AddBoolean(S->getValue()); |